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