xref: /titanic_50/usr/src/cmd/smbsrv/smbadm/smbadm.c (revision faa1795a28a5c712eed6d0a3f84d98c368a316c6)
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 /*
22dc20a302Sas200622  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23da6c28aaSamw  * Use is subject to license terms.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
27da6c28aaSamw 
28da6c28aaSamw /*
29da6c28aaSamw  * This module contains smbadm CLI which offers smb configuration
30da6c28aaSamw  * functionalities.
31da6c28aaSamw  */
32da6c28aaSamw #include <stdlib.h>
33da6c28aaSamw #include <stdio.h>
34da6c28aaSamw #include <syslog.h>
35da6c28aaSamw #include <strings.h>
36da6c28aaSamw #include <limits.h>
37da6c28aaSamw #include <getopt.h>
38da6c28aaSamw #include <libintl.h>
39da6c28aaSamw #include <zone.h>
40da6c28aaSamw #include <grp.h>
41da6c28aaSamw #include <libgen.h>
42da6c28aaSamw 
43da6c28aaSamw #include <smbsrv/libsmb.h>
44da6c28aaSamw 
45da6c28aaSamw typedef enum {
46da6c28aaSamw 	HELP_ADD_MEMBER,
47da6c28aaSamw 	HELP_CREATE,
48da6c28aaSamw 	HELP_DELETE,
49da6c28aaSamw 	HELP_DEL_MEMBER,
50da6c28aaSamw 	HELP_GET,
51da6c28aaSamw 	HELP_JOIN,
52da6c28aaSamw 	HELP_LIST,
53da6c28aaSamw 	HELP_RENAME,
54da6c28aaSamw 	HELP_SET,
55da6c28aaSamw 	HELP_SHOW,
56da6c28aaSamw 	HELP_UDISABLE,
57da6c28aaSamw 	HELP_UENABLE
58da6c28aaSamw } smbadm_help_t;
59da6c28aaSamw 
60*faa1795aSjb150015 #define	SMBADM_CMDF_GROUP	0x01
61*faa1795aSjb150015 
62da6c28aaSamw typedef struct smbadm_cmdinfo {
63da6c28aaSamw 	char *name;
64da6c28aaSamw 	int (*func)(int, char **);
65da6c28aaSamw 	smbadm_help_t usage;
66*faa1795aSjb150015 	uint32_t flags;
67da6c28aaSamw } smbadm_cmdinfo_t;
68da6c28aaSamw 
69da6c28aaSamw smbadm_cmdinfo_t *curcmd;
70da6c28aaSamw static char *progname;
71da6c28aaSamw 
72da6c28aaSamw static int smbadm_join(int, char **);
73da6c28aaSamw static int smbadm_list(int, char **);
74da6c28aaSamw static int smbadm_group_create(int, char **);
75da6c28aaSamw static int smbadm_group_delete(int, char **);
76da6c28aaSamw static int smbadm_group_rename(int, char **);
77da6c28aaSamw static int smbadm_group_show(int, char **);
78da6c28aaSamw static int smbadm_group_getprop(int, char **);
79da6c28aaSamw static int smbadm_group_setprop(int, char **);
80da6c28aaSamw static int smbadm_group_addmember(int, char **);
81da6c28aaSamw static int smbadm_group_delmember(int, char **);
82da6c28aaSamw static int smbadm_user_disable(int, char **);
83da6c28aaSamw static int smbadm_user_enable(int, char **);
84da6c28aaSamw 
85da6c28aaSamw static smbadm_cmdinfo_t smbadm_cmdtable[] =
86da6c28aaSamw {
87*faa1795aSjb150015 	{ "add-member",		smbadm_group_addmember,	HELP_ADD_MEMBER,
88*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
89*faa1795aSjb150015 	{ "create",		smbadm_group_create,	HELP_CREATE,
90*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
91*faa1795aSjb150015 	{ "delete",		smbadm_group_delete,	HELP_DELETE,
92*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
93*faa1795aSjb150015 	{ "disable-user",	smbadm_user_disable,	HELP_UDISABLE,	0 },
94*faa1795aSjb150015 	{ "enable-user",	smbadm_user_enable,	HELP_UENABLE,	0 },
95*faa1795aSjb150015 	{ "get",		smbadm_group_getprop,	HELP_GET,
96*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
97*faa1795aSjb150015 	{ "join",		smbadm_join,		HELP_JOIN,	0 },
98*faa1795aSjb150015 	{ "list",		smbadm_list,		HELP_LIST,	0 },
99*faa1795aSjb150015 	{ "remove-member",	smbadm_group_delmember,	HELP_DEL_MEMBER,
100*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
101*faa1795aSjb150015 	{ "rename",		smbadm_group_rename,	HELP_RENAME,
102*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
103*faa1795aSjb150015 	{ "set",		smbadm_group_setprop,	HELP_SET,
104*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
105*faa1795aSjb150015 	{ "show",		smbadm_group_show,	HELP_SHOW,
106*faa1795aSjb150015 	SMBADM_CMDF_GROUP },
107da6c28aaSamw };
108da6c28aaSamw 
109da6c28aaSamw #define	SMBADM_NCMD	(sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0]))
110da6c28aaSamw 
111da6c28aaSamw typedef struct smbadm_prop {
112da6c28aaSamw 	char *p_name;
113da6c28aaSamw 	char *p_value;
114da6c28aaSamw } smbadm_prop_t;
115da6c28aaSamw 
116da6c28aaSamw typedef struct smbadm_prop_handle {
117da6c28aaSamw 	char *p_name;
118da6c28aaSamw 	char *p_dispvalue;
119da6c28aaSamw 	int (*p_setfn)(char *, smbadm_prop_t *);
120da6c28aaSamw 	int (*p_getfn)(char *, smbadm_prop_t *);
121da6c28aaSamw 	boolean_t (*p_chkfn)(smbadm_prop_t *);
122da6c28aaSamw } smbadm_prop_handle_t;
123da6c28aaSamw 
124da6c28aaSamw static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval);
125da6c28aaSamw static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop);
126da6c28aaSamw static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname);
127da6c28aaSamw 
128da6c28aaSamw static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop);
129da6c28aaSamw static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop);
130da6c28aaSamw static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop);
131da6c28aaSamw static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop);
132da6c28aaSamw static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop);
133da6c28aaSamw static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop);
134da6c28aaSamw static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop);
135da6c28aaSamw static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop);
136da6c28aaSamw static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop);
137da6c28aaSamw 
138da6c28aaSamw static smbadm_prop_handle_t smbadm_ptable[] = {
139da6c28aaSamw 	{"backup",	"on | off", 	smbadm_setprop_backup,
140da6c28aaSamw 	smbadm_getprop_backup,	smbadm_chkprop_priv 	},
141da6c28aaSamw 	{"restore",	"on | off",	smbadm_setprop_restore,
142da6c28aaSamw 	smbadm_getprop_restore,	smbadm_chkprop_priv	},
143da6c28aaSamw 	{"take-ownership", "on | off",	smbadm_setprop_tkowner,
144da6c28aaSamw 	smbadm_getprop_tkowner,	smbadm_chkprop_priv	},
145da6c28aaSamw 	{"description",	"<string>",	smbadm_setprop_desc,
146da6c28aaSamw 	smbadm_getprop_desc,	NULL			},
147da6c28aaSamw };
148da6c28aaSamw 
149*faa1795aSjb150015 static int smbadm_grpcmd_init(void);
150*faa1795aSjb150015 static void smbadm_grpcmd_fini(void);
151da6c28aaSamw static const char *smbadm_pwd_strerror(int error);
152da6c28aaSamw 
153da6c28aaSamw /*
154da6c28aaSamw  * Number of supported properties
155da6c28aaSamw  */
156da6c28aaSamw #define	SMBADM_NPROP	(sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0]))
157da6c28aaSamw 
158da6c28aaSamw static void
159da6c28aaSamw smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd)
160da6c28aaSamw {
161da6c28aaSamw 	switch (cmd->usage) {
162da6c28aaSamw 	case HELP_ADD_MEMBER:
163da6c28aaSamw 		(void) fprintf(fp,
164da6c28aaSamw 		    gettext("\t%s -m member [[-m member] ...] group\n"),
165da6c28aaSamw 		    cmd->name);
166da6c28aaSamw 		return;
167da6c28aaSamw 
168da6c28aaSamw 	case HELP_CREATE:
169da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [-d description] group\n"),
170da6c28aaSamw 		    cmd->name);
171da6c28aaSamw 		return;
172da6c28aaSamw 
173da6c28aaSamw 	case HELP_DELETE:
174da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s group\n"), cmd->name);
175da6c28aaSamw 		return;
176da6c28aaSamw 
177da6c28aaSamw 	case HELP_UDISABLE:
178da6c28aaSamw 	case HELP_UENABLE:
179da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s user\n"), cmd->name);
180da6c28aaSamw 		return;
181da6c28aaSamw 
182da6c28aaSamw 	case HELP_GET:
183da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"),
184da6c28aaSamw 		    cmd->name);
185da6c28aaSamw 		return;
186da6c28aaSamw 
187da6c28aaSamw 	case HELP_JOIN:
188da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s -u username domain\n"
189da6c28aaSamw 		    "\t%s -w workgroup\n"), cmd->name, cmd->name);
190da6c28aaSamw 		return;
191da6c28aaSamw 
192da6c28aaSamw 	case HELP_LIST:
193da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s\n"), cmd->name);
194da6c28aaSamw 		return;
195da6c28aaSamw 
196da6c28aaSamw 	case HELP_DEL_MEMBER:
197da6c28aaSamw 		(void) fprintf(fp,
198da6c28aaSamw 		    gettext("\t%s -m member [[-m member] ...] group\n"),
199da6c28aaSamw 		    cmd->name);
200da6c28aaSamw 		return;
201da6c28aaSamw 
202da6c28aaSamw 	case HELP_RENAME:
203da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s group new-group\n"),
204da6c28aaSamw 		    cmd->name);
205da6c28aaSamw 		return;
206da6c28aaSamw 
207da6c28aaSamw 	case HELP_SET:
208da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s -p property=value "
209da6c28aaSamw 		    "[[-p property=value] ...] group\n"), cmd->name);
210da6c28aaSamw 		return;
211da6c28aaSamw 
212da6c28aaSamw 	case HELP_SHOW:
213da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"),
214da6c28aaSamw 		    cmd->name);
215da6c28aaSamw 		return;
216da6c28aaSamw 
217da6c28aaSamw 	}
218da6c28aaSamw 
219da6c28aaSamw 	abort();
220da6c28aaSamw 	/* NOTREACHED */
221da6c28aaSamw }
222da6c28aaSamw 
223da6c28aaSamw static void
224da6c28aaSamw smbadm_usage(boolean_t requested)
225da6c28aaSamw {
226da6c28aaSamw 	FILE *fp = requested ? stdout : stderr;
227da6c28aaSamw 	boolean_t show_props = B_FALSE;
228da6c28aaSamw 	int i;
229da6c28aaSamw 
230da6c28aaSamw 	if (curcmd == NULL) {
231da6c28aaSamw 		(void) fprintf(fp,
232da6c28aaSamw 		    gettext("usage: %s [-h | <command> [options]]\n"),
233da6c28aaSamw 		    progname);
234da6c28aaSamw 		(void) fprintf(fp,
235da6c28aaSamw 		    gettext("where 'command' is one of the following:\n\n"));
236da6c28aaSamw 
237da6c28aaSamw 		for (i = 0; i < SMBADM_NCMD; i++)
238da6c28aaSamw 			smbadm_cmdusage(fp, &smbadm_cmdtable[i]);
239da6c28aaSamw 
240da6c28aaSamw 		(void) fprintf(fp,
241da6c28aaSamw 		    gettext("\nFor property list, run %s %s|%s\n"),
242da6c28aaSamw 		    progname, "get", "set");
243da6c28aaSamw 
244da6c28aaSamw 		exit(requested ? 0 : 2);
245da6c28aaSamw 	}
246da6c28aaSamw 
247da6c28aaSamw 	(void) fprintf(fp, gettext("usage:\n"));
248da6c28aaSamw 	smbadm_cmdusage(fp, curcmd);
249da6c28aaSamw 
250da6c28aaSamw 	if (strcmp(curcmd->name, "get") == 0 ||
251da6c28aaSamw 	    strcmp(curcmd->name, "set") == 0)
252da6c28aaSamw 		show_props = B_TRUE;
253da6c28aaSamw 
254da6c28aaSamw 	if (show_props) {
255da6c28aaSamw 		(void) fprintf(fp,
256da6c28aaSamw 		    gettext("\nThe following properties are supported:\n"));
257da6c28aaSamw 
258da6c28aaSamw 		(void) fprintf(fp, "\n\t%-16s   %s\n\n",
259da6c28aaSamw 		    "PROPERTY", "VALUES");
260da6c28aaSamw 
261da6c28aaSamw 		for (i = 0; i < SMBADM_NPROP; i++) {
262da6c28aaSamw 			(void) fprintf(fp, "\t%-16s   %s\n",
263da6c28aaSamw 			    smbadm_ptable[i].p_name,
264da6c28aaSamw 			    smbadm_ptable[i].p_dispvalue);
265da6c28aaSamw 		}
266da6c28aaSamw 	}
267da6c28aaSamw 
268da6c28aaSamw 	exit(requested ? 0 : 2);
269da6c28aaSamw }
270da6c28aaSamw 
271da6c28aaSamw /*
272da6c28aaSamw  * smbadm_join
273da6c28aaSamw  *
274da6c28aaSamw  * Join the given domain/workgroup
275da6c28aaSamw  */
276da6c28aaSamw static int
277da6c28aaSamw smbadm_join(int argc, char **argv)
278da6c28aaSamw {
279da6c28aaSamw 	char option;
280da6c28aaSamw 	smb_joininfo_t jdi;
281da6c28aaSamw 	boolean_t join_w = B_FALSE;
282da6c28aaSamw 	boolean_t join_d = B_FALSE;
283da6c28aaSamw 	uint32_t status;
284*faa1795aSjb150015 	char kdom[MAXHOSTNAMELEN];
285da6c28aaSamw 
286da6c28aaSamw 	bzero(&jdi, sizeof (jdi));
287da6c28aaSamw 
288da6c28aaSamw 	while ((option = getopt(argc, argv, "u:w:")) != -1) {
289da6c28aaSamw 		switch (option) {
290da6c28aaSamw 		case 'w':
291da6c28aaSamw 			(void) strlcpy(jdi.domain_name, optarg,
292da6c28aaSamw 			    sizeof (jdi.domain_name));
293da6c28aaSamw 			jdi.mode = SMB_SECMODE_WORKGRP;
294da6c28aaSamw 			join_w = B_TRUE;
295da6c28aaSamw 			break;
296da6c28aaSamw 
297da6c28aaSamw 		case 'u':
298da6c28aaSamw 			/* admin username */
299da6c28aaSamw 			(void) strlcpy(jdi.domain_username, optarg,
300da6c28aaSamw 			    sizeof (jdi.domain_username));
301da6c28aaSamw 			jdi.mode = SMB_SECMODE_DOMAIN;
302da6c28aaSamw 			join_d = B_TRUE;
303da6c28aaSamw 			break;
304da6c28aaSamw 
305da6c28aaSamw 		default:
306da6c28aaSamw 			smbadm_usage(B_FALSE);
307da6c28aaSamw 		}
308da6c28aaSamw 	}
309da6c28aaSamw 
310da6c28aaSamw 	if (join_w && join_d) {
311da6c28aaSamw 		(void) fprintf(stderr,
312da6c28aaSamw 		    gettext("domain and workgroup "
313da6c28aaSamw 		    "can not be specified together\n"));
314da6c28aaSamw 		smbadm_usage(B_FALSE);
315da6c28aaSamw 	}
316da6c28aaSamw 
317da6c28aaSamw 	if (join_d && (argv[optind] != NULL)) {
318da6c28aaSamw 		(void) strlcpy(jdi.domain_name, argv[optind],
319da6c28aaSamw 		    sizeof (jdi.domain_name));
320da6c28aaSamw 	}
321da6c28aaSamw 
322da6c28aaSamw 	if (*jdi.domain_name == '\0') {
323da6c28aaSamw 		(void) fprintf(stderr, gettext("missing %s name\n"),
324da6c28aaSamw 		    (join_d) ? "domain" : "workgroup");
325da6c28aaSamw 		smbadm_usage(B_FALSE);
326da6c28aaSamw 	}
327da6c28aaSamw 
328da6c28aaSamw 	if (join_d && *jdi.domain_username == '\0') {
329da6c28aaSamw 		(void) fprintf(stderr, gettext("missing username\n"));
330da6c28aaSamw 		smbadm_usage(B_FALSE);
331da6c28aaSamw 	}
332da6c28aaSamw 
333da6c28aaSamw 	if (join_w) {
334da6c28aaSamw 		status = smb_join(&jdi);
335da6c28aaSamw 		if (status == NT_STATUS_SUCCESS) {
336da6c28aaSamw 			(void) printf(
337da6c28aaSamw 			    gettext("Successfully joined workgroup '%s'\n"),
338da6c28aaSamw 			    jdi.domain_name);
339da6c28aaSamw 			return (0);
340da6c28aaSamw 		}
341da6c28aaSamw 
342da6c28aaSamw 		(void) fprintf(stderr,
343da6c28aaSamw 		    gettext("failed to join workgroup '%s' (%s)\n"),
344da6c28aaSamw 		    jdi.domain_name, xlate_nt_status(status));
345da6c28aaSamw 
346da6c28aaSamw 		return (1);
347da6c28aaSamw 	}
348da6c28aaSamw 
349*faa1795aSjb150015 	if ((smb_config_getstr(SMB_CI_KPASSWD_DOMAIN, kdom, sizeof (kdom))
350*faa1795aSjb150015 	    == SMBD_SMF_OK) && (*kdom != 0)) {
351*faa1795aSjb150015 		if (strncasecmp(jdi.domain_name, kdom,
352*faa1795aSjb150015 		    strlen(jdi.domain_name))) {
353*faa1795aSjb150015 			char reply[8];
354*faa1795aSjb150015 
355*faa1795aSjb150015 			(void) printf(gettext("The system has already "
356*faa1795aSjb150015 			    "joined to a different domain %s by another "
357*faa1795aSjb150015 			    "program.\nWould you like to continue [yes/no]? "),
358*faa1795aSjb150015 			    kdom);
359*faa1795aSjb150015 			(void) scanf("%8s", reply);
360*faa1795aSjb150015 			(void) trim_whitespace(reply);
361*faa1795aSjb150015 			if (strncasecmp(reply, "yes", 3) != 0)
362*faa1795aSjb150015 				return (0);
363*faa1795aSjb150015 		}
364*faa1795aSjb150015 	}
365*faa1795aSjb150015 
366da6c28aaSamw 	/* Join the domain */
367da6c28aaSamw 	if (*jdi.domain_passwd == '\0') {
368da6c28aaSamw 		char *p = NULL;
369da6c28aaSamw 		char *prompt = gettext("Enter domain password: ");
370da6c28aaSamw 		p = getpassphrase(prompt);
371da6c28aaSamw 		if (!p) {
372da6c28aaSamw 			(void) fprintf(stderr, gettext("missing password\n"));
373da6c28aaSamw 			smbadm_usage(B_FALSE);
374da6c28aaSamw 		}
375da6c28aaSamw 
376da6c28aaSamw 		(void) strlcpy(jdi.domain_passwd, p,
377da6c28aaSamw 		    sizeof (jdi.domain_passwd));
378da6c28aaSamw 	}
379da6c28aaSamw 
380da6c28aaSamw 	(void) printf(gettext("Joining '%s' ... this may take a minute ...\n"),
381da6c28aaSamw 	    jdi.domain_name);
382da6c28aaSamw 
383da6c28aaSamw 	status = smb_join(&jdi);
384da6c28aaSamw 
385da6c28aaSamw 	switch (status) {
386da6c28aaSamw 	case NT_STATUS_SUCCESS:
387da6c28aaSamw 		(void) printf(gettext("Successfully joined domain '%s'\n"),
388da6c28aaSamw 		    jdi.domain_name);
389da6c28aaSamw 		return (0);
390da6c28aaSamw 
391da6c28aaSamw 	case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
392da6c28aaSamw 		(void) fprintf(stderr, gettext("failed to find "
393da6c28aaSamw 		    "any domain controllers for '%s'\n"),
394da6c28aaSamw 		    jdi.domain_name);
395da6c28aaSamw 		break;
396da6c28aaSamw 
397da6c28aaSamw 	default:
398da6c28aaSamw 		(void) fprintf(stderr,
399da6c28aaSamw 		    gettext("failed to join domain '%s' (%s)\n"),
400da6c28aaSamw 		    jdi.domain_name, xlate_nt_status(status));
401da6c28aaSamw 	}
402da6c28aaSamw 
403da6c28aaSamw 	return (1);
404da6c28aaSamw }
405da6c28aaSamw 
406da6c28aaSamw /*
407da6c28aaSamw  * smbadm_list
408da6c28aaSamw  *
409da6c28aaSamw  * Displays current security mode and domain/workgroup name.
410da6c28aaSamw  */
411da6c28aaSamw /*ARGSUSED*/
412da6c28aaSamw static int
413da6c28aaSamw smbadm_list(int argc, char **argv)
414da6c28aaSamw {
415*faa1795aSjb150015 	char domain[MAXHOSTNAMELEN];
416*faa1795aSjb150015 	char modename[16];
417*faa1795aSjb150015 	int rc;
418da6c28aaSamw 
419*faa1795aSjb150015 	rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename));
420*faa1795aSjb150015 	if (rc != SMBD_SMF_OK) {
421da6c28aaSamw 		(void) fprintf(stderr,
422da6c28aaSamw 		    gettext("failed to get the security mode\n"));
423da6c28aaSamw 		return (1);
424da6c28aaSamw 	}
425da6c28aaSamw 
426*faa1795aSjb150015 	(void) printf(gettext("security mode: %s\n"), modename);
427da6c28aaSamw 
428*faa1795aSjb150015 	if (smb_getdomainname(domain, sizeof (domain)) != 0) {
429*faa1795aSjb150015 		(void) fprintf(stderr, gettext("failed to get the %s name\n"),
430*faa1795aSjb150015 		    modename);
431da6c28aaSamw 		return (1);
432da6c28aaSamw 	}
433da6c28aaSamw 
434*faa1795aSjb150015 	(void) printf(gettext("%s name: %s\n"), modename, domain);
435da6c28aaSamw 	return (0);
436da6c28aaSamw }
437da6c28aaSamw 
438da6c28aaSamw /*
439da6c28aaSamw  * smbadm_group_create
440da6c28aaSamw  *
441da6c28aaSamw  * Creates a local SMB group
442da6c28aaSamw  */
443da6c28aaSamw static int
444da6c28aaSamw smbadm_group_create(int argc, char **argv)
445da6c28aaSamw {
446da6c28aaSamw 	char *gname = NULL;
447da6c28aaSamw 	char *desc = NULL;
448da6c28aaSamw 	char option;
449dc20a302Sas200622 	int status;
450da6c28aaSamw 
451da6c28aaSamw 	while ((option = getopt(argc, argv, "d:")) != -1) {
452da6c28aaSamw 		switch (option) {
453da6c28aaSamw 		case 'd':
454da6c28aaSamw 			desc = optarg;
455da6c28aaSamw 			break;
456da6c28aaSamw 
457da6c28aaSamw 		default:
458da6c28aaSamw 			smbadm_usage(B_FALSE);
459da6c28aaSamw 		}
460da6c28aaSamw 	}
461da6c28aaSamw 
462da6c28aaSamw 	gname = argv[optind];
463da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0') {
464da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
465da6c28aaSamw 		smbadm_usage(B_FALSE);
466da6c28aaSamw 	}
467da6c28aaSamw 
468da6c28aaSamw 	if (getgrnam(gname) == NULL) {
469da6c28aaSamw 		(void) fprintf(stderr,
470dc20a302Sas200622 		    gettext("failed to get the Solaris group '%s'\n"), gname);
471da6c28aaSamw 		(void) fprintf(stderr,
472dc20a302Sas200622 		    gettext("use 'groupadd' to add '%s'\n"), gname);
473da6c28aaSamw 		return (1);
474da6c28aaSamw 	}
475da6c28aaSamw 
476dc20a302Sas200622 	status = smb_lgrp_add(gname, desc);
477dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
478da6c28aaSamw 		(void) fprintf(stderr,
479da6c28aaSamw 		    gettext("failed to create the group (%s)\n"),
480dc20a302Sas200622 		    smb_lgrp_strerror(status));
481da6c28aaSamw 	} else {
482dc20a302Sas200622 		(void) printf(gettext("'%s' created.\n"),
483da6c28aaSamw 		    gname);
484da6c28aaSamw 	}
485da6c28aaSamw 
486da6c28aaSamw 	return (status);
487da6c28aaSamw }
488da6c28aaSamw 
489da6c28aaSamw /*
490da6c28aaSamw  * smbadm_group_dump_members
491da6c28aaSamw  *
492da6c28aaSamw  * Dump group members details.
493da6c28aaSamw  */
494da6c28aaSamw static void
495dc20a302Sas200622 smbadm_group_dump_members(smb_gsid_t *members, int num)
496da6c28aaSamw {
497dc20a302Sas200622 	char sidstr[NT_SID_FMTBUF_SIZE];
498da6c28aaSamw 	int i;
499da6c28aaSamw 
500dc20a302Sas200622 	if (num == 0) {
501da6c28aaSamw 		(void) printf(gettext("\tNo members\n"));
502da6c28aaSamw 		return;
503da6c28aaSamw 	}
504da6c28aaSamw 
505da6c28aaSamw 	(void) printf(gettext("\tMembers:\n"));
506dc20a302Sas200622 	for (i = 0; i < num; i++) {
507dc20a302Sas200622 		(void) smb_lookup_sid(members[i].gs_sid, sidstr,
508dc20a302Sas200622 		    sizeof (sidstr));
509dc20a302Sas200622 		(void) printf(gettext("\t\t%s\n"), sidstr);
510da6c28aaSamw 	}
511da6c28aaSamw }
512da6c28aaSamw 
513da6c28aaSamw /*
514da6c28aaSamw  * smbadm_group_dump_privs
515da6c28aaSamw  *
516da6c28aaSamw  * Dump group privilege details.
517da6c28aaSamw  */
518da6c28aaSamw static void
519dc20a302Sas200622 smbadm_group_dump_privs(smb_privset_t *privs)
520da6c28aaSamw {
521dc20a302Sas200622 	smb_privinfo_t *pinfo;
522dc20a302Sas200622 	char *pstatus;
523da6c28aaSamw 	int i;
524da6c28aaSamw 
525da6c28aaSamw 	(void) printf(gettext("\tPrivileges: \n"));
526da6c28aaSamw 
527dc20a302Sas200622 	for (i = 0; i < privs->priv_cnt; i++) {
528dc20a302Sas200622 		pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part);
529dc20a302Sas200622 		if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0)
530da6c28aaSamw 			continue;
531da6c28aaSamw 
532dc20a302Sas200622 		switch (privs->priv[i].attrs) {
533dc20a302Sas200622 		case SE_PRIVILEGE_ENABLED:
534dc20a302Sas200622 			pstatus = "On";
535dc20a302Sas200622 			break;
536dc20a302Sas200622 		case SE_PRIVILEGE_DISABLED:
537dc20a302Sas200622 			pstatus = "Off";
538dc20a302Sas200622 			break;
539dc20a302Sas200622 		default:
540dc20a302Sas200622 			pstatus = "Unknown";
541dc20a302Sas200622 			break;
542dc20a302Sas200622 		}
543dc20a302Sas200622 		(void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus);
544da6c28aaSamw 	}
545da6c28aaSamw 
546dc20a302Sas200622 	if (privs->priv_cnt == 0)
547da6c28aaSamw 		(void) printf(gettext("\t\tNo privileges\n"));
548da6c28aaSamw }
549da6c28aaSamw 
550da6c28aaSamw /*
551da6c28aaSamw  * smbadm_group_dump
552da6c28aaSamw  *
553da6c28aaSamw  * Dump group details.
554da6c28aaSamw  */
555dc20a302Sas200622 static void
556dc20a302Sas200622 smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
557da6c28aaSamw {
558dc20a302Sas200622 	char sidstr[NT_SID_FMTBUF_SIZE];
559da6c28aaSamw 
560dc20a302Sas200622 	(void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);
561da6c28aaSamw 
562dc20a302Sas200622 	nt_sid_format2(grp->sg_id.gs_sid, sidstr);
563dc20a302Sas200622 	(void) printf(gettext("\tSID: %s\n"), sidstr);
564da6c28aaSamw 
565da6c28aaSamw 	if (show_privs)
566dc20a302Sas200622 		smbadm_group_dump_privs(grp->sg_privs);
567da6c28aaSamw 
568da6c28aaSamw 	if (show_mem)
569dc20a302Sas200622 		smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers);
570da6c28aaSamw }
571da6c28aaSamw 
572da6c28aaSamw /*
573da6c28aaSamw  * smbadm_group_show
574da6c28aaSamw  *
575da6c28aaSamw  */
576da6c28aaSamw static int
577da6c28aaSamw smbadm_group_show(int argc, char **argv)
578da6c28aaSamw {
579da6c28aaSamw 	char *gname = NULL;
580da6c28aaSamw 	boolean_t show_privs;
581da6c28aaSamw 	boolean_t show_members;
582da6c28aaSamw 	char option;
583dc20a302Sas200622 	int status;
584dc20a302Sas200622 	smb_group_t grp;
585dc20a302Sas200622 	smb_giter_t gi;
586da6c28aaSamw 
587da6c28aaSamw 	show_privs = show_members = B_FALSE;
588da6c28aaSamw 
589da6c28aaSamw 	while ((option = getopt(argc, argv, "mp")) != -1) {
590da6c28aaSamw 		switch (option) {
591da6c28aaSamw 		case 'm':
592da6c28aaSamw 			show_members = B_TRUE;
593da6c28aaSamw 			break;
594da6c28aaSamw 		case 'p':
595da6c28aaSamw 			show_privs = B_TRUE;
596da6c28aaSamw 			break;
597da6c28aaSamw 
598da6c28aaSamw 		default:
599da6c28aaSamw 			smbadm_usage(B_FALSE);
600da6c28aaSamw 		}
601da6c28aaSamw 	}
602da6c28aaSamw 
603da6c28aaSamw 	gname = argv[optind];
604da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0')
605da6c28aaSamw 		gname = "*";
606da6c28aaSamw 
607dc20a302Sas200622 	if (strcmp(gname, "*")) {
608dc20a302Sas200622 		status = smb_lgrp_getbyname(gname, &grp);
609dc20a302Sas200622 		if (status == SMB_LGRP_SUCCESS) {
610dc20a302Sas200622 			smbadm_group_dump(&grp, show_members, show_privs);
611dc20a302Sas200622 			smb_lgrp_free(&grp);
612dc20a302Sas200622 		} else {
613da6c28aaSamw 			(void) fprintf(stderr,
614dc20a302Sas200622 			    gettext("failed to find '%s' (%s)\n"),
615dc20a302Sas200622 			    gname, smb_lgrp_strerror(status));
616dc20a302Sas200622 		}
617dc20a302Sas200622 		return (status);
618da6c28aaSamw 	}
619da6c28aaSamw 
620dc20a302Sas200622 	status = smb_lgrp_iteropen(&gi);
621dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
622da6c28aaSamw 		(void) fprintf(stderr,
623dc20a302Sas200622 		    gettext("failed to list groups (%s)\n"),
624dc20a302Sas200622 		    smb_lgrp_strerror(status));
625dc20a302Sas200622 		return (status);
626da6c28aaSamw 	}
627da6c28aaSamw 
628dc20a302Sas200622 	while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
629dc20a302Sas200622 		smbadm_group_dump(&grp, show_members, show_privs);
630dc20a302Sas200622 		smb_lgrp_free(&grp);
631da6c28aaSamw 	}
632dc20a302Sas200622 	smb_lgrp_iterclose(&gi);
633da6c28aaSamw 
634dc20a302Sas200622 	return (0);
635da6c28aaSamw }
636da6c28aaSamw 
637da6c28aaSamw /*
638da6c28aaSamw  * smbadm_group_delete
639da6c28aaSamw  */
640da6c28aaSamw static int
641da6c28aaSamw smbadm_group_delete(int argc, char **argv)
642da6c28aaSamw {
643da6c28aaSamw 	char *gname = NULL;
644dc20a302Sas200622 	int status;
645da6c28aaSamw 
646da6c28aaSamw 	gname = argv[optind];
647da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0') {
648da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
649da6c28aaSamw 		smbadm_usage(B_FALSE);
650da6c28aaSamw 	}
651da6c28aaSamw 
652dc20a302Sas200622 	status = smb_lgrp_delete(gname);
653dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
654da6c28aaSamw 		(void) fprintf(stderr,
655da6c28aaSamw 		    gettext("failed to delete the group (%s)\n"),
656dc20a302Sas200622 		    smb_lgrp_strerror(status));
657da6c28aaSamw 	} else {
658dc20a302Sas200622 		(void) printf(gettext("'%s' deleted.\n"),
659da6c28aaSamw 		    gname);
660da6c28aaSamw 	}
661da6c28aaSamw 
662da6c28aaSamw 	return (status);
663da6c28aaSamw }
664da6c28aaSamw 
665da6c28aaSamw /*
666da6c28aaSamw  * smbadm_group_rename
667da6c28aaSamw  */
668da6c28aaSamw static int
669da6c28aaSamw smbadm_group_rename(int argc, char **argv)
670da6c28aaSamw {
671da6c28aaSamw 	char *gname = NULL;
672da6c28aaSamw 	char *ngname = NULL;
673dc20a302Sas200622 	int status;
674da6c28aaSamw 
675da6c28aaSamw 	gname = argv[optind];
676da6c28aaSamw 	if (optind++ >= argc || gname == NULL || *gname == '\0') {
677da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
678da6c28aaSamw 		smbadm_usage(B_FALSE);
679da6c28aaSamw 	}
680da6c28aaSamw 
681da6c28aaSamw 	ngname = argv[optind];
682da6c28aaSamw 	if (optind >= argc || ngname == NULL || *ngname == '\0') {
683da6c28aaSamw 		(void) fprintf(stderr, gettext("missing new group name\n"));
684da6c28aaSamw 		smbadm_usage(B_FALSE);
685da6c28aaSamw 	}
686da6c28aaSamw 
687dc20a302Sas200622 	if (getgrnam(ngname) == NULL) {
688da6c28aaSamw 		(void) fprintf(stderr,
689dc20a302Sas200622 		    gettext("failed to get the Solaris group '%s'\n"), ngname);
690da6c28aaSamw 		(void) fprintf(stderr,
691dc20a302Sas200622 		    gettext("use 'groupadd' to add '%s'\n"), ngname);
692da6c28aaSamw 		return (1);
693da6c28aaSamw 	}
694da6c28aaSamw 
695dc20a302Sas200622 	status = smb_lgrp_rename(gname, ngname);
696dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
697dc20a302Sas200622 		if (status == SMB_LGRP_EXISTS)
698da6c28aaSamw 			(void) fprintf(stderr,
699dc20a302Sas200622 			    gettext("failed to rename '%s' (%s already "
700dc20a302Sas200622 			    "exists)\n"), gname, ngname);
701dc20a302Sas200622 		else
702dc20a302Sas200622 			(void) fprintf(stderr,
703dc20a302Sas200622 			    gettext("failed to rename '%s' (%s)\n"), gname,
704dc20a302Sas200622 			    smb_lgrp_strerror(status));
705da6c28aaSamw 	} else {
706dc20a302Sas200622 		(void) printf(gettext("'%s' renamed to '%s'\n"), gname, ngname);
707da6c28aaSamw 	}
708da6c28aaSamw 
709da6c28aaSamw 	return (status);
710da6c28aaSamw }
711da6c28aaSamw 
712da6c28aaSamw /*
713da6c28aaSamw  * smbadm_group_setprop
714da6c28aaSamw  *
715da6c28aaSamw  * Set the group properties.
716da6c28aaSamw  */
717da6c28aaSamw static int
718da6c28aaSamw smbadm_group_setprop(int argc, char **argv)
719da6c28aaSamw {
720da6c28aaSamw 	char *gname = NULL;
721da6c28aaSamw 	smbadm_prop_t props[SMBADM_NPROP];
722da6c28aaSamw 	smbadm_prop_handle_t *phandle;
723da6c28aaSamw 	char option;
724da6c28aaSamw 	int pcnt = 0;
725da6c28aaSamw 	int ret;
726da6c28aaSamw 	int p;
727da6c28aaSamw 
728da6c28aaSamw 	bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t));
729da6c28aaSamw 
730da6c28aaSamw 	while ((option = getopt(argc, argv, "p:")) != -1) {
731da6c28aaSamw 		switch (option) {
732da6c28aaSamw 		case 'p':
733da6c28aaSamw 			if (pcnt >= SMBADM_NPROP) {
734da6c28aaSamw 				(void) fprintf(stderr,
735da6c28aaSamw 				    gettext("exceeded number of supported"
736da6c28aaSamw 				    " properties\n"));
737da6c28aaSamw 				smbadm_usage(B_FALSE);
738da6c28aaSamw 			}
739da6c28aaSamw 
740dc20a302Sas200622 			if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
741da6c28aaSamw 				smbadm_usage(B_FALSE);
742da6c28aaSamw 			break;
743da6c28aaSamw 
744da6c28aaSamw 		default:
745da6c28aaSamw 			smbadm_usage(B_FALSE);
746da6c28aaSamw 		}
747da6c28aaSamw 	}
748da6c28aaSamw 
749da6c28aaSamw 	if (pcnt == 0) {
750da6c28aaSamw 		(void) fprintf(stderr,
751da6c28aaSamw 		    gettext("missing property=value argument\n"));
752da6c28aaSamw 		smbadm_usage(B_FALSE);
753da6c28aaSamw 	}
754da6c28aaSamw 
755da6c28aaSamw 	gname = argv[optind];
756da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0') {
757da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
758da6c28aaSamw 		smbadm_usage(B_FALSE);
759da6c28aaSamw 	}
760da6c28aaSamw 
761da6c28aaSamw 	for (p = 0; p < pcnt; p++) {
762da6c28aaSamw 		phandle = smbadm_prop_gethandle(props[p].p_name);
763da6c28aaSamw 		if (phandle) {
764da6c28aaSamw 			if (phandle->p_setfn(gname, &props[p]) != 0)
765da6c28aaSamw 				ret = 1;
766da6c28aaSamw 		}
767da6c28aaSamw 	}
768da6c28aaSamw 
769da6c28aaSamw 	return (ret);
770da6c28aaSamw }
771da6c28aaSamw 
772da6c28aaSamw /*
773da6c28aaSamw  * smbadm_group_getprop
774da6c28aaSamw  *
775da6c28aaSamw  * Get the group properties.
776da6c28aaSamw  */
777da6c28aaSamw static int
778da6c28aaSamw smbadm_group_getprop(int argc, char **argv)
779da6c28aaSamw {
780da6c28aaSamw 	char *gname = NULL;
781da6c28aaSamw 	smbadm_prop_t props[SMBADM_NPROP];
782da6c28aaSamw 	smbadm_prop_handle_t *phandle;
783da6c28aaSamw 	char option;
784da6c28aaSamw 	int pcnt = 0;
785da6c28aaSamw 	int ret;
786da6c28aaSamw 	int p;
787da6c28aaSamw 
788da6c28aaSamw 	bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t));
789da6c28aaSamw 
790da6c28aaSamw 	while ((option = getopt(argc, argv, "p:")) != -1) {
791da6c28aaSamw 		switch (option) {
792da6c28aaSamw 		case 'p':
793da6c28aaSamw 			if (pcnt >= SMBADM_NPROP) {
794da6c28aaSamw 				(void) fprintf(stderr,
795da6c28aaSamw 				    gettext("exceeded number of supported"
796da6c28aaSamw 				    " properties\n"));
797da6c28aaSamw 				smbadm_usage(B_FALSE);
798da6c28aaSamw 			}
799da6c28aaSamw 
800dc20a302Sas200622 			if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
801da6c28aaSamw 				smbadm_usage(B_FALSE);
802da6c28aaSamw 			break;
803da6c28aaSamw 
804da6c28aaSamw 		default:
805da6c28aaSamw 			smbadm_usage(B_FALSE);
806da6c28aaSamw 		}
807da6c28aaSamw 	}
808da6c28aaSamw 
809da6c28aaSamw 	gname = argv[optind];
810da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0') {
811da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
812da6c28aaSamw 		smbadm_usage(B_FALSE);
813da6c28aaSamw 	}
814da6c28aaSamw 
815da6c28aaSamw 	if (pcnt == 0) {
816da6c28aaSamw 		/*
817da6c28aaSamw 		 * If no property has be specified then get
818da6c28aaSamw 		 * all the properties.
819da6c28aaSamw 		 */
820da6c28aaSamw 		pcnt = SMBADM_NPROP;
821da6c28aaSamw 		for (p = 0; p < pcnt; p++)
822da6c28aaSamw 			props[p].p_name = smbadm_ptable[p].p_name;
823da6c28aaSamw 	}
824da6c28aaSamw 
825da6c28aaSamw 	for (p = 0; p < pcnt; p++) {
826da6c28aaSamw 		phandle = smbadm_prop_gethandle(props[p].p_name);
827da6c28aaSamw 		if (phandle) {
828da6c28aaSamw 			if (phandle->p_getfn(gname, &props[p]) != 0)
829da6c28aaSamw 				ret = 1;
830da6c28aaSamw 		}
831da6c28aaSamw 	}
832da6c28aaSamw 
833da6c28aaSamw 	return (ret);
834da6c28aaSamw }
835da6c28aaSamw 
836da6c28aaSamw /*
837da6c28aaSamw  * smbadm_group_addmember
838da6c28aaSamw  *
839da6c28aaSamw  */
840da6c28aaSamw static int
841da6c28aaSamw smbadm_group_addmember(int argc, char **argv)
842da6c28aaSamw {
843da6c28aaSamw 	char *gname = NULL;
844da6c28aaSamw 	char **mname;
845da6c28aaSamw 	char option;
846dc20a302Sas200622 	smb_gsid_t msid;
847dc20a302Sas200622 	int status;
848da6c28aaSamw 	int mcnt = 0;
849da6c28aaSamw 	int ret = 0;
850da6c28aaSamw 	int i;
851da6c28aaSamw 
852da6c28aaSamw 
853da6c28aaSamw 	mname = (char **)malloc(argc * sizeof (char *));
854da6c28aaSamw 	if (mname == NULL) {
855da6c28aaSamw 		(void) fprintf(stderr, gettext("out of memory\n"));
856da6c28aaSamw 		return (1);
857da6c28aaSamw 	}
858da6c28aaSamw 	bzero(mname, argc * sizeof (char *));
859da6c28aaSamw 
860da6c28aaSamw 	while ((option = getopt(argc, argv, "m:")) != -1) {
861da6c28aaSamw 		switch (option) {
862da6c28aaSamw 		case 'm':
863da6c28aaSamw 			mname[mcnt++] = optarg;
864da6c28aaSamw 			break;
865da6c28aaSamw 
866da6c28aaSamw 		default:
867da6c28aaSamw 			free(mname);
868da6c28aaSamw 			smbadm_usage(B_FALSE);
869da6c28aaSamw 		}
870da6c28aaSamw 	}
871da6c28aaSamw 
872da6c28aaSamw 	if (mcnt == 0) {
873da6c28aaSamw 		(void) fprintf(stderr, gettext("missing member name\n"));
874da6c28aaSamw 		free(mname);
875da6c28aaSamw 		smbadm_usage(B_FALSE);
876da6c28aaSamw 	}
877da6c28aaSamw 
878da6c28aaSamw 	gname = argv[optind];
879da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == 0) {
880da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
881da6c28aaSamw 		free(mname);
882da6c28aaSamw 		smbadm_usage(B_FALSE);
883da6c28aaSamw 	}
884da6c28aaSamw 
885da6c28aaSamw 
886da6c28aaSamw 	for (i = 0; i < mcnt; i++) {
887da6c28aaSamw 		if (mname[i] == NULL)
888da6c28aaSamw 			continue;
889da6c28aaSamw 
890dc20a302Sas200622 		if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
891dc20a302Sas200622 			(void) fprintf(stderr,
892dc20a302Sas200622 			    gettext("failed to add %s "
893dc20a302Sas200622 			    "(could not obtain the SID)\n"),
894dc20a302Sas200622 			    mname[i]);
895dc20a302Sas200622 			continue;
896dc20a302Sas200622 		}
897dc20a302Sas200622 
898dc20a302Sas200622 		status = smb_lgrp_add_member(gname, msid.gs_sid, msid.gs_type);
899dc20a302Sas200622 		free(msid.gs_sid);
900dc20a302Sas200622 		if (status != SMB_LGRP_SUCCESS) {
901da6c28aaSamw 			(void) fprintf(stderr,
902da6c28aaSamw 			    gettext("failed to add %s (%s)\n"),
903dc20a302Sas200622 			    mname[i], smb_lgrp_strerror(status));
904da6c28aaSamw 			ret = 1;
905dc20a302Sas200622 		} else {
906dc20a302Sas200622 			(void) printf(gettext("'%s' is now a member of '%s'\n"),
907da6c28aaSamw 			    mname[i], gname);
908da6c28aaSamw 		}
909dc20a302Sas200622 	}
910da6c28aaSamw 
911da6c28aaSamw 	free(mname);
912da6c28aaSamw 	return (ret);
913da6c28aaSamw }
914da6c28aaSamw 
915da6c28aaSamw /*
916da6c28aaSamw  * smbadm_group_delmember
917da6c28aaSamw  */
918da6c28aaSamw static int
919da6c28aaSamw smbadm_group_delmember(int argc, char **argv)
920da6c28aaSamw {
921da6c28aaSamw 	char *gname = NULL;
922da6c28aaSamw 	char **mname;
923da6c28aaSamw 	char option;
924dc20a302Sas200622 	smb_gsid_t msid;
925dc20a302Sas200622 	int status;
926da6c28aaSamw 	int mcnt = 0;
927da6c28aaSamw 	int ret = 0;
928da6c28aaSamw 	int i;
929da6c28aaSamw 
930da6c28aaSamw 	mname = (char **)malloc(argc * sizeof (char *));
931da6c28aaSamw 	if (mname == NULL) {
932da6c28aaSamw 		(void) fprintf(stderr, gettext("out of memory\n"));
933da6c28aaSamw 		return (1);
934da6c28aaSamw 	}
935da6c28aaSamw 	bzero(mname, argc * sizeof (char *));
936da6c28aaSamw 
937da6c28aaSamw 	while ((option = getopt(argc, argv, "m:")) != -1) {
938da6c28aaSamw 		switch (option) {
939da6c28aaSamw 		case 'm':
940da6c28aaSamw 			mname[mcnt++] = optarg;
941da6c28aaSamw 			break;
942da6c28aaSamw 
943da6c28aaSamw 		default:
944da6c28aaSamw 			free(mname);
945da6c28aaSamw 			smbadm_usage(B_FALSE);
946da6c28aaSamw 		}
947da6c28aaSamw 	}
948da6c28aaSamw 
949da6c28aaSamw 	if (mcnt == 0) {
950da6c28aaSamw 		(void) fprintf(stderr, gettext("missing member name\n"));
951da6c28aaSamw 		free(mname);
952da6c28aaSamw 		smbadm_usage(B_FALSE);
953da6c28aaSamw 	}
954da6c28aaSamw 
955da6c28aaSamw 	gname = argv[optind];
956da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == 0) {
957da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
958da6c28aaSamw 		free(mname);
959da6c28aaSamw 		smbadm_usage(B_FALSE);
960da6c28aaSamw 	}
961da6c28aaSamw 
962da6c28aaSamw 
963da6c28aaSamw 	for (i = 0; i < mcnt; i++) {
964da6c28aaSamw 		if (mname[i] == NULL)
965da6c28aaSamw 			continue;
966da6c28aaSamw 
967dc20a302Sas200622 		if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
968dc20a302Sas200622 			(void) fprintf(stderr,
969dc20a302Sas200622 			    gettext("failed to remove %s "
970dc20a302Sas200622 			    "(could not obtain the SID)\n"),
971dc20a302Sas200622 			    mname[i]);
972dc20a302Sas200622 			continue;
973dc20a302Sas200622 		}
974dc20a302Sas200622 
975dc20a302Sas200622 		status = smb_lgrp_del_member(gname, msid.gs_sid, msid.gs_type);
976dc20a302Sas200622 		free(msid.gs_sid);
977dc20a302Sas200622 		if (status != SMB_LGRP_SUCCESS) {
978da6c28aaSamw 			(void) fprintf(stderr,
979da6c28aaSamw 			    gettext("failed to remove %s (%s)\n"),
980dc20a302Sas200622 			    mname[i], smb_lgrp_strerror(status));
981da6c28aaSamw 			ret = 1;
982da6c28aaSamw 		} else {
983da6c28aaSamw 			(void) printf(
984dc20a302Sas200622 			    gettext("'%s' has been removed from %s\n"),
985da6c28aaSamw 			    mname[i], gname);
986da6c28aaSamw 		}
987da6c28aaSamw 	}
988da6c28aaSamw 
989da6c28aaSamw 	return (ret);
990da6c28aaSamw }
991da6c28aaSamw 
992da6c28aaSamw static int
993da6c28aaSamw smbadm_user_disable(int argc, char **argv)
994da6c28aaSamw {
995da6c28aaSamw 	int error;
996da6c28aaSamw 	char *user = NULL;
997da6c28aaSamw 
998da6c28aaSamw 	user = argv[optind];
999da6c28aaSamw 	if (optind >= argc || user == NULL || *user == '\0') {
1000da6c28aaSamw 		(void) fprintf(stderr, gettext("missing user name\n"));
1001da6c28aaSamw 		smbadm_usage(B_FALSE);
1002da6c28aaSamw 	}
1003da6c28aaSamw 
1004da6c28aaSamw 	error = smb_pwd_setcntl(user, SMB_PWC_DISABLE);
1005da6c28aaSamw 	if (error == SMB_PWE_SUCCESS)
1006da6c28aaSamw 		(void) printf(gettext("%s is disabled.\n"), user);
1007da6c28aaSamw 	else
1008da6c28aaSamw 		(void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1009da6c28aaSamw 
1010da6c28aaSamw 	return (error);
1011da6c28aaSamw }
1012da6c28aaSamw 
1013da6c28aaSamw static int
1014da6c28aaSamw smbadm_user_enable(int argc, char **argv)
1015da6c28aaSamw {
1016da6c28aaSamw 	int error;
1017da6c28aaSamw 	char *user = NULL;
1018da6c28aaSamw 
1019da6c28aaSamw 	user = argv[optind];
1020da6c28aaSamw 	if (optind >= argc || user == NULL || *user == '\0') {
1021da6c28aaSamw 		(void) fprintf(stderr, gettext("missing user name\n"));
1022da6c28aaSamw 		smbadm_usage(B_FALSE);
1023da6c28aaSamw 	}
1024da6c28aaSamw 
1025da6c28aaSamw 	error = smb_pwd_setcntl(user, SMB_PWC_ENABLE);
1026da6c28aaSamw 	if (error == SMB_PWE_SUCCESS)
1027da6c28aaSamw 		(void) printf(gettext("%s is enabled.\n"), user);
1028da6c28aaSamw 	else
1029da6c28aaSamw 		(void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1030da6c28aaSamw 
1031da6c28aaSamw 	return (error);
1032da6c28aaSamw }
1033da6c28aaSamw 
1034da6c28aaSamw 
1035da6c28aaSamw int
1036da6c28aaSamw main(int argc, char **argv)
1037da6c28aaSamw {
1038dc20a302Sas200622 	int ret;
1039da6c28aaSamw 	int i;
1040da6c28aaSamw 
1041da6c28aaSamw 	(void) malloc(0);	/* satisfy libumem dependency */
1042da6c28aaSamw 
1043da6c28aaSamw 	progname = basename(argv[0]);
1044da6c28aaSamw 
1045da6c28aaSamw 	if (getzoneid() != GLOBAL_ZONEID) {
1046da6c28aaSamw 		(void) fprintf(stderr,
1047da6c28aaSamw 		    gettext("cannot execute in non-global zone\n"));
1048da6c28aaSamw 		return (0);
1049da6c28aaSamw 	}
1050da6c28aaSamw 
1051da6c28aaSamw 	if (is_system_labeled()) {
1052da6c28aaSamw 		(void) fprintf(stderr,
1053da6c28aaSamw 		    gettext("Trusted Extensions not supported\n"));
1054da6c28aaSamw 		return (0);
1055da6c28aaSamw 	}
1056da6c28aaSamw 
1057da6c28aaSamw 	if (argc < 2) {
1058da6c28aaSamw 		(void) fprintf(stderr, gettext("missing command\n"));
1059da6c28aaSamw 		smbadm_usage(B_FALSE);
1060da6c28aaSamw 	}
1061da6c28aaSamw 
1062da6c28aaSamw 	/*
1063da6c28aaSamw 	 * Special case "cmd --help/-?"
1064da6c28aaSamw 	 */
1065da6c28aaSamw 	if (strcmp(argv[1], "-?") == 0 ||
1066da6c28aaSamw 	    strcmp(argv[1], "--help") == 0 ||
1067da6c28aaSamw 	    strcmp(argv[1], "-h") == 0)
1068da6c28aaSamw 		smbadm_usage(B_TRUE);
1069da6c28aaSamw 
1070da6c28aaSamw 	for (i = 0; i < SMBADM_NCMD; ++i) {
1071da6c28aaSamw 		curcmd = &smbadm_cmdtable[i];
1072da6c28aaSamw 		if (strcasecmp(argv[1], curcmd->name) == 0) {
1073da6c28aaSamw 			if (argc > 2) {
1074da6c28aaSamw 				/* cmd subcmd --help/-? */
1075da6c28aaSamw 				if (strcmp(argv[2], "-?") == 0 ||
1076da6c28aaSamw 				    strcmp(argv[2], "--help") == 0 ||
1077da6c28aaSamw 				    strcmp(argv[2], "-h") == 0)
1078da6c28aaSamw 					smbadm_usage(B_TRUE);
1079da6c28aaSamw 			}
1080da6c28aaSamw 
1081*faa1795aSjb150015 			if ((ret = smbadm_grpcmd_init()) != 0)
1082*faa1795aSjb150015 				return (ret);
1083dc20a302Sas200622 
1084dc20a302Sas200622 			ret = curcmd->func(argc - 1, &argv[1]);
1085*faa1795aSjb150015 
1086*faa1795aSjb150015 			smbadm_grpcmd_fini();
1087dc20a302Sas200622 			return (ret);
1088da6c28aaSamw 		}
1089da6c28aaSamw 	}
1090da6c28aaSamw 
1091da6c28aaSamw 	curcmd = NULL;
1092da6c28aaSamw 	(void) fprintf(stderr, gettext("unknown subcommand (%s)\n"), argv[1]);
1093da6c28aaSamw 	smbadm_usage(B_FALSE);
1094da6c28aaSamw 	return (2);
1095da6c28aaSamw }
1096da6c28aaSamw 
1097*faa1795aSjb150015 static int
1098*faa1795aSjb150015 smbadm_grpcmd_init(void)
1099*faa1795aSjb150015 {
1100*faa1795aSjb150015 	int rc;
1101*faa1795aSjb150015 
1102*faa1795aSjb150015 	if (curcmd->flags & SMBADM_CMDF_GROUP) {
1103*faa1795aSjb150015 		if (smb_idmap_start() != 0) {
1104*faa1795aSjb150015 			(void) fprintf(stderr,
1105*faa1795aSjb150015 			    gettext("failed to contact idmap service\n"));
1106*faa1795aSjb150015 			return (1);
1107*faa1795aSjb150015 		}
1108*faa1795aSjb150015 
1109*faa1795aSjb150015 		if ((rc = smb_lgrp_start()) != SMB_LGRP_SUCCESS) {
1110*faa1795aSjb150015 			(void) fprintf(stderr,
1111*faa1795aSjb150015 			    gettext("failed to initialize (%s)\n"),
1112*faa1795aSjb150015 			    smb_lgrp_strerror(rc));
1113*faa1795aSjb150015 			smb_idmap_stop();
1114*faa1795aSjb150015 			return (1);
1115*faa1795aSjb150015 		}
1116*faa1795aSjb150015 	}
1117*faa1795aSjb150015 
1118*faa1795aSjb150015 	return (0);
1119*faa1795aSjb150015 }
1120*faa1795aSjb150015 
1121*faa1795aSjb150015 static void
1122*faa1795aSjb150015 smbadm_grpcmd_fini(void)
1123*faa1795aSjb150015 {
1124*faa1795aSjb150015 	if (curcmd->flags & SMBADM_CMDF_GROUP) {
1125*faa1795aSjb150015 		smb_lgrp_stop();
1126*faa1795aSjb150015 		smb_idmap_stop();
1127*faa1795aSjb150015 	}
1128*faa1795aSjb150015 }
1129*faa1795aSjb150015 
1130da6c28aaSamw static boolean_t
1131da6c28aaSamw smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval)
1132da6c28aaSamw {
1133da6c28aaSamw 	smbadm_prop_handle_t *pinfo;
1134da6c28aaSamw 	int i;
1135da6c28aaSamw 
1136da6c28aaSamw 	for (i = 0; i < SMBADM_NPROP; i++) {
1137da6c28aaSamw 		pinfo = &smbadm_ptable[i];
1138da6c28aaSamw 		if (strcmp(pinfo->p_name, prop->p_name) == 0) {
1139da6c28aaSamw 			if (pinfo->p_chkfn && chkval)
1140da6c28aaSamw 				return (pinfo->p_chkfn(prop));
1141da6c28aaSamw 
1142da6c28aaSamw 			return (B_TRUE);
1143da6c28aaSamw 		}
1144da6c28aaSamw 	}
1145da6c28aaSamw 
1146da6c28aaSamw 	(void) fprintf(stderr,
1147da6c28aaSamw 	    gettext("unrecognized property '%s'\n"), prop->p_name);
1148da6c28aaSamw 
1149da6c28aaSamw 	return (B_FALSE);
1150da6c28aaSamw }
1151da6c28aaSamw 
1152da6c28aaSamw static int
1153da6c28aaSamw smbadm_prop_parse(char *arg, smbadm_prop_t *prop)
1154da6c28aaSamw {
1155da6c28aaSamw 	boolean_t parse_value;
1156da6c28aaSamw 	char *equal;
1157da6c28aaSamw 
1158da6c28aaSamw 	if (arg == NULL)
1159da6c28aaSamw 		return (2);
1160da6c28aaSamw 
1161da6c28aaSamw 	prop->p_name = prop->p_value = NULL;
1162da6c28aaSamw 
1163da6c28aaSamw 	if (strcmp(curcmd->name, "set") == 0)
1164da6c28aaSamw 		parse_value = B_TRUE;
1165da6c28aaSamw 	else
1166da6c28aaSamw 		parse_value = B_FALSE;
1167da6c28aaSamw 
1168da6c28aaSamw 	prop->p_name = arg;
1169da6c28aaSamw 
1170da6c28aaSamw 	if (parse_value) {
1171da6c28aaSamw 		equal = strchr(arg, '=');
1172da6c28aaSamw 		if (equal == NULL)
1173da6c28aaSamw 			return (2);
1174da6c28aaSamw 
1175da6c28aaSamw 		*equal++ = '\0';
1176da6c28aaSamw 		prop->p_value = equal;
1177da6c28aaSamw 	}
1178da6c28aaSamw 
1179da6c28aaSamw 	if (smbadm_prop_validate(prop, parse_value) == B_FALSE)
1180da6c28aaSamw 		return (2);
1181da6c28aaSamw 
1182da6c28aaSamw 	return (0);
1183da6c28aaSamw }
1184da6c28aaSamw 
1185da6c28aaSamw static smbadm_prop_handle_t *
1186da6c28aaSamw smbadm_prop_gethandle(char *pname)
1187da6c28aaSamw {
1188da6c28aaSamw 	int i;
1189da6c28aaSamw 
1190da6c28aaSamw 	for (i = 0; i < SMBADM_NPROP; i++)
1191da6c28aaSamw 		if (strcmp(pname, smbadm_ptable[i].p_name) == 0)
1192da6c28aaSamw 			return (&smbadm_ptable[i]);
1193da6c28aaSamw 
1194da6c28aaSamw 	return (NULL);
1195da6c28aaSamw }
1196da6c28aaSamw 
1197da6c28aaSamw static int
1198da6c28aaSamw smbadm_setprop_desc(char *gname, smbadm_prop_t *prop)
1199da6c28aaSamw {
1200dc20a302Sas200622 	int status;
1201da6c28aaSamw 
1202dc20a302Sas200622 	status = smb_lgrp_setcmnt(gname, prop->p_value);
1203dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
1204da6c28aaSamw 		(void) fprintf(stderr,
1205da6c28aaSamw 		    gettext("failed to modify the group description (%s)\n"),
1206dc20a302Sas200622 		    smb_lgrp_strerror(status));
1207da6c28aaSamw 		return (1);
1208da6c28aaSamw 	}
1209da6c28aaSamw 
1210da6c28aaSamw 	(void) printf(gettext("Successfully modified "
1211da6c28aaSamw 	    "'%s' description\n"), gname);
1212da6c28aaSamw 
1213da6c28aaSamw 	return (0);
1214da6c28aaSamw }
1215da6c28aaSamw 
1216da6c28aaSamw static int
1217da6c28aaSamw smbadm_getprop_desc(char *gname, smbadm_prop_t *prop)
1218da6c28aaSamw {
1219dc20a302Sas200622 	char *cmnt = NULL;
1220dc20a302Sas200622 	int status;
1221da6c28aaSamw 
1222dc20a302Sas200622 	status = smb_lgrp_getcmnt(gname, &cmnt);
1223dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
1224da6c28aaSamw 		(void) fprintf(stderr,
1225dc20a302Sas200622 		    gettext("failed to get the group description (%s)\n"),
1226dc20a302Sas200622 		    smb_lgrp_strerror(status));
1227da6c28aaSamw 		return (1);
1228da6c28aaSamw 	}
1229da6c28aaSamw 
1230dc20a302Sas200622 	(void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt);
1231dc20a302Sas200622 	free(cmnt);
1232da6c28aaSamw 	return (0);
1233da6c28aaSamw }
1234da6c28aaSamw 
1235da6c28aaSamw static int
1236dc20a302Sas200622 smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1237da6c28aaSamw {
1238dc20a302Sas200622 	boolean_t enable;
1239dc20a302Sas200622 	int status;
1240da6c28aaSamw 	int ret;
1241da6c28aaSamw 
1242da6c28aaSamw 	if (strcasecmp(prop->p_value, "on") == 0) {
1243da6c28aaSamw 		(void) printf(gettext("Enabling %s privilege "), prop->p_name);
1244dc20a302Sas200622 		enable = B_TRUE;
1245da6c28aaSamw 	} else {
1246da6c28aaSamw 		(void) printf(gettext("Disabling %s privilege "), prop->p_name);
1247dc20a302Sas200622 		enable = B_FALSE;
1248da6c28aaSamw 	}
1249da6c28aaSamw 
1250dc20a302Sas200622 	status = smb_lgrp_setpriv(gname, priv_id, enable);
1251dc20a302Sas200622 	if (status == SMB_LGRP_SUCCESS) {
1252da6c28aaSamw 		(void) printf(gettext("succeeded\n"));
1253da6c28aaSamw 		ret = 0;
1254da6c28aaSamw 	} else {
1255dc20a302Sas200622 		(void) printf(gettext("failed: %s\n"),
1256dc20a302Sas200622 		    smb_lgrp_strerror(status));
1257da6c28aaSamw 		ret = 1;
1258da6c28aaSamw 	}
1259da6c28aaSamw 
1260da6c28aaSamw 	return (ret);
1261da6c28aaSamw }
1262da6c28aaSamw 
1263da6c28aaSamw static int
1264dc20a302Sas200622 smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1265da6c28aaSamw {
1266dc20a302Sas200622 	boolean_t enable;
1267dc20a302Sas200622 	int status;
1268da6c28aaSamw 
1269dc20a302Sas200622 	status = smb_lgrp_getpriv(gname, priv_id, &enable);
1270dc20a302Sas200622 	if (status != SMB_LGRP_SUCCESS) {
1271da6c28aaSamw 		(void) fprintf(stderr, gettext("failed to get %s (%s)\n"),
1272dc20a302Sas200622 		    prop->p_name, smb_lgrp_strerror(status));
1273da6c28aaSamw 		return (1);
1274da6c28aaSamw 	}
1275da6c28aaSamw 
1276dc20a302Sas200622 	(void) printf(gettext("\t%s: %s\n"), prop->p_name,
1277dc20a302Sas200622 	    (enable) ? "On" : "Off");
1278da6c28aaSamw 
1279da6c28aaSamw 	return (0);
1280da6c28aaSamw }
1281da6c28aaSamw 
1282da6c28aaSamw static int
1283da6c28aaSamw smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop)
1284da6c28aaSamw {
1285da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1286da6c28aaSamw }
1287da6c28aaSamw 
1288da6c28aaSamw static int
1289da6c28aaSamw smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop)
1290da6c28aaSamw {
1291da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1292da6c28aaSamw }
1293da6c28aaSamw 
1294da6c28aaSamw static int
1295da6c28aaSamw smbadm_setprop_backup(char *gname, smbadm_prop_t *prop)
1296da6c28aaSamw {
1297da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_BACKUP_LUID, prop));
1298da6c28aaSamw }
1299da6c28aaSamw 
1300da6c28aaSamw static int
1301da6c28aaSamw smbadm_getprop_backup(char *gname, smbadm_prop_t *prop)
1302da6c28aaSamw {
1303da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_BACKUP_LUID, prop));
1304da6c28aaSamw }
1305da6c28aaSamw 
1306da6c28aaSamw static int
1307da6c28aaSamw smbadm_setprop_restore(char *gname, smbadm_prop_t *prop)
1308da6c28aaSamw {
1309da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_RESTORE_LUID, prop));
1310da6c28aaSamw }
1311da6c28aaSamw 
1312da6c28aaSamw static int
1313da6c28aaSamw smbadm_getprop_restore(char *gname, smbadm_prop_t *prop)
1314da6c28aaSamw {
1315da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_RESTORE_LUID, prop));
1316da6c28aaSamw }
1317da6c28aaSamw 
1318da6c28aaSamw static boolean_t
1319da6c28aaSamw smbadm_chkprop_priv(smbadm_prop_t *prop)
1320da6c28aaSamw {
1321da6c28aaSamw 	if (prop->p_value == NULL || *prop->p_value == '\0') {
1322da6c28aaSamw 		(void) fprintf(stderr,
1323da6c28aaSamw 		    gettext("missing value for '%s'\n"), prop->p_name);
1324da6c28aaSamw 		return (B_FALSE);
1325da6c28aaSamw 	}
1326da6c28aaSamw 
1327da6c28aaSamw 	if (strcasecmp(prop->p_value, "on") == 0)
1328da6c28aaSamw 		return (B_TRUE);
1329da6c28aaSamw 
1330da6c28aaSamw 	if (strcasecmp(prop->p_value, "off") == 0)
1331da6c28aaSamw 		return (B_TRUE);
1332da6c28aaSamw 
1333da6c28aaSamw 	(void) fprintf(stderr,
1334da6c28aaSamw 	    gettext("%s: unrecognized value for '%s' property\n"),
1335da6c28aaSamw 	    prop->p_value, prop->p_name);
1336da6c28aaSamw 
1337da6c28aaSamw 	return (B_FALSE);
1338da6c28aaSamw }
1339da6c28aaSamw 
1340da6c28aaSamw static const char *
1341da6c28aaSamw smbadm_pwd_strerror(int error)
1342da6c28aaSamw {
1343da6c28aaSamw 	switch (error) {
1344da6c28aaSamw 	case SMB_PWE_SUCCESS:
1345da6c28aaSamw 		return (gettext("Success."));
1346da6c28aaSamw 
1347da6c28aaSamw 	case SMB_PWE_USER_UNKNOWN:
1348da6c28aaSamw 		return (gettext("User does not exist."));
1349da6c28aaSamw 
1350da6c28aaSamw 	case SMB_PWE_USER_DISABLE:
1351da6c28aaSamw 		return (gettext("User is disable."));
1352da6c28aaSamw 
1353da6c28aaSamw 	case SMB_PWE_CLOSE_FAILED:
1354da6c28aaSamw 	case SMB_PWE_OPEN_FAILED:
1355da6c28aaSamw 	case SMB_PWE_WRITE_FAILED:
1356da6c28aaSamw 	case SMB_PWE_UPDATE_FAILED:
1357da6c28aaSamw 		return (gettext("Unexpected failure. "
1358da6c28aaSamw 		    "SMB password database unchanged."));
1359da6c28aaSamw 
1360da6c28aaSamw 	case SMB_PWE_STAT_FAILED:
1361da6c28aaSamw 		return (gettext("stat of SMB password file failed."));
1362da6c28aaSamw 
1363da6c28aaSamw 	case SMB_PWE_BUSY:
1364da6c28aaSamw 		return (gettext("SMB password database busy. "
1365da6c28aaSamw 		    "Try again later."));
1366da6c28aaSamw 
1367da6c28aaSamw 	case SMB_PWE_DENIED:
1368da6c28aaSamw 		return (gettext("Operation not permitted."));
1369da6c28aaSamw 
1370da6c28aaSamw 	case SMB_PWE_SYSTEM_ERROR:
1371da6c28aaSamw 		return (gettext("System error."));
1372da6c28aaSamw 	}
1373da6c28aaSamw 
1374da6c28aaSamw 	return (gettext("Unknown error code."));
1375da6c28aaSamw }
1376da6c28aaSamw 
1377da6c28aaSamw /*
1378da6c28aaSamw  * Enable libumem debugging by default on DEBUG builds.
1379da6c28aaSamw  */
1380da6c28aaSamw #ifdef DEBUG
1381da6c28aaSamw const char *
1382da6c28aaSamw _umem_debug_init(void)
1383da6c28aaSamw {
1384da6c28aaSamw 	return ("default,verbose"); /* $UMEM_DEBUG setting */
1385da6c28aaSamw }
1386da6c28aaSamw 
1387da6c28aaSamw const char *
1388da6c28aaSamw _umem_logging_init(void)
1389da6c28aaSamw {
1390da6c28aaSamw 	return ("fail,contents"); /* $UMEM_LOGGING setting */
1391da6c28aaSamw }
1392da6c28aaSamw #endif
1393