xref: /illumos-gate/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c (revision 7f667e74610492ddbce8ce60f52ece95d2401949)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"@(#)smb_cfg.c	1.5	08/07/08 SMI"
27 
28 /*
29  * CIFS configuration management library
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <synch.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <syslog.h>
39 #include <netdb.h>
40 #include <ctype.h>
41 #include <sys/types.h>
42 #include <libscf.h>
43 #include <assert.h>
44 #include <uuid/uuid.h>
45 #include <smbsrv/libsmb.h>
46 
47 typedef struct smb_cfg_param {
48 	smb_cfg_id_t sc_id;
49 	char *sc_name;
50 	int sc_type;
51 	uint32_t sc_flags;
52 } smb_cfg_param_t;
53 
54 /*
55  * config parameter flags
56  */
57 #define	SMB_CF_PROTECTED	0x01
58 
59 /* idmap SMF fmri and Property Group */
60 #define	IDMAP_FMRI_PREFIX		"system/idmap"
61 #define	MACHINE_SID			"machine_sid"
62 #define	IDMAP_DOMAIN			"domain_name"
63 #define	IDMAP_PG_NAME			"config"
64 
65 #define	SMB_SECMODE_WORKGRP_STR 	"workgroup"
66 #define	SMB_SECMODE_DOMAIN_STR  	"domain"
67 
68 #define	SMB_ENC_LEN	1024
69 #define	SMB_DEC_LEN	256
70 
71 static char *b64_data =
72 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
73 
74 static smb_cfg_param_t smb_cfg_table[] =
75 {
76 	/* Oplock configuration, Kernel Only */
77 	{SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0},
78 
79 	/* Autohome configuration */
80 	{SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0},
81 
82 	/* Domain/PDC configuration */
83 	{SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0},
84 	{SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0},
85 	{SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0},
86 	{SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0},
87 	{SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0},
88 	{SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0},
89 	{SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0},
90 
91 	/* WINS configuration */
92 	{SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0},
93 	{SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0},
94 	{SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0},
95 
96 	/* RPC services configuration */
97 	{SMB_CI_SRVSVC_SHRSET_ENABLE, "srvsvc_sharesetinfo_enable",
98 	    SCF_TYPE_BOOLEAN, 0},
99 
100 	/* Kmod specific configuration */
101 	{SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0},
102 	{SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0},
103 	{SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0},
104 	{SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0},
105 
106 	{SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0},
107 	{SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0},
108 
109 	/* Kmod tuning configuration */
110 	{SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0},
111 
112 	/* SMBd configuration */
113 	{SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0},
114 	{SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0},
115 	{SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0},
116 	{SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0},
117 
118 	/* ADS Configuration */
119 	{SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0},
120 
121 	/* Dynamic DNS */
122 	{SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0},
123 
124 	{SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING,
125 	    SMB_CF_PROTECTED},
126 	{SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING,
127 	    0},
128 	{SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING,
129 	    0},
130 	{SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER,
131 	    0},
132 	{SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER,
133 	    0},
134 	{SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0}
135 
136 	/* SMB_CI_MAX */
137 };
138 
139 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
140 
141 static boolean_t smb_is_base64(unsigned char c);
142 static char *smb_base64_encode(char *str_to_encode);
143 static char *smb_base64_decode(char *encoded_str);
144 
145 char *
146 smb_config_getname(smb_cfg_id_t id)
147 {
148 	smb_cfg_param_t *cfg;
149 	cfg = smb_config_getent(id);
150 	return (cfg->sc_name);
151 }
152 
153 static boolean_t
154 smb_is_base64(unsigned char c)
155 {
156 	return (isalnum(c) || (c == '+') || (c == '/'));
157 }
158 
159 /*
160  * smb_base64_encode
161  *
162  * Encode a string using base64 algorithm.
163  * Caller should free the returned buffer when done.
164  */
165 static char *
166 smb_base64_encode(char *str_to_encode)
167 {
168 	int ret_cnt = 0;
169 	int i = 0, j = 0;
170 	char arr_3[3], arr_4[4];
171 	int len = strlen(str_to_encode);
172 	char *ret = malloc(SMB_ENC_LEN);
173 
174 	if (ret == NULL) {
175 		return (NULL);
176 	}
177 
178 	while (len--) {
179 		arr_3[i++] = *(str_to_encode++);
180 		if (i == 3) {
181 			arr_4[0] = (arr_3[0] & 0xfc) >> 2;
182 			arr_4[1] = ((arr_3[0] & 0x03) << 4) +
183 			    ((arr_3[1] & 0xf0) >> 4);
184 			arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
185 			    ((arr_3[2] & 0xc0) >> 6);
186 			arr_4[3] = arr_3[2] & 0x3f;
187 
188 			for (i = 0; i < 4; i++)
189 				ret[ret_cnt++] = b64_data[arr_4[i]];
190 			i = 0;
191 		}
192 	}
193 
194 	if (i) {
195 		for (j = i; j < 3; j++)
196 			arr_3[j] = '\0';
197 
198 		arr_4[0] = (arr_3[0] & 0xfc) >> 2;
199 		arr_4[1] = ((arr_3[0] & 0x03) << 4) +
200 		    ((arr_3[1] & 0xf0) >> 4);
201 		arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
202 		    ((arr_3[2] & 0xc0) >> 6);
203 		arr_4[3] = arr_3[2] & 0x3f;
204 
205 		for (j = 0; j < (i + 1); j++)
206 			ret[ret_cnt++] = b64_data[arr_4[j]];
207 
208 		while (i++ < 3)
209 			ret[ret_cnt++] = '=';
210 	}
211 
212 	ret[ret_cnt++] = '\0';
213 	return (ret);
214 }
215 
216 /*
217  * smb_base64_decode
218  *
219  * Decode using base64 algorithm.
220  * Caller should free the returned buffer when done.
221  */
222 static char *
223 smb_base64_decode(char *encoded_str)
224 {
225 	int len = strlen(encoded_str);
226 	int i = 0, j = 0;
227 	int en_ind = 0;
228 	char arr_4[4], arr_3[3];
229 	int ret_cnt = 0;
230 	char *ret = malloc(SMB_DEC_LEN);
231 	char *p;
232 
233 	if (ret == NULL) {
234 		return (NULL);
235 	}
236 
237 	while (len-- && (encoded_str[en_ind] != '=') &&
238 	    smb_is_base64(encoded_str[en_ind])) {
239 		arr_4[i++] = encoded_str[en_ind];
240 		en_ind++;
241 		if (i == 4) {
242 			for (i = 0; i < 4; i++) {
243 				if ((p = strchr(b64_data, arr_4[i])) == NULL)
244 					return (NULL);
245 
246 				arr_4[i] = (int)(p - b64_data);
247 			}
248 
249 			arr_3[0] = (arr_4[0] << 2) +
250 			    ((arr_4[1] & 0x30) >> 4);
251 			arr_3[1] = ((arr_4[1] & 0xf) << 4) +
252 			    ((arr_4[2] & 0x3c) >> 2);
253 			arr_3[2] = ((arr_4[2] & 0x3) << 6) +
254 			    arr_4[3];
255 
256 			for (i = 0; i < 3; i++)
257 				ret[ret_cnt++] = arr_3[i];
258 
259 			i = 0;
260 		}
261 	}
262 
263 	if (i) {
264 		for (j = i; j < 4; j++)
265 			arr_4[j] = 0;
266 
267 		for (j = 0; j < 4; j++) {
268 			if ((p = strchr(b64_data, arr_4[j])) == NULL)
269 				return (NULL);
270 
271 			arr_4[j] = (int)(p - b64_data);
272 		}
273 		arr_3[0] = (arr_4[0] << 2) +
274 		    ((arr_4[1] & 0x30) >> 4);
275 		arr_3[1] = ((arr_4[1] & 0xf) << 4) +
276 		    ((arr_4[2] & 0x3c) >> 2);
277 		arr_3[2] = ((arr_4[2] & 0x3) << 6) +
278 		    arr_4[3];
279 		for (j = 0; j < (i - 1); j++)
280 			ret[ret_cnt++] = arr_3[j];
281 	}
282 
283 	ret[ret_cnt++] = '\0';
284 	return (ret);
285 }
286 
287 static char *
288 smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp)
289 {
290 	smb_scfhandle_t *handle;
291 	char *value;
292 
293 	if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL)
294 		return (NULL);
295 
296 	handle = smb_smf_scf_init(svc_fmri_prefix);
297 	if (handle == NULL) {
298 		free(value);
299 		return (NULL);
300 	}
301 
302 	(void) smb_smf_create_service_pgroup(handle, svc_propgrp);
303 
304 	if (smb_smf_get_string_property(handle, name, value,
305 	    sizeof (char) * MAX_VALUE_BUFLEN) != 0) {
306 		smb_smf_scf_fini(handle);
307 		free(value);
308 		return (NULL);
309 	}
310 
311 	smb_smf_scf_fini(handle);
312 	return (value);
313 
314 }
315 
316 static int
317 smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp,
318     char *name, char *value)
319 {
320 	smb_scfhandle_t *handle = NULL;
321 	int rc = 0;
322 
323 
324 	handle = smb_smf_scf_init(svc_fmri_prefix);
325 	if (handle == NULL) {
326 		return (1);
327 	}
328 
329 	(void) smb_smf_create_service_pgroup(handle, svc_propgrp);
330 
331 	if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
332 		smb_smf_scf_fini(handle);
333 		return (1);
334 	}
335 
336 	if (smb_smf_set_string_property(handle, name, value) != SMBD_SMF_OK)
337 		rc = 1;
338 
339 	if (smb_smf_end_transaction(handle) != SMBD_SMF_OK)
340 		rc = 1;
341 
342 	smb_smf_scf_fini(handle);
343 	return (rc);
344 }
345 
346 /*
347  * smb_config_getstr
348  *
349  * Fetch the specified string configuration item from SMF
350  */
351 int
352 smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz)
353 {
354 	smb_scfhandle_t *handle;
355 	smb_cfg_param_t *cfg;
356 	int rc = SMBD_SMF_OK;
357 
358 	*cbuf = '\0';
359 	cfg = smb_config_getent(id);
360 	assert(cfg->sc_type == SCF_TYPE_ASTRING);
361 
362 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
363 	if (handle == NULL)
364 		return (SMBD_SMF_SYSTEM_ERR);
365 
366 	if (cfg->sc_flags & SMB_CF_PROTECTED) {
367 		char protbuf[SMB_ENC_LEN];
368 		char *tmp;
369 
370 		if ((rc = smb_smf_create_service_pgroup(handle,
371 		    SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK)
372 			goto error;
373 
374 		if ((rc = smb_smf_get_string_property(handle, cfg->sc_name,
375 		    protbuf, sizeof (protbuf))) != SMBD_SMF_OK)
376 			goto error;
377 
378 		if (*protbuf != '\0') {
379 			tmp = smb_base64_decode(protbuf);
380 			(void) strlcpy(cbuf, tmp, bufsz);
381 			free(tmp);
382 		}
383 	} else {
384 		rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
385 		if (rc == SMBD_SMF_OK)
386 			rc = smb_smf_get_string_property(handle, cfg->sc_name,
387 			    cbuf, bufsz);
388 	}
389 
390 error:
391 	smb_smf_scf_fini(handle);
392 	return (rc);
393 }
394 
395 int
396 smb_config_getip(smb_cfg_id_t sc_id, smb_inaddr_t *ipaddr)
397 {
398 	int rc;
399 	char ipstr[INET6_ADDRSTRLEN];
400 
401 	rc = smb_config_getstr(sc_id, ipstr, sizeof (ipstr));
402 	if (rc == SMBD_SMF_OK) {
403 		rc = inet_pton(AF_INET, ipstr, ipaddr);
404 		if (rc == 0) {
405 			rc = inet_pton(AF_INET6, ipstr, ipaddr);
406 			if (rc == 0)
407 				bzero(ipaddr, sizeof (smb_inaddr_t));
408 		}
409 	}
410 	return (rc);
411 }
412 
413 /*
414  * smb_config_getnum
415  *
416  * Returns the value of a numeric config param.
417  */
418 int
419 smb_config_getnum(smb_cfg_id_t id, int64_t *cint)
420 {
421 	smb_scfhandle_t *handle;
422 	smb_cfg_param_t *cfg;
423 	int rc = SMBD_SMF_OK;
424 
425 	*cint = 0;
426 	cfg = smb_config_getent(id);
427 	assert(cfg->sc_type == SCF_TYPE_INTEGER);
428 
429 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
430 	if (handle == NULL)
431 		return (SMBD_SMF_SYSTEM_ERR);
432 
433 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
434 	if (rc == SMBD_SMF_OK)
435 		rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint);
436 	smb_smf_scf_fini(handle);
437 
438 	return (rc);
439 }
440 
441 /*
442  * smb_config_getbool
443  *
444  * Returns the value of a boolean config param.
445  */
446 boolean_t
447 smb_config_getbool(smb_cfg_id_t id)
448 {
449 	smb_scfhandle_t *handle;
450 	smb_cfg_param_t *cfg;
451 	int rc = SMBD_SMF_OK;
452 	uint8_t vbool;
453 
454 	cfg = smb_config_getent(id);
455 	assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
456 
457 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
458 	if (handle == NULL)
459 		return (B_FALSE);
460 
461 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
462 	if (rc == SMBD_SMF_OK)
463 		rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool);
464 	smb_smf_scf_fini(handle);
465 
466 	return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE);
467 }
468 
469 /*
470  * smb_config_get
471  *
472  * This function returns the value of the requested config
473  * iterm regardless of its type in string format. This should
474  * be used when the config item type is not known by the caller.
475  */
476 int
477 smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz)
478 {
479 	smb_cfg_param_t *cfg;
480 	int64_t cint;
481 	int rc;
482 
483 	cfg = smb_config_getent(id);
484 	switch (cfg->sc_type) {
485 	case SCF_TYPE_ASTRING:
486 		return (smb_config_getstr(id, cbuf, bufsz));
487 
488 	case SCF_TYPE_INTEGER:
489 		rc = smb_config_getnum(id, &cint);
490 		if (rc == SMBD_SMF_OK)
491 			(void) snprintf(cbuf, bufsz, "%lld", cint);
492 		return (rc);
493 
494 	case SCF_TYPE_BOOLEAN:
495 		if (smb_config_getbool(id))
496 			(void) strlcpy(cbuf, "true", bufsz);
497 		else
498 			(void) strlcpy(cbuf, "false", bufsz);
499 		return (SMBD_SMF_OK);
500 	}
501 
502 	return (SMBD_SMF_INVALID_ARG);
503 }
504 
505 /*
506  * smb_config_setstr
507  *
508  * Set the specified config param with the given
509  * value.
510  */
511 int
512 smb_config_setstr(smb_cfg_id_t id, char *value)
513 {
514 	smb_scfhandle_t *handle;
515 	smb_cfg_param_t *cfg;
516 	int rc = SMBD_SMF_OK;
517 	boolean_t protected;
518 	char *tmp = NULL;
519 	char *pg;
520 
521 	cfg = smb_config_getent(id);
522 	assert(cfg->sc_type == SCF_TYPE_ASTRING);
523 
524 	if (cfg->sc_flags & SMB_CF_PROTECTED) {
525 		pg = SMBD_PROTECTED_PG_NAME;
526 		protected = B_TRUE;
527 	} else {
528 		pg = SMBD_PG_NAME;
529 		protected = B_FALSE;
530 	}
531 
532 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
533 	if (handle == NULL)
534 		return (SMBD_SMF_SYSTEM_ERR);
535 
536 	rc = smb_smf_create_service_pgroup(handle, pg);
537 	if (rc == SMBD_SMF_OK)
538 		rc = smb_smf_start_transaction(handle);
539 
540 	if (rc != SMBD_SMF_OK) {
541 		smb_smf_scf_fini(handle);
542 		return (rc);
543 	}
544 
545 	if (protected && value && (*value != '\0')) {
546 		if ((tmp = smb_base64_encode(value)) == NULL) {
547 			(void) smb_smf_end_transaction(handle);
548 			smb_smf_scf_fini(handle);
549 			return (SMBD_SMF_NO_MEMORY);
550 		}
551 
552 		value = tmp;
553 	}
554 
555 	rc = smb_smf_set_string_property(handle, cfg->sc_name, value);
556 
557 	free(tmp);
558 	(void) smb_smf_end_transaction(handle);
559 	smb_smf_scf_fini(handle);
560 	return (rc);
561 }
562 
563 /*
564  * smb_config_setnum
565  *
566  * Sets a numeric configuration iterm
567  */
568 int
569 smb_config_setnum(smb_cfg_id_t id, int64_t value)
570 {
571 	smb_scfhandle_t *handle;
572 	smb_cfg_param_t *cfg;
573 	int rc = SMBD_SMF_OK;
574 
575 	cfg = smb_config_getent(id);
576 	assert(cfg->sc_type == SCF_TYPE_INTEGER);
577 
578 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
579 	if (handle == NULL)
580 		return (SMBD_SMF_SYSTEM_ERR);
581 
582 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
583 	if (rc == SMBD_SMF_OK)
584 		rc = smb_smf_start_transaction(handle);
585 
586 	if (rc != SMBD_SMF_OK) {
587 		smb_smf_scf_fini(handle);
588 		return (rc);
589 	}
590 
591 	rc = smb_smf_set_integer_property(handle, cfg->sc_name, value);
592 
593 	(void) smb_smf_end_transaction(handle);
594 	smb_smf_scf_fini(handle);
595 	return (rc);
596 }
597 
598 /*
599  * smb_config_setbool
600  *
601  * Sets a boolean configuration iterm
602  */
603 int
604 smb_config_setbool(smb_cfg_id_t id, boolean_t value)
605 {
606 	smb_scfhandle_t *handle;
607 	smb_cfg_param_t *cfg;
608 	int rc = SMBD_SMF_OK;
609 
610 	cfg = smb_config_getent(id);
611 	assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
612 
613 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
614 	if (handle == NULL)
615 		return (SMBD_SMF_SYSTEM_ERR);
616 
617 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
618 	if (rc == SMBD_SMF_OK)
619 		rc = smb_smf_start_transaction(handle);
620 
621 	if (rc != SMBD_SMF_OK) {
622 		smb_smf_scf_fini(handle);
623 		return (rc);
624 	}
625 
626 	rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value);
627 
628 	(void) smb_smf_end_transaction(handle);
629 	smb_smf_scf_fini(handle);
630 	return (rc);
631 }
632 
633 /*
634  * smb_config_set
635  *
636  * This function sets the value of the specified config
637  * iterm regardless of its type in string format. This should
638  * be used when the config item type is not known by the caller.
639  */
640 int
641 smb_config_set(smb_cfg_id_t id, char *value)
642 {
643 	smb_cfg_param_t *cfg;
644 	int64_t cint;
645 
646 	cfg = smb_config_getent(id);
647 	switch (cfg->sc_type) {
648 	case SCF_TYPE_ASTRING:
649 		return (smb_config_setstr(id, value));
650 
651 	case SCF_TYPE_INTEGER:
652 		cint = atoi(value);
653 		return (smb_config_setnum(id, cint));
654 
655 	case SCF_TYPE_BOOLEAN:
656 		return (smb_config_setbool(id, strcasecmp(value, "true") == 0));
657 	}
658 
659 	return (SMBD_SMF_INVALID_ARG);
660 }
661 uint8_t
662 smb_config_get_fg_flag()
663 {
664 	uint8_t run_fg = 0; /* Default is to run in daemon mode */
665 	smb_scfhandle_t *handle = NULL;
666 
667 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
668 	if (handle == NULL) {
669 		return (run_fg);
670 	}
671 
672 	if (smb_smf_create_service_pgroup(handle,
673 	    SMBD_PG_NAME) != SMBD_SMF_OK) {
674 		smb_smf_scf_fini(handle);
675 		return (run_fg);
676 	}
677 
678 	if (smb_smf_get_boolean_property(handle, "run_fg", &run_fg) != 0) {
679 		smb_smf_scf_fini(handle);
680 		return (run_fg);
681 	}
682 
683 	smb_smf_scf_fini(handle);
684 
685 	return (run_fg);
686 }
687 
688 /*
689  * smb_config_get_localsid
690  *
691  * Returns value of the "config/machine_sid" parameter
692  * from the IDMAP SMF configuration repository.
693  *
694  */
695 char *
696 smb_config_get_localsid(void)
697 {
698 	return (smb_config_getenv_generic(MACHINE_SID, IDMAP_FMRI_PREFIX,
699 	    IDMAP_PG_NAME));
700 }
701 
702 /*
703  * smb_config_set_idmap_domain
704  *
705  * Set the "config/domain_name" parameter from IDMAP SMF repository.
706  */
707 int
708 smb_config_set_idmap_domain(char *value)
709 {
710 	return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
711 	    IDMAP_DOMAIN, value));
712 }
713 
714 /*
715  * smb_config_refresh_idmap
716  *
717  * Refresh IDMAP SMF service after making changes to its configuration.
718  */
719 int
720 smb_config_refresh_idmap(void)
721 {
722 	char instance[32];
723 
724 	(void) snprintf(instance, sizeof (instance), "%s:default",
725 	    IDMAP_FMRI_PREFIX);
726 	return (smf_refresh_instance(instance));
727 }
728 
729 int
730 smb_config_secmode_fromstr(char *secmode)
731 {
732 	if (secmode == NULL)
733 		return (SMB_SECMODE_WORKGRP);
734 
735 	if (strcasecmp(secmode, SMB_SECMODE_DOMAIN_STR) == 0)
736 		return (SMB_SECMODE_DOMAIN);
737 
738 	return (SMB_SECMODE_WORKGRP);
739 }
740 
741 char *
742 smb_config_secmode_tostr(int secmode)
743 {
744 	if (secmode == SMB_SECMODE_DOMAIN)
745 		return (SMB_SECMODE_DOMAIN_STR);
746 
747 	return (SMB_SECMODE_WORKGRP_STR);
748 }
749 
750 int
751 smb_config_get_secmode()
752 {
753 	char p[16];
754 
755 	(void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p));
756 	return (smb_config_secmode_fromstr(p));
757 }
758 
759 int
760 smb_config_set_secmode(int secmode)
761 {
762 	char *p;
763 
764 	p = smb_config_secmode_tostr(secmode);
765 	return (smb_config_setstr(SMB_CI_SECURITY, p));
766 }
767 
768 static smb_cfg_param_t *
769 smb_config_getent(smb_cfg_id_t id)
770 {
771 	int i;
772 
773 	for (i = 0; i < SMB_CI_MAX; i++)
774 		if (smb_cfg_table[i].sc_id == id)
775 			return (&smb_cfg_table[id]);
776 
777 	assert(0);
778 	return (NULL);
779 }
780 
781 void
782 smb_config_getdomaininfo(char *domain, char *fqdn, char *forest, char *guid)
783 {
784 	(void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, NETBIOS_NAME_SZ);
785 	(void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn, MAXHOSTNAMELEN);
786 	(void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest, MAXHOSTNAMELEN);
787 	(void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid,
788 	    UUID_PRINTABLE_STRING_LENGTH);
789 }
790 
791 void
792 smb_config_setdomaininfo(char *domain, char *fqdn, char *forest, char *guid)
793 {
794 	(void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain);
795 	(void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn);
796 	(void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest);
797 	(void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid);
798 }
799