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