xref: /titanic_52/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*a90cf9f2SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw /*
27da6c28aaSamw  * CIFS configuration management library
28da6c28aaSamw  */
29da6c28aaSamw 
30da6c28aaSamw #include <stdio.h>
31da6c28aaSamw #include <stdlib.h>
32da6c28aaSamw #include <unistd.h>
33da6c28aaSamw #include <synch.h>
34da6c28aaSamw #include <string.h>
35da6c28aaSamw #include <strings.h>
36da6c28aaSamw #include <syslog.h>
37da6c28aaSamw #include <netdb.h>
38da6c28aaSamw #include <ctype.h>
39da6c28aaSamw #include <sys/types.h>
40da6c28aaSamw #include <libscf.h>
41dc20a302Sas200622 #include <assert.h>
428d7e4166Sjose borrego #include <uuid/uuid.h>
43da6c28aaSamw #include <smbsrv/libsmb.h>
44da6c28aaSamw 
45da6c28aaSamw typedef struct smb_cfg_param {
46dc20a302Sas200622 	smb_cfg_id_t sc_id;
47da6c28aaSamw 	char *sc_name;
48da6c28aaSamw 	int sc_type;
49da6c28aaSamw 	uint32_t sc_flags;
50da6c28aaSamw } smb_cfg_param_t;
51da6c28aaSamw 
52*a90cf9f2SGordon Ross struct str_val {
53*a90cf9f2SGordon Ross 	char *str;
54*a90cf9f2SGordon Ross 	uint32_t val;
55*a90cf9f2SGordon Ross };
56*a90cf9f2SGordon Ross 
57da6c28aaSamw /*
58da6c28aaSamw  * config parameter flags
59da6c28aaSamw  */
60dc20a302Sas200622 #define	SMB_CF_PROTECTED	0x01
6129bd2886SAlan Wright #define	SMB_CF_EXEC		0x02
62da6c28aaSamw 
63da6c28aaSamw /* idmap SMF fmri and Property Group */
64da6c28aaSamw #define	IDMAP_FMRI_PREFIX		"system/idmap"
65da6c28aaSamw #define	MACHINE_SID			"machine_sid"
6612b65585SGordon Ross #define	MACHINE_UUID			"machine_uuid"
6755bf511dSas200622 #define	IDMAP_DOMAIN			"domain_name"
68b3700b07SGordon Ross #define	IDMAP_PREF_DC			"preferred_dc"
69da6c28aaSamw #define	IDMAP_PG_NAME			"config"
70da6c28aaSamw 
71da6c28aaSamw #define	SMB_SECMODE_WORKGRP_STR 	"workgroup"
72da6c28aaSamw #define	SMB_SECMODE_DOMAIN_STR  	"domain"
73da6c28aaSamw 
74da6c28aaSamw #define	SMB_ENC_LEN	1024
75da6c28aaSamw #define	SMB_DEC_LEN	256
76da6c28aaSamw 
77da6c28aaSamw static char *b64_data =
78da6c28aaSamw 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
79da6c28aaSamw 
80da6c28aaSamw static smb_cfg_param_t smb_cfg_table[] =
81da6c28aaSamw {
829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{SMB_CI_VERSION, "sv_version", SCF_TYPE_ASTRING, 0},
839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
84da6c28aaSamw 	/* Oplock configuration, Kernel Only */
85dc20a302Sas200622 	{SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0},
86da6c28aaSamw 
87da6c28aaSamw 	/* Autohome configuration */
88dc20a302Sas200622 	{SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0},
89da6c28aaSamw 
90da6c28aaSamw 	/* Domain/PDC configuration */
91dc20a302Sas200622 	{SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0},
92dc20a302Sas200622 	{SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0},
93dc20a302Sas200622 	{SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0},
948d7e4166Sjose borrego 	{SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0},
958d7e4166Sjose borrego 	{SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0},
968d7e4166Sjose borrego 	{SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0},
97dc20a302Sas200622 	{SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0},
98da6c28aaSamw 
99da6c28aaSamw 	/* WINS configuration */
100dc20a302Sas200622 	{SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0},
101dc20a302Sas200622 	{SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0},
102dc20a302Sas200622 	{SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0},
103da6c28aaSamw 
104da6c28aaSamw 	/* Kmod specific configuration */
105dc20a302Sas200622 	{SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0},
106dc20a302Sas200622 	{SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0},
107dc20a302Sas200622 	{SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0},
108dc20a302Sas200622 	{SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0},
109da6c28aaSamw 
110dc20a302Sas200622 	{SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0},
111dc20a302Sas200622 	{SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0},
112da6c28aaSamw 
113da6c28aaSamw 	/* Kmod tuning configuration */
114dc20a302Sas200622 	{SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0},
115da6c28aaSamw 
116da6c28aaSamw 	/* SMBd configuration */
117dc20a302Sas200622 	{SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0},
11883d2dfe6SGordon Ross 	{SMB_CI_NETBIOS_ENABLE, "netbios_enable", SCF_TYPE_BOOLEAN, 0},
119dc20a302Sas200622 	{SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0},
120dc20a302Sas200622 	{SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0},
121dc20a302Sas200622 	{SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0},
122da6c28aaSamw 
123da6c28aaSamw 	/* ADS Configuration */
124dc20a302Sas200622 	{SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0},
125da6c28aaSamw 
126da6c28aaSamw 	/* Dynamic DNS */
127dc20a302Sas200622 	{SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0},
128da6c28aaSamw 
129dc20a302Sas200622 	{SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING,
130faa1795aSjb150015 	    SMB_CF_PROTECTED},
13112b65585SGordon Ross 
13212b65585SGordon Ross 	{SMB_CI_MACHINE_UUID, "machine_uuid", SCF_TYPE_ASTRING, 0},
13312b65585SGordon Ross 	{SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 0},
13412b65585SGordon Ross 	{SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 0},
13512b65585SGordon Ross 	{SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 0},
13612b65585SGordon Ross 	{SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 0},
13729bd2886SAlan Wright 	{SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0},
138cb174861Sjoyce mcintosh 	{SMB_CI_PRINT_ENABLE, "print_enable", SCF_TYPE_BOOLEAN, 0},
13929bd2886SAlan Wright 	{SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC},
14029bd2886SAlan Wright 	{SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC},
141148c5f43SAlan Wright 	{SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC},
1425f1ef25cSAram Hăvărneanu 	{SMB_CI_DFS_STDROOT_NUM, "dfs_stdroot_num", SCF_TYPE_INTEGER, 0},
143b819cea2SGordon Ross 	{SMB_CI_TRAVERSE_MOUNTS, "traverse_mounts", SCF_TYPE_BOOLEAN, 0},
144*a90cf9f2SGordon Ross 	{SMB_CI_SMB2_ENABLE_OLD, "smb2_enable", SCF_TYPE_BOOLEAN, 0},
145*a90cf9f2SGordon Ross 	{SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0},
146*a90cf9f2SGordon Ross 	{SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0},
147*a90cf9f2SGordon Ross 	{SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
14812b65585SGordon Ross 
149da6c28aaSamw 	/* SMB_CI_MAX */
150da6c28aaSamw };
151da6c28aaSamw 
152dc20a302Sas200622 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
153dc20a302Sas200622 
154da6c28aaSamw static boolean_t smb_is_base64(unsigned char c);
155da6c28aaSamw static char *smb_base64_encode(char *str_to_encode);
156da6c28aaSamw static char *smb_base64_decode(char *encoded_str);
157b3700b07SGordon Ross static int smb_config_get_idmap_preferred_dc(char *, int);
158b3700b07SGordon Ross static int smb_config_set_idmap_preferred_dc(char *);
159dc20a302Sas200622 
160dc20a302Sas200622 char *
161dc20a302Sas200622 smb_config_getname(smb_cfg_id_t id)
162dc20a302Sas200622 {
163dc20a302Sas200622 	smb_cfg_param_t *cfg;
164dc20a302Sas200622 	cfg = smb_config_getent(id);
165dc20a302Sas200622 	return (cfg->sc_name);
166dc20a302Sas200622 }
167da6c28aaSamw 
168da6c28aaSamw static boolean_t
169da6c28aaSamw smb_is_base64(unsigned char c)
170da6c28aaSamw {
171da6c28aaSamw 	return (isalnum(c) || (c == '+') || (c == '/'));
172da6c28aaSamw }
173da6c28aaSamw 
174da6c28aaSamw /*
175da6c28aaSamw  * smb_base64_encode
176da6c28aaSamw  *
177da6c28aaSamw  * Encode a string using base64 algorithm.
178da6c28aaSamw  * Caller should free the returned buffer when done.
179da6c28aaSamw  */
180da6c28aaSamw static char *
181da6c28aaSamw smb_base64_encode(char *str_to_encode)
182da6c28aaSamw {
183da6c28aaSamw 	int ret_cnt = 0;
184da6c28aaSamw 	int i = 0, j = 0;
185da6c28aaSamw 	char arr_3[3], arr_4[4];
186da6c28aaSamw 	int len = strlen(str_to_encode);
187da6c28aaSamw 	char *ret = malloc(SMB_ENC_LEN);
188da6c28aaSamw 
189da6c28aaSamw 	if (ret == NULL) {
190da6c28aaSamw 		return (NULL);
191da6c28aaSamw 	}
192da6c28aaSamw 
193da6c28aaSamw 	while (len--) {
194da6c28aaSamw 		arr_3[i++] = *(str_to_encode++);
195da6c28aaSamw 		if (i == 3) {
196da6c28aaSamw 			arr_4[0] = (arr_3[0] & 0xfc) >> 2;
197da6c28aaSamw 			arr_4[1] = ((arr_3[0] & 0x03) << 4) +
198da6c28aaSamw 			    ((arr_3[1] & 0xf0) >> 4);
199da6c28aaSamw 			arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
200da6c28aaSamw 			    ((arr_3[2] & 0xc0) >> 6);
201da6c28aaSamw 			arr_4[3] = arr_3[2] & 0x3f;
202da6c28aaSamw 
203da6c28aaSamw 			for (i = 0; i < 4; i++)
204da6c28aaSamw 				ret[ret_cnt++] = b64_data[arr_4[i]];
205da6c28aaSamw 			i = 0;
206da6c28aaSamw 		}
207da6c28aaSamw 	}
208da6c28aaSamw 
209da6c28aaSamw 	if (i) {
210da6c28aaSamw 		for (j = i; j < 3; j++)
211da6c28aaSamw 			arr_3[j] = '\0';
212da6c28aaSamw 
213da6c28aaSamw 		arr_4[0] = (arr_3[0] & 0xfc) >> 2;
214da6c28aaSamw 		arr_4[1] = ((arr_3[0] & 0x03) << 4) +
215da6c28aaSamw 		    ((arr_3[1] & 0xf0) >> 4);
216da6c28aaSamw 		arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
217da6c28aaSamw 		    ((arr_3[2] & 0xc0) >> 6);
218da6c28aaSamw 		arr_4[3] = arr_3[2] & 0x3f;
219da6c28aaSamw 
220da6c28aaSamw 		for (j = 0; j < (i + 1); j++)
221da6c28aaSamw 			ret[ret_cnt++] = b64_data[arr_4[j]];
222da6c28aaSamw 
223da6c28aaSamw 		while (i++ < 3)
224da6c28aaSamw 			ret[ret_cnt++] = '=';
225da6c28aaSamw 	}
226da6c28aaSamw 
227da6c28aaSamw 	ret[ret_cnt++] = '\0';
228da6c28aaSamw 	return (ret);
229da6c28aaSamw }
230da6c28aaSamw 
231da6c28aaSamw /*
232da6c28aaSamw  * smb_base64_decode
233da6c28aaSamw  *
234da6c28aaSamw  * Decode using base64 algorithm.
235da6c28aaSamw  * Caller should free the returned buffer when done.
236da6c28aaSamw  */
237da6c28aaSamw static char *
238da6c28aaSamw smb_base64_decode(char *encoded_str)
239da6c28aaSamw {
240da6c28aaSamw 	int len = strlen(encoded_str);
241da6c28aaSamw 	int i = 0, j = 0;
242da6c28aaSamw 	int en_ind = 0;
243da6c28aaSamw 	char arr_4[4], arr_3[3];
244da6c28aaSamw 	int ret_cnt = 0;
245da6c28aaSamw 	char *ret = malloc(SMB_DEC_LEN);
246da6c28aaSamw 	char *p;
247da6c28aaSamw 
248da6c28aaSamw 	if (ret == NULL) {
249da6c28aaSamw 		return (NULL);
250da6c28aaSamw 	}
251da6c28aaSamw 
252da6c28aaSamw 	while (len-- && (encoded_str[en_ind] != '=') &&
253da6c28aaSamw 	    smb_is_base64(encoded_str[en_ind])) {
254da6c28aaSamw 		arr_4[i++] = encoded_str[en_ind];
255da6c28aaSamw 		en_ind++;
256da6c28aaSamw 		if (i == 4) {
257da6c28aaSamw 			for (i = 0; i < 4; i++) {
258da6c28aaSamw 				if ((p = strchr(b64_data, arr_4[i])) == NULL)
259da6c28aaSamw 					return (NULL);
260da6c28aaSamw 
261da6c28aaSamw 				arr_4[i] = (int)(p - b64_data);
262da6c28aaSamw 			}
263da6c28aaSamw 
264da6c28aaSamw 			arr_3[0] = (arr_4[0] << 2) +
265da6c28aaSamw 			    ((arr_4[1] & 0x30) >> 4);
266da6c28aaSamw 			arr_3[1] = ((arr_4[1] & 0xf) << 4) +
267da6c28aaSamw 			    ((arr_4[2] & 0x3c) >> 2);
268da6c28aaSamw 			arr_3[2] = ((arr_4[2] & 0x3) << 6) +
269da6c28aaSamw 			    arr_4[3];
270da6c28aaSamw 
271da6c28aaSamw 			for (i = 0; i < 3; i++)
272da6c28aaSamw 				ret[ret_cnt++] = arr_3[i];
273da6c28aaSamw 
274da6c28aaSamw 			i = 0;
275da6c28aaSamw 		}
276da6c28aaSamw 	}
277da6c28aaSamw 
278da6c28aaSamw 	if (i) {
279da6c28aaSamw 		for (j = i; j < 4; j++)
280da6c28aaSamw 			arr_4[j] = 0;
281da6c28aaSamw 
282da6c28aaSamw 		for (j = 0; j < 4; j++) {
283da6c28aaSamw 			if ((p = strchr(b64_data, arr_4[j])) == NULL)
284da6c28aaSamw 				return (NULL);
285da6c28aaSamw 
286da6c28aaSamw 			arr_4[j] = (int)(p - b64_data);
287da6c28aaSamw 		}
288da6c28aaSamw 		arr_3[0] = (arr_4[0] << 2) +
289da6c28aaSamw 		    ((arr_4[1] & 0x30) >> 4);
290da6c28aaSamw 		arr_3[1] = ((arr_4[1] & 0xf) << 4) +
291da6c28aaSamw 		    ((arr_4[2] & 0x3c) >> 2);
292da6c28aaSamw 		arr_3[2] = ((arr_4[2] & 0x3) << 6) +
293da6c28aaSamw 		    arr_4[3];
294da6c28aaSamw 		for (j = 0; j < (i - 1); j++)
295da6c28aaSamw 			ret[ret_cnt++] = arr_3[j];
296da6c28aaSamw 	}
297da6c28aaSamw 
298da6c28aaSamw 	ret[ret_cnt++] = '\0';
299da6c28aaSamw 	return (ret);
300da6c28aaSamw }
301da6c28aaSamw 
302da6c28aaSamw static char *
303da6c28aaSamw smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp)
304da6c28aaSamw {
305da6c28aaSamw 	smb_scfhandle_t *handle;
306da6c28aaSamw 	char *value;
307da6c28aaSamw 
308da6c28aaSamw 	if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL)
309da6c28aaSamw 		return (NULL);
310da6c28aaSamw 
311da6c28aaSamw 	handle = smb_smf_scf_init(svc_fmri_prefix);
312da6c28aaSamw 	if (handle == NULL) {
313da6c28aaSamw 		free(value);
314da6c28aaSamw 		return (NULL);
315da6c28aaSamw 	}
316da6c28aaSamw 
317da6c28aaSamw 	(void) smb_smf_create_service_pgroup(handle, svc_propgrp);
318da6c28aaSamw 
319da6c28aaSamw 	if (smb_smf_get_string_property(handle, name, value,
320da6c28aaSamw 	    sizeof (char) * MAX_VALUE_BUFLEN) != 0) {
321da6c28aaSamw 		smb_smf_scf_fini(handle);
322da6c28aaSamw 		free(value);
323da6c28aaSamw 		return (NULL);
324da6c28aaSamw 	}
325da6c28aaSamw 
326da6c28aaSamw 	smb_smf_scf_fini(handle);
327da6c28aaSamw 	return (value);
328da6c28aaSamw 
329da6c28aaSamw }
330da6c28aaSamw 
331dc20a302Sas200622 static int
332da6c28aaSamw smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp,
333da6c28aaSamw     char *name, char *value)
334da6c28aaSamw {
335da6c28aaSamw 	smb_scfhandle_t *handle = NULL;
336da6c28aaSamw 	int rc = 0;
337da6c28aaSamw 
338da6c28aaSamw 
339da6c28aaSamw 	handle = smb_smf_scf_init(svc_fmri_prefix);
340da6c28aaSamw 	if (handle == NULL) {
341da6c28aaSamw 		return (1);
342da6c28aaSamw 	}
343da6c28aaSamw 
344da6c28aaSamw 	(void) smb_smf_create_service_pgroup(handle, svc_propgrp);
345da6c28aaSamw 
346da6c28aaSamw 	if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
347da6c28aaSamw 		smb_smf_scf_fini(handle);
348da6c28aaSamw 		return (1);
349da6c28aaSamw 	}
350da6c28aaSamw 
351da6c28aaSamw 	if (smb_smf_set_string_property(handle, name, value) != SMBD_SMF_OK)
352da6c28aaSamw 		rc = 1;
353da6c28aaSamw 
354da6c28aaSamw 	if (smb_smf_end_transaction(handle) != SMBD_SMF_OK)
355da6c28aaSamw 		rc = 1;
356da6c28aaSamw 
357da6c28aaSamw 	smb_smf_scf_fini(handle);
358da6c28aaSamw 	return (rc);
359da6c28aaSamw }
360da6c28aaSamw 
361da6c28aaSamw /*
362da6c28aaSamw  * smb_config_getstr
363da6c28aaSamw  *
364dc20a302Sas200622  * Fetch the specified string configuration item from SMF
365da6c28aaSamw  */
366dc20a302Sas200622 int
367dc20a302Sas200622 smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz)
368da6c28aaSamw {
369dc20a302Sas200622 	smb_scfhandle_t *handle;
370da6c28aaSamw 	smb_cfg_param_t *cfg;
371dc20a302Sas200622 	int rc = SMBD_SMF_OK;
37229bd2886SAlan Wright 	char *pg;
37396a62adaSjoyce mcintosh 	char protbuf[SMB_ENC_LEN];
37496a62adaSjoyce mcintosh 	char *tmp;
375da6c28aaSamw 
376dc20a302Sas200622 	*cbuf = '\0';
377dc20a302Sas200622 	cfg = smb_config_getent(id);
378dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_ASTRING);
379dc20a302Sas200622 
380b3700b07SGordon Ross 	if (id == SMB_CI_DOMAIN_SRV)
381b3700b07SGordon Ross 		return (smb_config_get_idmap_preferred_dc(cbuf, bufsz));
382b3700b07SGordon Ross 
383dc20a302Sas200622 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
384dc20a302Sas200622 	if (handle == NULL)
385dc20a302Sas200622 		return (SMBD_SMF_SYSTEM_ERR);
386dc20a302Sas200622 
387dc20a302Sas200622 	if (cfg->sc_flags & SMB_CF_PROTECTED) {
388dc20a302Sas200622 		if ((rc = smb_smf_create_service_pgroup(handle,
389dc20a302Sas200622 		    SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK)
390dc20a302Sas200622 			goto error;
391dc20a302Sas200622 
392dc20a302Sas200622 		if ((rc = smb_smf_get_string_property(handle, cfg->sc_name,
393dc20a302Sas200622 		    protbuf, sizeof (protbuf))) != SMBD_SMF_OK)
394dc20a302Sas200622 			goto error;
395dc20a302Sas200622 
396dc20a302Sas200622 		if (*protbuf != '\0') {
397dc20a302Sas200622 			tmp = smb_base64_decode(protbuf);
398dc20a302Sas200622 			(void) strlcpy(cbuf, tmp, bufsz);
399dc20a302Sas200622 			free(tmp);
400dc20a302Sas200622 		}
401dc20a302Sas200622 	} else {
40229bd2886SAlan Wright 		pg = (cfg->sc_flags & SMB_CF_EXEC) ? SMBD_EXEC_PG_NAME :
40329bd2886SAlan Wright 		    SMBD_PG_NAME;
40429bd2886SAlan Wright 		rc = smb_smf_create_service_pgroup(handle, pg);
405dc20a302Sas200622 		if (rc == SMBD_SMF_OK)
406dc20a302Sas200622 			rc = smb_smf_get_string_property(handle, cfg->sc_name,
407dc20a302Sas200622 			    cbuf, bufsz);
408da6c28aaSamw 	}
409da6c28aaSamw 
410dc20a302Sas200622 error:
411dc20a302Sas200622 	smb_smf_scf_fini(handle);
412dc20a302Sas200622 	return (rc);
413da6c28aaSamw }
414da6c28aaSamw 
41596a62adaSjoyce mcintosh /*
41696a62adaSjoyce mcintosh  * Translate the value of an astring SMF property into a binary
41796a62adaSjoyce mcintosh  * IP address. If the value is neither a valid IPv4 nor IPv6
41896a62adaSjoyce mcintosh  * address, attempt to look it up as a hostname using the
41996a62adaSjoyce mcintosh  * configured address type.
42096a62adaSjoyce mcintosh  */
4217f667e74Sjose borrego int
4227f667e74Sjose borrego smb_config_getip(smb_cfg_id_t sc_id, smb_inaddr_t *ipaddr)
4237f667e74Sjose borrego {
42496a62adaSjoyce mcintosh 	int rc, error;
42596a62adaSjoyce mcintosh 	int a_family;
42696a62adaSjoyce mcintosh 	char ipstr[MAXHOSTNAMELEN];
42796a62adaSjoyce mcintosh 	struct hostent *h;
42896a62adaSjoyce mcintosh 	smb_cfg_param_t *cfg;
4297f667e74Sjose borrego 
43029bd2886SAlan Wright 	if (ipaddr == NULL)
43129bd2886SAlan Wright 		return (SMBD_SMF_INVALID_ARG);
43229bd2886SAlan Wright 
43329bd2886SAlan Wright 	bzero(ipaddr, sizeof (smb_inaddr_t));
4347f667e74Sjose borrego 	rc = smb_config_getstr(sc_id, ipstr, sizeof (ipstr));
4357f667e74Sjose borrego 	if (rc == SMBD_SMF_OK) {
43696a62adaSjoyce mcintosh 		if (*ipstr == '\0')
43796a62adaSjoyce mcintosh 			return (SMBD_SMF_INVALID_ARG);
43896a62adaSjoyce mcintosh 
43929bd2886SAlan Wright 		if (inet_pton(AF_INET, ipstr, &ipaddr->a_ipv4) == 1) {
44029bd2886SAlan Wright 			ipaddr->a_family = AF_INET;
44129bd2886SAlan Wright 			return (SMBD_SMF_OK);
44229bd2886SAlan Wright 		}
44329bd2886SAlan Wright 
44429bd2886SAlan Wright 		if (inet_pton(AF_INET6, ipstr, &ipaddr->a_ipv6) == 1) {
44529bd2886SAlan Wright 			ipaddr->a_family = AF_INET6;
44696a62adaSjoyce mcintosh 			return (SMBD_SMF_OK);
44796a62adaSjoyce mcintosh 		}
44896a62adaSjoyce mcintosh 
44996a62adaSjoyce mcintosh 		/*
45096a62adaSjoyce mcintosh 		 * The value is neither an IPv4 nor IPv6 address;
45196a62adaSjoyce mcintosh 		 * so check if it's a hostname.
45296a62adaSjoyce mcintosh 		 */
45396a62adaSjoyce mcintosh 		a_family = smb_config_getbool(SMB_CI_IPV6_ENABLE) ?
45496a62adaSjoyce mcintosh 		    AF_INET6 : AF_INET;
45596a62adaSjoyce mcintosh 		h = getipnodebyname(ipstr, a_family, AI_DEFAULT,
45696a62adaSjoyce mcintosh 		    &error);
45796a62adaSjoyce mcintosh 		if (h != NULL) {
45896a62adaSjoyce mcintosh 			bcopy(*(h->h_addr_list), &ipaddr->a_ip,
45996a62adaSjoyce mcintosh 			    h->h_length);
46096a62adaSjoyce mcintosh 			ipaddr->a_family = a_family;
46196a62adaSjoyce mcintosh 			freehostent(h);
46229bd2886SAlan Wright 			rc = SMBD_SMF_OK;
46329bd2886SAlan Wright 		} else {
46496a62adaSjoyce mcintosh 			cfg = smb_config_getent(sc_id);
46596a62adaSjoyce mcintosh 			syslog(LOG_ERR, "smbd/%s: %s unable to get %s "
46696a62adaSjoyce mcintosh 			    "address: %d", cfg->sc_name, ipstr,
46796a62adaSjoyce mcintosh 			    a_family == AF_INET ?  "IPv4" : "IPv6", error);
46829bd2886SAlan Wright 			rc = SMBD_SMF_INVALID_ARG;
4697f667e74Sjose borrego 		}
4707f667e74Sjose borrego 	}
47129bd2886SAlan Wright 
4727f667e74Sjose borrego 	return (rc);
4737f667e74Sjose borrego }
4747f667e74Sjose borrego 
475da6c28aaSamw /*
476da6c28aaSamw  * smb_config_getnum
477da6c28aaSamw  *
478da6c28aaSamw  * Returns the value of a numeric config param.
479da6c28aaSamw  */
480da6c28aaSamw int
481dc20a302Sas200622 smb_config_getnum(smb_cfg_id_t id, int64_t *cint)
482da6c28aaSamw {
483dc20a302Sas200622 	smb_scfhandle_t *handle;
484da6c28aaSamw 	smb_cfg_param_t *cfg;
485dc20a302Sas200622 	int rc = SMBD_SMF_OK;
486da6c28aaSamw 
487dc20a302Sas200622 	*cint = 0;
488dc20a302Sas200622 	cfg = smb_config_getent(id);
489dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_INTEGER);
490dc20a302Sas200622 
491dc20a302Sas200622 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
492dc20a302Sas200622 	if (handle == NULL)
493dc20a302Sas200622 		return (SMBD_SMF_SYSTEM_ERR);
494dc20a302Sas200622 
495dc20a302Sas200622 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
496dc20a302Sas200622 	if (rc == SMBD_SMF_OK)
497dc20a302Sas200622 		rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint);
498dc20a302Sas200622 	smb_smf_scf_fini(handle);
499dc20a302Sas200622 
500da6c28aaSamw 	return (rc);
501da6c28aaSamw }
502da6c28aaSamw 
503dc20a302Sas200622 /*
504dc20a302Sas200622  * smb_config_getbool
505dc20a302Sas200622  *
506dc20a302Sas200622  * Returns the value of a boolean config param.
507dc20a302Sas200622  */
508dc20a302Sas200622 boolean_t
509dc20a302Sas200622 smb_config_getbool(smb_cfg_id_t id)
510dc20a302Sas200622 {
511dc20a302Sas200622 	smb_scfhandle_t *handle;
512dc20a302Sas200622 	smb_cfg_param_t *cfg;
513dc20a302Sas200622 	int rc = SMBD_SMF_OK;
514dc20a302Sas200622 	uint8_t vbool;
515dc20a302Sas200622 
516dc20a302Sas200622 	cfg = smb_config_getent(id);
517dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
518dc20a302Sas200622 
519dc20a302Sas200622 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
520dc20a302Sas200622 	if (handle == NULL)
521dc20a302Sas200622 		return (B_FALSE);
522dc20a302Sas200622 
523dc20a302Sas200622 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
524dc20a302Sas200622 	if (rc == SMBD_SMF_OK)
525dc20a302Sas200622 		rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool);
526dc20a302Sas200622 	smb_smf_scf_fini(handle);
527dc20a302Sas200622 
528dc20a302Sas200622 	return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE);
529dc20a302Sas200622 }
530dc20a302Sas200622 
531dc20a302Sas200622 /*
532dc20a302Sas200622  * smb_config_get
533dc20a302Sas200622  *
534dc20a302Sas200622  * This function returns the value of the requested config
535dc20a302Sas200622  * iterm regardless of its type in string format. This should
536dc20a302Sas200622  * be used when the config item type is not known by the caller.
537dc20a302Sas200622  */
538dc20a302Sas200622 int
539dc20a302Sas200622 smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz)
540dc20a302Sas200622 {
541dc20a302Sas200622 	smb_cfg_param_t *cfg;
542dc20a302Sas200622 	int64_t cint;
543dc20a302Sas200622 	int rc;
544dc20a302Sas200622 
545dc20a302Sas200622 	cfg = smb_config_getent(id);
546dc20a302Sas200622 	switch (cfg->sc_type) {
547dc20a302Sas200622 	case SCF_TYPE_ASTRING:
548dc20a302Sas200622 		return (smb_config_getstr(id, cbuf, bufsz));
549dc20a302Sas200622 
550dc20a302Sas200622 	case SCF_TYPE_INTEGER:
551dc20a302Sas200622 		rc = smb_config_getnum(id, &cint);
552dc20a302Sas200622 		if (rc == SMBD_SMF_OK)
553dc20a302Sas200622 			(void) snprintf(cbuf, bufsz, "%lld", cint);
554dc20a302Sas200622 		return (rc);
555dc20a302Sas200622 
556dc20a302Sas200622 	case SCF_TYPE_BOOLEAN:
557dc20a302Sas200622 		if (smb_config_getbool(id))
558dc20a302Sas200622 			(void) strlcpy(cbuf, "true", bufsz);
559dc20a302Sas200622 		else
560dc20a302Sas200622 			(void) strlcpy(cbuf, "false", bufsz);
561dc20a302Sas200622 		return (SMBD_SMF_OK);
562dc20a302Sas200622 	}
563dc20a302Sas200622 
564dc20a302Sas200622 	return (SMBD_SMF_INVALID_ARG);
565dc20a302Sas200622 }
566dc20a302Sas200622 
567dc20a302Sas200622 /*
568dc20a302Sas200622  * smb_config_setstr
569dc20a302Sas200622  *
570dc20a302Sas200622  * Set the specified config param with the given
571dc20a302Sas200622  * value.
572dc20a302Sas200622  */
573dc20a302Sas200622 int
574dc20a302Sas200622 smb_config_setstr(smb_cfg_id_t id, char *value)
575dc20a302Sas200622 {
576dc20a302Sas200622 	smb_scfhandle_t *handle;
577dc20a302Sas200622 	smb_cfg_param_t *cfg;
578dc20a302Sas200622 	int rc = SMBD_SMF_OK;
579dc20a302Sas200622 	boolean_t protected;
580dc20a302Sas200622 	char *tmp = NULL;
581dc20a302Sas200622 	char *pg;
582dc20a302Sas200622 
583dc20a302Sas200622 	cfg = smb_config_getent(id);
584dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_ASTRING);
585dc20a302Sas200622 
586b3700b07SGordon Ross 	if (id == SMB_CI_DOMAIN_SRV)
587b3700b07SGordon Ross 		return (smb_config_set_idmap_preferred_dc(value));
588b3700b07SGordon Ross 
589dc20a302Sas200622 	protected = B_FALSE;
59029bd2886SAlan Wright 
59129bd2886SAlan Wright 	switch (cfg->sc_flags) {
59229bd2886SAlan Wright 	case SMB_CF_PROTECTED:
59329bd2886SAlan Wright 		protected = B_TRUE;
59429bd2886SAlan Wright 		pg = SMBD_PROTECTED_PG_NAME;
59529bd2886SAlan Wright 		break;
59629bd2886SAlan Wright 	case SMB_CF_EXEC:
59729bd2886SAlan Wright 		pg = SMBD_EXEC_PG_NAME;
59829bd2886SAlan Wright 		break;
59929bd2886SAlan Wright 	default:
60029bd2886SAlan Wright 		pg = SMBD_PG_NAME;
60129bd2886SAlan Wright 		break;
602dc20a302Sas200622 	}
603dc20a302Sas200622 
604dc20a302Sas200622 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
605dc20a302Sas200622 	if (handle == NULL)
606dc20a302Sas200622 		return (SMBD_SMF_SYSTEM_ERR);
607dc20a302Sas200622 
608dc20a302Sas200622 	rc = smb_smf_create_service_pgroup(handle, pg);
609dc20a302Sas200622 	if (rc == SMBD_SMF_OK)
610dc20a302Sas200622 		rc = smb_smf_start_transaction(handle);
611dc20a302Sas200622 
612dc20a302Sas200622 	if (rc != SMBD_SMF_OK) {
613dc20a302Sas200622 		smb_smf_scf_fini(handle);
614dc20a302Sas200622 		return (rc);
615dc20a302Sas200622 	}
616dc20a302Sas200622 
617dc20a302Sas200622 	if (protected && value && (*value != '\0')) {
618dc20a302Sas200622 		if ((tmp = smb_base64_encode(value)) == NULL) {
619dc20a302Sas200622 			(void) smb_smf_end_transaction(handle);
620dc20a302Sas200622 			smb_smf_scf_fini(handle);
621dc20a302Sas200622 			return (SMBD_SMF_NO_MEMORY);
622dc20a302Sas200622 		}
623dc20a302Sas200622 
624dc20a302Sas200622 		value = tmp;
625dc20a302Sas200622 	}
626dc20a302Sas200622 
627dc20a302Sas200622 	rc = smb_smf_set_string_property(handle, cfg->sc_name, value);
628dc20a302Sas200622 
629dc20a302Sas200622 	free(tmp);
630dc20a302Sas200622 	(void) smb_smf_end_transaction(handle);
631dc20a302Sas200622 	smb_smf_scf_fini(handle);
632dc20a302Sas200622 	return (rc);
633da6c28aaSamw }
634da6c28aaSamw 
635da6c28aaSamw /*
636da6c28aaSamw  * smb_config_setnum
637da6c28aaSamw  *
638dc20a302Sas200622  * Sets a numeric configuration iterm
639da6c28aaSamw  */
640da6c28aaSamw int
641dc20a302Sas200622 smb_config_setnum(smb_cfg_id_t id, int64_t value)
642da6c28aaSamw {
643dc20a302Sas200622 	smb_scfhandle_t *handle;
644da6c28aaSamw 	smb_cfg_param_t *cfg;
645dc20a302Sas200622 	int rc = SMBD_SMF_OK;
646da6c28aaSamw 
647dc20a302Sas200622 	cfg = smb_config_getent(id);
648dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_INTEGER);
649da6c28aaSamw 
650da6c28aaSamw 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
651dc20a302Sas200622 	if (handle == NULL)
652dc20a302Sas200622 		return (SMBD_SMF_SYSTEM_ERR);
653da6c28aaSamw 
654dc20a302Sas200622 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
655dc20a302Sas200622 	if (rc == SMBD_SMF_OK)
656dc20a302Sas200622 		rc = smb_smf_start_transaction(handle);
657da6c28aaSamw 
658dc20a302Sas200622 	if (rc != SMBD_SMF_OK) {
659dc20a302Sas200622 		smb_smf_scf_fini(handle);
660da6c28aaSamw 		return (rc);
661da6c28aaSamw 	}
662da6c28aaSamw 
663dc20a302Sas200622 	rc = smb_smf_set_integer_property(handle, cfg->sc_name, value);
664dc20a302Sas200622 
665dc20a302Sas200622 	(void) smb_smf_end_transaction(handle);
666dc20a302Sas200622 	smb_smf_scf_fini(handle);
667dc20a302Sas200622 	return (rc);
668dc20a302Sas200622 }
669dc20a302Sas200622 
670dc20a302Sas200622 /*
671dc20a302Sas200622  * smb_config_setbool
672dc20a302Sas200622  *
673dc20a302Sas200622  * Sets a boolean configuration iterm
674dc20a302Sas200622  */
675dc20a302Sas200622 int
676dc20a302Sas200622 smb_config_setbool(smb_cfg_id_t id, boolean_t value)
677dc20a302Sas200622 {
678dc20a302Sas200622 	smb_scfhandle_t *handle;
679dc20a302Sas200622 	smb_cfg_param_t *cfg;
680dc20a302Sas200622 	int rc = SMBD_SMF_OK;
681dc20a302Sas200622 
682dc20a302Sas200622 	cfg = smb_config_getent(id);
683dc20a302Sas200622 	assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
684dc20a302Sas200622 
685dc20a302Sas200622 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
686dc20a302Sas200622 	if (handle == NULL)
687dc20a302Sas200622 		return (SMBD_SMF_SYSTEM_ERR);
688dc20a302Sas200622 
689dc20a302Sas200622 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
690dc20a302Sas200622 	if (rc == SMBD_SMF_OK)
691dc20a302Sas200622 		rc = smb_smf_start_transaction(handle);
692dc20a302Sas200622 
693dc20a302Sas200622 	if (rc != SMBD_SMF_OK) {
694dc20a302Sas200622 		smb_smf_scf_fini(handle);
695dc20a302Sas200622 		return (rc);
696dc20a302Sas200622 	}
697dc20a302Sas200622 
698dc20a302Sas200622 	rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value);
699dc20a302Sas200622 
700dc20a302Sas200622 	(void) smb_smf_end_transaction(handle);
701dc20a302Sas200622 	smb_smf_scf_fini(handle);
702dc20a302Sas200622 	return (rc);
703dc20a302Sas200622 }
704dc20a302Sas200622 
705dc20a302Sas200622 /*
706dc20a302Sas200622  * smb_config_set
707dc20a302Sas200622  *
708dc20a302Sas200622  * This function sets the value of the specified config
709dc20a302Sas200622  * iterm regardless of its type in string format. This should
710dc20a302Sas200622  * be used when the config item type is not known by the caller.
711dc20a302Sas200622  */
712dc20a302Sas200622 int
713dc20a302Sas200622 smb_config_set(smb_cfg_id_t id, char *value)
714dc20a302Sas200622 {
715dc20a302Sas200622 	smb_cfg_param_t *cfg;
716dc20a302Sas200622 	int64_t cint;
717dc20a302Sas200622 
718dc20a302Sas200622 	cfg = smb_config_getent(id);
719dc20a302Sas200622 	switch (cfg->sc_type) {
720dc20a302Sas200622 	case SCF_TYPE_ASTRING:
721dc20a302Sas200622 		return (smb_config_setstr(id, value));
722dc20a302Sas200622 
723dc20a302Sas200622 	case SCF_TYPE_INTEGER:
724dc20a302Sas200622 		cint = atoi(value);
725dc20a302Sas200622 		return (smb_config_setnum(id, cint));
726dc20a302Sas200622 
727dc20a302Sas200622 	case SCF_TYPE_BOOLEAN:
728dc20a302Sas200622 		return (smb_config_setbool(id, strcasecmp(value, "true") == 0));
729dc20a302Sas200622 	}
730dc20a302Sas200622 
731dc20a302Sas200622 	return (SMBD_SMF_INVALID_ARG);
732dc20a302Sas200622 }
733b819cea2SGordon Ross 
734b819cea2SGordon Ross int
735b819cea2SGordon Ross smb_config_get_debug()
736b819cea2SGordon Ross {
737b819cea2SGordon Ross 	int64_t val64;
738b819cea2SGordon Ross 	int val = 0;	/* default */
739b819cea2SGordon Ross 	smb_scfhandle_t *handle = NULL;
740b819cea2SGordon Ross 
741b819cea2SGordon Ross 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
742b819cea2SGordon Ross 	if (handle == NULL) {
743b819cea2SGordon Ross 		return (val);
744b819cea2SGordon Ross 	}
745b819cea2SGordon Ross 
746b819cea2SGordon Ross 	if (smb_smf_create_service_pgroup(handle,
747b819cea2SGordon Ross 	    SMBD_PG_NAME) != SMBD_SMF_OK) {
748b819cea2SGordon Ross 		smb_smf_scf_fini(handle);
749b819cea2SGordon Ross 		return (val);
750b819cea2SGordon Ross 	}
751b819cea2SGordon Ross 
752b819cea2SGordon Ross 	if (smb_smf_get_integer_property(handle, "debug", &val64) != 0) {
753b819cea2SGordon Ross 		smb_smf_scf_fini(handle);
754b819cea2SGordon Ross 		return (val);
755b819cea2SGordon Ross 	}
756b819cea2SGordon Ross 	val = (int)val64;
757b819cea2SGordon Ross 
758b819cea2SGordon Ross 	smb_smf_scf_fini(handle);
759b819cea2SGordon Ross 
760b819cea2SGordon Ross 	return (val);
761b819cea2SGordon Ross }
762b819cea2SGordon Ross 
763da6c28aaSamw uint8_t
764da6c28aaSamw smb_config_get_fg_flag()
765da6c28aaSamw {
766da6c28aaSamw 	uint8_t run_fg = 0; /* Default is to run in daemon mode */
767da6c28aaSamw 	smb_scfhandle_t *handle = NULL;
768da6c28aaSamw 
769da6c28aaSamw 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
770da6c28aaSamw 	if (handle == NULL) {
771da6c28aaSamw 		return (run_fg);
772da6c28aaSamw 	}
773da6c28aaSamw 
774da6c28aaSamw 	if (smb_smf_create_service_pgroup(handle,
775da6c28aaSamw 	    SMBD_PG_NAME) != SMBD_SMF_OK) {
776da6c28aaSamw 		smb_smf_scf_fini(handle);
777da6c28aaSamw 		return (run_fg);
778da6c28aaSamw 	}
779da6c28aaSamw 
780da6c28aaSamw 	if (smb_smf_get_boolean_property(handle, "run_fg", &run_fg) != 0) {
781da6c28aaSamw 		smb_smf_scf_fini(handle);
782da6c28aaSamw 		return (run_fg);
783da6c28aaSamw 	}
784da6c28aaSamw 
785da6c28aaSamw 	smb_smf_scf_fini(handle);
786da6c28aaSamw 
787da6c28aaSamw 	return (run_fg);
788da6c28aaSamw }
789da6c28aaSamw 
790da6c28aaSamw /*
7911ed6b69aSGordon Ross  * smb_config_get_ads_enable
7921ed6b69aSGordon Ross  *
7931ed6b69aSGordon Ross  * Returns value of the "config/use_ads" parameter
7941ed6b69aSGordon Ross  * from the IDMAP SMF configuration repository.
7951ed6b69aSGordon Ross  *
7961ed6b69aSGordon Ross  */
7971ed6b69aSGordon Ross boolean_t
7981ed6b69aSGordon Ross smb_config_get_ads_enable(void)
7991ed6b69aSGordon Ross {
8001ed6b69aSGordon Ross 	smb_scfhandle_t *handle = NULL;
8011ed6b69aSGordon Ross 	uint8_t vbool;
8021ed6b69aSGordon Ross 	int rc = 0;
8031ed6b69aSGordon Ross 
8041ed6b69aSGordon Ross 	handle = smb_smf_scf_init(IDMAP_FMRI_PREFIX);
8051ed6b69aSGordon Ross 	if (handle == NULL)
8061ed6b69aSGordon Ross 		return (B_FALSE);
8071ed6b69aSGordon Ross 
8081ed6b69aSGordon Ross 	rc = smb_smf_create_service_pgroup(handle, IDMAP_PG_NAME);
8091ed6b69aSGordon Ross 	if (rc == SMBD_SMF_OK)
8101ed6b69aSGordon Ross 		rc = smb_smf_get_boolean_property(handle, "use_ads", &vbool);
8111ed6b69aSGordon Ross 	smb_smf_scf_fini(handle);
8121ed6b69aSGordon Ross 
813b3700b07SGordon Ross 	return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_TRUE);
8141ed6b69aSGordon Ross }
8151ed6b69aSGordon Ross 
8161ed6b69aSGordon Ross /*
817da6c28aaSamw  * smb_config_get_localsid
818da6c28aaSamw  *
819da6c28aaSamw  * Returns value of the "config/machine_sid" parameter
820da6c28aaSamw  * from the IDMAP SMF configuration repository.
82112b65585SGordon Ross  * Result is allocated; caller should free.
822da6c28aaSamw  */
823da6c28aaSamw char *
824da6c28aaSamw smb_config_get_localsid(void)
825da6c28aaSamw {
826da6c28aaSamw 	return (smb_config_getenv_generic(MACHINE_SID, IDMAP_FMRI_PREFIX,
827da6c28aaSamw 	    IDMAP_PG_NAME));
828da6c28aaSamw }
829da6c28aaSamw 
830da6c28aaSamw /*
83112b65585SGordon Ross  * smb_config_get_localuuid
83212b65585SGordon Ross  *
83312b65585SGordon Ross  * Returns value of the "config/machine_uuid" parameter
83412b65585SGordon Ross  * from the IDMAP SMF configuration repository.
83512b65585SGordon Ross  *
83612b65585SGordon Ross  */
83712b65585SGordon Ross int
83812b65585SGordon Ross smb_config_get_localuuid(uuid_t uu)
83912b65585SGordon Ross {
84012b65585SGordon Ross 	char *s;
84112b65585SGordon Ross 
84212b65585SGordon Ross 	uuid_clear(uu);
84312b65585SGordon Ross 	s = smb_config_getenv_generic(MACHINE_UUID, IDMAP_FMRI_PREFIX,
84412b65585SGordon Ross 	    IDMAP_PG_NAME);
84512b65585SGordon Ross 	if (s == NULL)
84612b65585SGordon Ross 		return (-1);
84712b65585SGordon Ross 
84812b65585SGordon Ross 	if (uuid_parse(s, uu) < 0) {
84912b65585SGordon Ross 		free(s);
85012b65585SGordon Ross 		return (-1);
85112b65585SGordon Ross 	}
85212b65585SGordon Ross 
85312b65585SGordon Ross 	return (0);
85412b65585SGordon Ross }
85512b65585SGordon Ross 
856b3700b07SGordon Ross static int
857b3700b07SGordon Ross smb_config_get_idmap_preferred_dc(char *cbuf, int bufsz)
858b3700b07SGordon Ross {
859b3700b07SGordon Ross 	char *s;
860b3700b07SGordon Ross 	int len, rc = -1;
861b3700b07SGordon Ross 
862b3700b07SGordon Ross 	s = smb_config_getenv_generic(IDMAP_PREF_DC,
863b3700b07SGordon Ross 	    IDMAP_FMRI_PREFIX, IDMAP_PG_NAME);
864b3700b07SGordon Ross 	if (s != NULL) {
865b3700b07SGordon Ross 		len = strlcpy(cbuf, s, bufsz);
866b3700b07SGordon Ross 		if (len < bufsz)
867b3700b07SGordon Ross 			rc = 0;
868b3700b07SGordon Ross 		free(s);
869b3700b07SGordon Ross 	}
870b3700b07SGordon Ross 	return (rc);
871b3700b07SGordon Ross }
872b3700b07SGordon Ross 
873b3700b07SGordon Ross static int
874b3700b07SGordon Ross smb_config_set_idmap_preferred_dc(char *value)
875b3700b07SGordon Ross {
876b3700b07SGordon Ross 	return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
877b3700b07SGordon Ross 	    IDMAP_PREF_DC, value));
878b3700b07SGordon Ross }
879b3700b07SGordon Ross 
88012b65585SGordon Ross /*
881da6c28aaSamw  * smb_config_set_idmap_domain
882da6c28aaSamw  *
88355bf511dSas200622  * Set the "config/domain_name" parameter from IDMAP SMF repository.
884da6c28aaSamw  */
885da6c28aaSamw int
886da6c28aaSamw smb_config_set_idmap_domain(char *value)
887da6c28aaSamw {
888da6c28aaSamw 	return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
88955bf511dSas200622 	    IDMAP_DOMAIN, value));
890da6c28aaSamw }
891da6c28aaSamw 
892da6c28aaSamw /*
893da6c28aaSamw  * smb_config_refresh_idmap
894da6c28aaSamw  *
895da6c28aaSamw  * Refresh IDMAP SMF service after making changes to its configuration.
896da6c28aaSamw  */
897da6c28aaSamw int
898da6c28aaSamw smb_config_refresh_idmap(void)
899da6c28aaSamw {
900da6c28aaSamw 	char instance[32];
901da6c28aaSamw 
902da6c28aaSamw 	(void) snprintf(instance, sizeof (instance), "%s:default",
903da6c28aaSamw 	    IDMAP_FMRI_PREFIX);
904da6c28aaSamw 	return (smf_refresh_instance(instance));
905da6c28aaSamw }
906da6c28aaSamw 
907da6c28aaSamw int
908da6c28aaSamw smb_config_secmode_fromstr(char *secmode)
909da6c28aaSamw {
910da6c28aaSamw 	if (secmode == NULL)
911da6c28aaSamw 		return (SMB_SECMODE_WORKGRP);
912da6c28aaSamw 
913da6c28aaSamw 	if (strcasecmp(secmode, SMB_SECMODE_DOMAIN_STR) == 0)
914da6c28aaSamw 		return (SMB_SECMODE_DOMAIN);
915da6c28aaSamw 
916da6c28aaSamw 	return (SMB_SECMODE_WORKGRP);
917da6c28aaSamw }
918da6c28aaSamw 
919da6c28aaSamw char *
920da6c28aaSamw smb_config_secmode_tostr(int secmode)
921da6c28aaSamw {
922da6c28aaSamw 	if (secmode == SMB_SECMODE_DOMAIN)
923da6c28aaSamw 		return (SMB_SECMODE_DOMAIN_STR);
924da6c28aaSamw 
925da6c28aaSamw 	return (SMB_SECMODE_WORKGRP_STR);
926da6c28aaSamw }
927da6c28aaSamw 
928da6c28aaSamw int
929da6c28aaSamw smb_config_get_secmode()
930da6c28aaSamw {
931dc20a302Sas200622 	char p[16];
932da6c28aaSamw 
933dc20a302Sas200622 	(void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p));
934da6c28aaSamw 	return (smb_config_secmode_fromstr(p));
935da6c28aaSamw }
936da6c28aaSamw 
937da6c28aaSamw int
938da6c28aaSamw smb_config_set_secmode(int secmode)
939da6c28aaSamw {
940da6c28aaSamw 	char *p;
941da6c28aaSamw 
942da6c28aaSamw 	p = smb_config_secmode_tostr(secmode);
943dc20a302Sas200622 	return (smb_config_setstr(SMB_CI_SECURITY, p));
944dc20a302Sas200622 }
945dc20a302Sas200622 
9468d7e4166Sjose borrego void
94729bd2886SAlan Wright smb_config_getdomaininfo(char *domain, char *fqdn, char *sid, char *forest,
94829bd2886SAlan Wright     char *guid)
9498d7e4166Sjose borrego {
95029bd2886SAlan Wright 	if (domain)
95129bd2886SAlan Wright 		(void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain,
95229bd2886SAlan Wright 		    NETBIOS_NAME_SZ);
95329bd2886SAlan Wright 
95429bd2886SAlan Wright 	if (fqdn)
95529bd2886SAlan Wright 		(void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn,
95629bd2886SAlan Wright 		    MAXHOSTNAMELEN);
95729bd2886SAlan Wright 
95829bd2886SAlan Wright 	if (sid)
95929bd2886SAlan Wright 		(void) smb_config_getstr(SMB_CI_DOMAIN_SID, sid,
96029bd2886SAlan Wright 		    SMB_SID_STRSZ);
96129bd2886SAlan Wright 
96229bd2886SAlan Wright 	if (forest)
96329bd2886SAlan Wright 		(void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest,
96429bd2886SAlan Wright 		    MAXHOSTNAMELEN);
96529bd2886SAlan Wright 
96629bd2886SAlan Wright 	if (guid)
9678d7e4166Sjose borrego 		(void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid,
9688d7e4166Sjose borrego 		    UUID_PRINTABLE_STRING_LENGTH);
9698d7e4166Sjose borrego }
9708d7e4166Sjose borrego 
9718d7e4166Sjose borrego void
97229bd2886SAlan Wright smb_config_setdomaininfo(char *domain, char *fqdn, char *sid, char *forest,
97329bd2886SAlan Wright     char *guid)
9748d7e4166Sjose borrego {
97529bd2886SAlan Wright 	if (domain)
9768d7e4166Sjose borrego 		(void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain);
97729bd2886SAlan Wright 	if (fqdn)
9788d7e4166Sjose borrego 		(void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn);
97929bd2886SAlan Wright 	if (sid)
98029bd2886SAlan Wright 		(void) smb_config_setstr(SMB_CI_DOMAIN_SID, sid);
98129bd2886SAlan Wright 	if (forest)
9828d7e4166Sjose borrego 		(void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest);
98329bd2886SAlan Wright 	if (guid)
9848d7e4166Sjose borrego 		(void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid);
9858d7e4166Sjose borrego }
9869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The version stored in SMF in string format as N.N where
9899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * N is a number defined by Microsoft. The first number represents
9909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the major version and the second number is the minor version.
9919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Current defined values can be found here in 'ver_table'.
9929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function reads the SMF string value and converts it to
9949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * two numbers returned in the given 'version' structure.
9959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Current default version number is 5.0 which is for Windows 2000.
9969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_config_get_version(smb_version_t *version)
9999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_version_t tmpver;
10019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char verstr[SMB_VERSTR_LEN];
10029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *p;
10039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc, i;
10049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	static smb_version_t ver_table [] = {
1005fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_NT,	SMB_MINOR_NT,		1381,	0 },
1006fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_2000,	SMB_MINOR_2000,		2195,	0 },
1007fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_XP,	SMB_MINOR_XP,		2196,	0 },
1008fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_2003,	SMB_MINOR_2003,		2196,	0 },
1009fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_VISTA,	SMB_MINOR_VISTA,	6000,	0 },
1010fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_2008,	SMB_MINOR_2008,		6000,	0 },
1011fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_2008R2,	SMB_MINOR_2008R2,	7007,	0 },
1012fd9ee8b5Sjoyce mcintosh 		{ 0, SMB_MAJOR_7,	SMB_MINOR_7,		7007,	0 }
10139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	};
10149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	*version = ver_table[1];
1016fd9ee8b5Sjoyce mcintosh 	version->sv_size = sizeof (smb_version_t);
10179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smb_config_getstr(SMB_CI_VERSION, verstr, sizeof (verstr));
10199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != SMBD_SMF_OK)
10209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
10219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((p = strchr(verstr, '.')) == NULL)
10239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
10249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	*p = '\0';
10269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tmpver.sv_major = (uint8_t)atoi(verstr);
10279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tmpver.sv_minor = (uint8_t)atoi(p + 1);
10289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < sizeof (ver_table)/sizeof (ver_table[0]); ++i) {
10309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((tmpver.sv_major == ver_table[i].sv_major) &&
10319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (tmpver.sv_minor == ver_table[i].sv_minor)) {
10329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			*version = ver_table[i];
1033fd9ee8b5Sjoyce mcintosh 			version->sv_size = sizeof (smb_version_t);
10349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
10359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
10369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1039148c5f43SAlan Wright /*
1040148c5f43SAlan Wright  * Reads share exec script properties
1041148c5f43SAlan Wright  */
1042148c5f43SAlan Wright uint32_t
1043148c5f43SAlan Wright smb_config_get_execinfo(char *map, char *unmap, size_t bufsz)
1044148c5f43SAlan Wright {
1045148c5f43SAlan Wright 	char buf[MAXPATHLEN];
1046148c5f43SAlan Wright 	uint32_t flags = 0;
1047148c5f43SAlan Wright 
1048148c5f43SAlan Wright 	if (map == NULL) {
1049148c5f43SAlan Wright 		map = buf;
1050148c5f43SAlan Wright 		bufsz = MAXPATHLEN;
1051148c5f43SAlan Wright 	}
1052148c5f43SAlan Wright 
1053148c5f43SAlan Wright 	*map = '\0';
1054148c5f43SAlan Wright 	(void) smb_config_getstr(SMB_CI_MAP, map, bufsz);
1055148c5f43SAlan Wright 	if (*map != '\0')
1056148c5f43SAlan Wright 		flags |= SMB_EXEC_MAP;
1057148c5f43SAlan Wright 
1058148c5f43SAlan Wright 	if (unmap == NULL) {
1059148c5f43SAlan Wright 		unmap = buf;
1060148c5f43SAlan Wright 		bufsz = MAXPATHLEN;
1061148c5f43SAlan Wright 	}
1062148c5f43SAlan Wright 
1063148c5f43SAlan Wright 	*unmap = '\0';
1064148c5f43SAlan Wright 	(void) smb_config_getstr(SMB_CI_UNMAP, unmap, bufsz);
1065148c5f43SAlan Wright 	if (*unmap != '\0')
1066148c5f43SAlan Wright 		flags |= SMB_EXEC_UNMAP;
1067148c5f43SAlan Wright 
1068148c5f43SAlan Wright 	*buf = '\0';
1069148c5f43SAlan Wright 	(void) smb_config_getstr(SMB_CI_DISPOSITION, buf, sizeof (buf));
1070148c5f43SAlan Wright 	if (*buf != '\0')
1071148c5f43SAlan Wright 		if (strcasecmp(buf, SMB_EXEC_DISP_TERMINATE) == 0)
1072148c5f43SAlan Wright 			flags |= SMB_EXEC_TERM;
1073148c5f43SAlan Wright 
1074148c5f43SAlan Wright 	return (flags);
1075148c5f43SAlan Wright }
1076148c5f43SAlan Wright 
10779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static smb_cfg_param_t *
10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_config_getent(smb_cfg_id_t id)
10799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int i;
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < SMB_CI_MAX; i++)
10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (smb_cfg_table[i].sc_id == id)
10849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (&smb_cfg_table[id]);
10859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(0);
10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (NULL);
10889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1089*a90cf9f2SGordon Ross 
1090*a90cf9f2SGordon Ross 
1091*a90cf9f2SGordon Ross /*
1092*a90cf9f2SGordon Ross  * We store the max SMB protocol version in SMF as a string,
1093*a90cf9f2SGordon Ross  * (for convenience of svccfg etc) but the programmatic get/set
1094*a90cf9f2SGordon Ross  * interfaces use the numeric form.
1095*a90cf9f2SGordon Ross  *
1096*a90cf9f2SGordon Ross  * The numeric values are as defined in the [MS-SMB2] spec.
1097*a90cf9f2SGordon Ross  * except for how we represent "1" (for SMB1) which is an
1098*a90cf9f2SGordon Ross  * arbitrary value below SMB2_VERS_BASE.
1099*a90cf9f2SGordon Ross  */
1100*a90cf9f2SGordon Ross static struct str_val
1101*a90cf9f2SGordon Ross smb_versions[] = {
1102*a90cf9f2SGordon Ross 	{ "3.0",	SMB_VERS_3_0 },
1103*a90cf9f2SGordon Ross 	{ "2.1",	SMB_VERS_2_1 },
1104*a90cf9f2SGordon Ross 	{ "2.002",	SMB_VERS_2_002 },
1105*a90cf9f2SGordon Ross 	{ "1",		SMB_VERS_1 },
1106*a90cf9f2SGordon Ross 	{ NULL,		0 }
1107*a90cf9f2SGordon Ross };
1108*a90cf9f2SGordon Ross 
1109*a90cf9f2SGordon Ross /*
1110*a90cf9f2SGordon Ross  * This really should be the latest (SMB_VERS_3_0)
1111*a90cf9f2SGordon Ross  * but we're being cautious with SMB3 for a while.
1112*a90cf9f2SGordon Ross  */
1113*a90cf9f2SGordon Ross uint32_t max_protocol_default = SMB_VERS_2_1;
1114*a90cf9f2SGordon Ross 
1115*a90cf9f2SGordon Ross uint32_t
1116*a90cf9f2SGordon Ross smb_config_get_max_protocol(void)
1117*a90cf9f2SGordon Ross {
1118*a90cf9f2SGordon Ross 	char str[SMB_VERSTR_LEN];
1119*a90cf9f2SGordon Ross 	int i, rc;
1120*a90cf9f2SGordon Ross 
1121*a90cf9f2SGordon Ross 	rc = smb_config_getstr(SMB_CI_MAX_PROTOCOL, str, sizeof (str));
1122*a90cf9f2SGordon Ross 	if (rc == SMBD_SMF_OK) {
1123*a90cf9f2SGordon Ross 		for (i = 0; smb_versions[i].str != NULL; i++) {
1124*a90cf9f2SGordon Ross 			if (strcmp(str, smb_versions[i].str) == 0)
1125*a90cf9f2SGordon Ross 				return (smb_versions[i].val);
1126*a90cf9f2SGordon Ross 		}
1127*a90cf9f2SGordon Ross 		if (str[0] != '\0') {
1128*a90cf9f2SGordon Ross 			syslog(LOG_ERR, "smbd/max_protocol value invalid");
1129*a90cf9f2SGordon Ross 		}
1130*a90cf9f2SGordon Ross 	}
1131*a90cf9f2SGordon Ross 
1132*a90cf9f2SGordon Ross 	return (max_protocol_default);
1133*a90cf9f2SGordon Ross }
1134*a90cf9f2SGordon Ross 
1135*a90cf9f2SGordon Ross int
1136*a90cf9f2SGordon Ross smb_config_check_protocol(char *value)
1137*a90cf9f2SGordon Ross {
1138*a90cf9f2SGordon Ross 	int i;
1139*a90cf9f2SGordon Ross 
1140*a90cf9f2SGordon Ross 	for (i = 0; smb_versions[i].str != NULL; i++) {
1141*a90cf9f2SGordon Ross 		if (strcmp(value, smb_versions[i].str) == 0)
1142*a90cf9f2SGordon Ross 			return (0);
1143*a90cf9f2SGordon Ross 	}
1144*a90cf9f2SGordon Ross 
1145*a90cf9f2SGordon Ross 	return (-1);
1146*a90cf9f2SGordon Ross }
1147*a90cf9f2SGordon Ross 
1148*a90cf9f2SGordon Ross /*
1149*a90cf9f2SGordon Ross  * If smb2_enable is present and max_protocol is empty,
1150*a90cf9f2SGordon Ross  * set max_protocol.  Delete smb2_enable.
1151*a90cf9f2SGordon Ross  */
1152*a90cf9f2SGordon Ross static void
1153*a90cf9f2SGordon Ross upgrade_smb2_enable()
1154*a90cf9f2SGordon Ross {
1155*a90cf9f2SGordon Ross 	smb_scfhandle_t *handle;
1156*a90cf9f2SGordon Ross 	char *s2e_name = "smb2_enable";
1157*a90cf9f2SGordon Ross 	char *s2e_sval;
1158*a90cf9f2SGordon Ross 	uint8_t	s2e_bval;
1159*a90cf9f2SGordon Ross 	char *maxp_name = "max_protocol";
1160*a90cf9f2SGordon Ross 	char *maxp_sval;
1161*a90cf9f2SGordon Ross 	char verstr[SMB_VERSTR_LEN];
1162*a90cf9f2SGordon Ross 	int rc;
1163*a90cf9f2SGordon Ross 
1164*a90cf9f2SGordon Ross 	handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
1165*a90cf9f2SGordon Ross 	if (handle == NULL)
1166*a90cf9f2SGordon Ross 		return;
1167*a90cf9f2SGordon Ross 	rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
1168*a90cf9f2SGordon Ross 	if (rc != SMBD_SMF_OK)
1169*a90cf9f2SGordon Ross 		goto out;
1170*a90cf9f2SGordon Ross 
1171*a90cf9f2SGordon Ross 	/* Is there an "smb2_enable" property? */
1172*a90cf9f2SGordon Ross 	rc = smb_smf_get_boolean_property(handle, s2e_name, &s2e_bval);
1173*a90cf9f2SGordon Ross 	if (rc != SMBD_SMF_OK) {
1174*a90cf9f2SGordon Ross 		syslog(LOG_DEBUG, "upgrade: smb2_enable not found");
1175*a90cf9f2SGordon Ross 		goto out;
1176*a90cf9f2SGordon Ross 	}
1177*a90cf9f2SGordon Ross 
1178*a90cf9f2SGordon Ross 	/*
1179*a90cf9f2SGordon Ross 	 * We will try to delete the smb2_enable property, so we need
1180*a90cf9f2SGordon Ross 	 * the transaction to start now, before we modify max_protocol
1181*a90cf9f2SGordon Ross 	 */
1182*a90cf9f2SGordon Ross 	if ((rc = smb_smf_start_transaction(handle)) != 0) {
1183*a90cf9f2SGordon Ross 		syslog(LOG_DEBUG, "upgrade_smb2_enable: start trans (%d)", rc);
1184*a90cf9f2SGordon Ross 		goto out;
1185*a90cf9f2SGordon Ross 	}
1186*a90cf9f2SGordon Ross 
1187*a90cf9f2SGordon Ross 	/*
1188*a90cf9f2SGordon Ross 	 * Old (smb2_enable) property exists.
1189*a90cf9f2SGordon Ross 	 * Does the new one? (max_protocol)
1190*a90cf9f2SGordon Ross 	 */
1191*a90cf9f2SGordon Ross 	rc = smb_smf_get_string_property(handle, maxp_name,
1192*a90cf9f2SGordon Ross 	    verstr, sizeof (verstr));
1193*a90cf9f2SGordon Ross 	if (rc == SMBD_SMF_OK && !smb_config_check_protocol(verstr)) {
1194*a90cf9f2SGordon Ross 		syslog(LOG_DEBUG, "upgrade: found %s = %s",
1195*a90cf9f2SGordon Ross 		    maxp_name, verstr);
1196*a90cf9f2SGordon Ross 		/* Leave existing max_protocol as we found it. */
1197*a90cf9f2SGordon Ross 	} else {
1198*a90cf9f2SGordon Ross 		/*
1199*a90cf9f2SGordon Ross 		 * New property missing or invalid.
1200*a90cf9f2SGordon Ross 		 * Upgrade from "smb2_enable".
1201*a90cf9f2SGordon Ross 		 */
1202*a90cf9f2SGordon Ross 		if (s2e_bval == 0) {
1203*a90cf9f2SGordon Ross 			s2e_sval = "false";
1204*a90cf9f2SGordon Ross 			maxp_sval = "1";
1205*a90cf9f2SGordon Ross 		} else {
1206*a90cf9f2SGordon Ross 			s2e_sval = "true";
1207*a90cf9f2SGordon Ross 			maxp_sval = "2.1";
1208*a90cf9f2SGordon Ross 		}
1209*a90cf9f2SGordon Ross 		/*
1210*a90cf9f2SGordon Ross 		 * Note: Need this in the same transaction as the
1211*a90cf9f2SGordon Ross 		 * delete of smb2_enable below.
1212*a90cf9f2SGordon Ross 		 */
1213*a90cf9f2SGordon Ross 		rc = smb_smf_set_string_property(handle, maxp_name, maxp_sval);
1214*a90cf9f2SGordon Ross 		if (rc != SMBD_SMF_OK) {
1215*a90cf9f2SGordon Ross 			syslog(LOG_ERR, "failed to set smbd/%d (%d)",
1216*a90cf9f2SGordon Ross 			    maxp_name, rc);
1217*a90cf9f2SGordon Ross 			goto out;
1218*a90cf9f2SGordon Ross 		}
1219*a90cf9f2SGordon Ross 		syslog(LOG_INFO, "upgrade smbd/smb2_enable=%s "
1220*a90cf9f2SGordon Ross 		    "converted to smbd/max_protocol=%s",
1221*a90cf9f2SGordon Ross 		    s2e_sval, maxp_sval);
1222*a90cf9f2SGordon Ross 	}
1223*a90cf9f2SGordon Ross 
1224*a90cf9f2SGordon Ross 	/*
1225*a90cf9f2SGordon Ross 	 * Delete the old smb2_enable property.
1226*a90cf9f2SGordon Ross 	 */
1227*a90cf9f2SGordon Ross 	if ((rc = smb_smf_delete_property(handle, s2e_name)) != 0) {
1228*a90cf9f2SGordon Ross 		syslog(LOG_DEBUG, "upgrade_smb2_enable: delete prop (%d)", rc);
1229*a90cf9f2SGordon Ross 	} else if ((rc = smb_smf_end_transaction(handle)) != 0) {
1230*a90cf9f2SGordon Ross 		syslog(LOG_DEBUG, "upgrade_smb2_enable: end trans (%d)", rc);
1231*a90cf9f2SGordon Ross 	}
1232*a90cf9f2SGordon Ross 	if (rc != 0) {
1233*a90cf9f2SGordon Ross 		syslog(LOG_ERR, "failed to delete property smbd/%d (%d)",
1234*a90cf9f2SGordon Ross 		    s2e_name, rc);
1235*a90cf9f2SGordon Ross 	}
1236*a90cf9f2SGordon Ross 
1237*a90cf9f2SGordon Ross out:
1238*a90cf9f2SGordon Ross 	(void) smb_smf_end_transaction(handle);
1239*a90cf9f2SGordon Ross 	smb_smf_scf_fini(handle);
1240*a90cf9f2SGordon Ross }
1241*a90cf9f2SGordon Ross 
1242*a90cf9f2SGordon Ross 
1243*a90cf9f2SGordon Ross /*
1244*a90cf9f2SGordon Ross  * Run once at startup convert old SMF settings to current.
1245*a90cf9f2SGordon Ross  */
1246*a90cf9f2SGordon Ross void
1247*a90cf9f2SGordon Ross smb_config_upgrade(void)
1248*a90cf9f2SGordon Ross {
1249*a90cf9f2SGordon Ross 	upgrade_smb2_enable();
1250*a90cf9f2SGordon Ross }
1251