1/*
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
4
5/*
6 * BSD 3 Clause License
7 *
8 * Copyright (c) 2007, The Storage Networking Industry Association.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 	- Redistributions of source code must retain the above copyright
14 *	  notice, this list of conditions and the following disclaimer.
15 *
16 * 	- Redistributions in binary form must reproduce the above copyright
17 *	  notice, this list of conditions and the following disclaimer in
18 *	  the documentation and/or other materials provided with the
19 *	  distribution.
20 *
21 *	- Neither the name of The Storage Networking Industry Association (SNIA)
22 *	  nor the names of its contributors may be used to endorse or promote
23 *	  products derived from this software without specific prior written
24 *	  permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 * NDMP configuration management
41 */
42#include <stdio.h>
43#include <stdlib.h>
44#include <synch.h>
45#include <syslog.h>
46#include <strings.h>
47#include <ndmpd_prop.h>
48#include <libndmp.h>
49#include "ndmpd.h"
50
51typedef struct ndmpd_cfg_param {
52	char		*sc_name;
53	char		*sc_defval;
54	char		*sc_value;
55	uint32_t	sc_flags;
56} ndmpd_cfg_param_t;
57
58
59static int ndmpd_config_update(ndmpd_cfg_param_t *cfg, char *value);
60
61/*
62 * IMPORTANT: any changes to the order of this table's entries
63 * need to be reflected in the enum ndmpd_cfg_id_t.
64 */
65ndmpd_cfg_param_t ndmpd_cfg_table[] =
66{
67	{"dar-support",			"",	0, NDMP_CF_NOTINIT},
68	{"mover-nic",			"",	0, NDMP_CF_NOTINIT},
69	{"dump-pathnode",		"",	0, NDMP_CF_NOTINIT},
70	{"tar-pathnode",		"",	0, NDMP_CF_NOTINIT},
71	{"fh-inode",			"",	0, NDMP_CF_NOTINIT},
72	{"ignore-ctime",		"",	0, NDMP_CF_NOTINIT},
73	{"include-lmtime",		"",	0, NDMP_CF_NOTINIT},
74	{"token-maxseq",		"",	0, NDMP_CF_NOTINIT},
75	{"version",			"",	0, NDMP_CF_NOTINIT},
76	{"restore-fullpath",		"",	0, NDMP_CF_NOTINIT},
77	{"debug-path",			"",	0, NDMP_CF_NOTINIT},
78	{"plugin-path",			"",	0, NDMP_CF_NOTINIT},
79	{"socket-css",			"",	0, NDMP_CF_NOTINIT},
80	{"socket-crs",			"",	0, NDMP_CF_NOTINIT},
81	{"mover-recordsize",		"",	0, NDMP_CF_NOTINIT},
82	{"restore-wildcard-enable",	"",	0, NDMP_CF_NOTINIT},
83	{"cram-md5-username",		"",	0, NDMP_CF_NOTINIT},
84	{"cram-md5-password",		"",	0, NDMP_CF_NOTINIT},
85	{"cleartext-username",		"",	0, NDMP_CF_NOTINIT},
86	{"cleartext-password",		"",	0, NDMP_CF_NOTINIT},
87	{"tcp-port",			"",	0, NDMP_CF_NOTINIT},
88	{"backup-quarantine",		"",	0, NDMP_CF_NOTINIT},
89	{"restore-quarantine",		"",	0, NDMP_CF_NOTINIT},
90	{"overwrite-quarantine",	"",	0, NDMP_CF_NOTINIT},
91	{"zfs-force-override",		"",	0, NDMP_CF_NOTINIT},
92	{"drive-type",			"",	0, NDMP_CF_NOTINIT},
93};
94
95/*
96 * Loads all the NDMP configuration parameters and sets up the
97 * config table.
98 */
99int
100ndmpd_load_prop(void)
101{
102	ndmpd_cfg_id_t id;
103	ndmpd_cfg_param_t *cfg;
104	char *value;
105
106	for (id = 0; id < NDMP_MAXALL; id++) {
107		cfg = &ndmpd_cfg_table[id];
108		if ((ndmp_get_prop(cfg->sc_name, &value)) == -1) {
109			syslog(LOG_DEBUG, "%s %s",
110			    cfg->sc_name, ndmp_strerror(ndmp_errno));
111			continue;
112		}
113		/*
114		 * enval == 0 could mean two things, either the
115		 * config param is not defined, or it has been
116		 * removed. If the variable has already been defined
117		 * and now enval is 0, it should be removed, otherwise
118		 * we don't need to do anything in this case.
119		 */
120		if ((cfg->sc_flags & NDMP_CF_DEFINED) || value) {
121			if (ndmpd_config_update(cfg, value)) {
122				free(value);
123				return (-1);
124			}
125		}
126		free(value);
127	}
128	return (0);
129}
130
131/*
132 * ndmpd_config_update
133 *
134 * Updates the specified config param with the given value.
135 * This function is called both on (re)load and set.
136 */
137static int
138ndmpd_config_update(ndmpd_cfg_param_t *cfg, char *value)
139{
140	char *curval;
141	int rc = 0;
142	int len;
143
144	if (value) {
145		len = strlen(value);
146		if (cfg->sc_value) {
147			curval = realloc(cfg->sc_value, (len + 1));
148		} else {
149			curval = ndmp_malloc(len + 1);
150		}
151
152		if (curval) {
153			cfg->sc_value = curval;
154			(void) strcpy(cfg->sc_value, value);
155			cfg->sc_flags |= NDMP_CF_DEFINED;
156		} else {
157			syslog(LOG_ERR, "Out of memory.");
158			rc = -1;
159		}
160	} else if (cfg->sc_value) {
161		free(cfg->sc_value);
162		cfg->sc_value = 0;
163		cfg->sc_flags &= ~NDMP_CF_DEFINED;
164	}
165
166	return (rc);
167}
168
169/*
170 * Returns value of the specified config param.
171 * The return value is a string pointer to the locally
172 * allocated memory if the config param is defined
173 * otherwise it would be NULL.
174 */
175char *
176ndmpd_get_prop(ndmpd_cfg_id_t id)
177{
178	char *env_val;
179
180	if (id < NDMP_MAXALL) {
181		env_val = ndmpd_cfg_table[id].sc_value;
182		return (env_val);
183	}
184
185	return (0);
186}
187
188/*
189 * Similar to ndmpd_get_prop except it will return dflt value
190 * if env is not set.
191 */
192char *
193ndmpd_get_prop_default(ndmpd_cfg_id_t id, char *dflt)
194{
195	char *env;
196
197	env = ndmpd_get_prop(id);
198
199	if (env && *env != 0) {
200		return (env);
201	} else {
202		return (dflt);
203	}
204}
205
206/*
207 * Returns the value of a yes/no config param.
208 * Returns 1 is config is set to "yes", otherwise 0.
209 */
210int
211ndmpd_get_prop_yorn(ndmpd_cfg_id_t id)
212{
213	char *val;
214
215	val = ndmpd_get_prop(id);
216	if (val) {
217		if (strcasecmp(val, "yes") == 0)
218			return (1);
219	}
220
221	return (0);
222}
223