xref: /illumos-gate/usr/src/cmd/smbsrv/smbadm/smbadm.c (revision 3db3f65c)
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 /*
22dc20a302Sas  * 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,
56*3db3f65cSamw 	HELP_USER_DISABLE,
57*3db3f65cSamw 	HELP_USER_ENABLE
58da6c28aaSamw } smbadm_help_t;
59da6c28aaSamw 
60*3db3f65cSamw #define	SMBADM_CMDF_USER	0x01
61*3db3f65cSamw #define	SMBADM_CMDF_GROUP	0x02
62*3db3f65cSamw #define	SMBADM_CMDF_TYPEMASK	0x0F
63faa1795aSjb 
64da6c28aaSamw typedef struct smbadm_cmdinfo {
65da6c28aaSamw 	char *name;
66da6c28aaSamw 	int (*func)(int, char **);
67da6c28aaSamw 	smbadm_help_t usage;
68faa1795aSjb 	uint32_t flags;
69da6c28aaSamw } smbadm_cmdinfo_t;
70da6c28aaSamw 
71da6c28aaSamw smbadm_cmdinfo_t *curcmd;
72da6c28aaSamw static char *progname;
73da6c28aaSamw 
74da6c28aaSamw static int smbadm_join(int, char **);
75da6c28aaSamw static int smbadm_list(int, char **);
76da6c28aaSamw static int smbadm_group_create(int, char **);
77da6c28aaSamw static int smbadm_group_delete(int, char **);
78da6c28aaSamw static int smbadm_group_rename(int, char **);
79da6c28aaSamw static int smbadm_group_show(int, char **);
80da6c28aaSamw static int smbadm_group_getprop(int, char **);
81da6c28aaSamw static int smbadm_group_setprop(int, char **);
82da6c28aaSamw static int smbadm_group_addmember(int, char **);
83da6c28aaSamw static int smbadm_group_delmember(int, char **);
84da6c28aaSamw static int smbadm_user_disable(int, char **);
85da6c28aaSamw static int smbadm_user_enable(int, char **);
86da6c28aaSamw 
87da6c28aaSamw static smbadm_cmdinfo_t smbadm_cmdtable[] =
88da6c28aaSamw {
89faa1795aSjb 	{ "add-member",		smbadm_group_addmember,	HELP_ADD_MEMBER,
90faa1795aSjb 	SMBADM_CMDF_GROUP },
91faa1795aSjb 	{ "create",		smbadm_group_create,	HELP_CREATE,
92faa1795aSjb 	SMBADM_CMDF_GROUP },
93faa1795aSjb 	{ "delete",		smbadm_group_delete,	HELP_DELETE,
94faa1795aSjb 	SMBADM_CMDF_GROUP },
95*3db3f65cSamw 	{ "disable-user",	smbadm_user_disable,	HELP_USER_DISABLE,
96*3db3f65cSamw 	SMBADM_CMDF_USER },
97*3db3f65cSamw 	{ "enable-user",	smbadm_user_enable,	HELP_USER_ENABLE,
98*3db3f65cSamw 	SMBADM_CMDF_USER },
99faa1795aSjb 	{ "get",		smbadm_group_getprop,	HELP_GET,
100faa1795aSjb 	SMBADM_CMDF_GROUP },
101faa1795aSjb 	{ "join",		smbadm_join,		HELP_JOIN,	0 },
102faa1795aSjb 	{ "list",		smbadm_list,		HELP_LIST,	0 },
103faa1795aSjb 	{ "remove-member",	smbadm_group_delmember,	HELP_DEL_MEMBER,
104faa1795aSjb 	SMBADM_CMDF_GROUP },
105faa1795aSjb 	{ "rename",		smbadm_group_rename,	HELP_RENAME,
106faa1795aSjb 	SMBADM_CMDF_GROUP },
107faa1795aSjb 	{ "set",		smbadm_group_setprop,	HELP_SET,
108faa1795aSjb 	SMBADM_CMDF_GROUP },
109faa1795aSjb 	{ "show",		smbadm_group_show,	HELP_SHOW,
110faa1795aSjb 	SMBADM_CMDF_GROUP },
111da6c28aaSamw };
112da6c28aaSamw 
113da6c28aaSamw #define	SMBADM_NCMD	(sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0]))
114da6c28aaSamw 
115da6c28aaSamw typedef struct smbadm_prop {
116da6c28aaSamw 	char *p_name;
117da6c28aaSamw 	char *p_value;
118da6c28aaSamw } smbadm_prop_t;
119da6c28aaSamw 
120da6c28aaSamw typedef struct smbadm_prop_handle {
121da6c28aaSamw 	char *p_name;
122da6c28aaSamw 	char *p_dispvalue;
123da6c28aaSamw 	int (*p_setfn)(char *, smbadm_prop_t *);
124da6c28aaSamw 	int (*p_getfn)(char *, smbadm_prop_t *);
125da6c28aaSamw 	boolean_t (*p_chkfn)(smbadm_prop_t *);
126da6c28aaSamw } smbadm_prop_handle_t;
127da6c28aaSamw 
128da6c28aaSamw static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval);
129da6c28aaSamw static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop);
130da6c28aaSamw static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname);
131da6c28aaSamw 
132da6c28aaSamw static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop);
133da6c28aaSamw static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop);
134da6c28aaSamw static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop);
135da6c28aaSamw static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop);
136da6c28aaSamw static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop);
137da6c28aaSamw static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop);
138da6c28aaSamw static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop);
139da6c28aaSamw static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop);
140da6c28aaSamw static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop);
141da6c28aaSamw 
142da6c28aaSamw static smbadm_prop_handle_t smbadm_ptable[] = {
143da6c28aaSamw 	{"backup",	"on | off", 	smbadm_setprop_backup,
144da6c28aaSamw 	smbadm_getprop_backup,	smbadm_chkprop_priv 	},
145da6c28aaSamw 	{"restore",	"on | off",	smbadm_setprop_restore,
146da6c28aaSamw 	smbadm_getprop_restore,	smbadm_chkprop_priv	},
147da6c28aaSamw 	{"take-ownership", "on | off",	smbadm_setprop_tkowner,
148da6c28aaSamw 	smbadm_getprop_tkowner,	smbadm_chkprop_priv	},
149da6c28aaSamw 	{"description",	"<string>",	smbadm_setprop_desc,
150da6c28aaSamw 	smbadm_getprop_desc,	NULL			},
151da6c28aaSamw };
152da6c28aaSamw 
153*3db3f65cSamw static int smbadm_init(void);
154*3db3f65cSamw static void smbadm_fini(void);
155da6c28aaSamw static const char *smbadm_pwd_strerror(int error);
156da6c28aaSamw 
157da6c28aaSamw /*
158da6c28aaSamw  * Number of supported properties
159da6c28aaSamw  */
160da6c28aaSamw #define	SMBADM_NPROP	(sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0]))
161da6c28aaSamw 
162da6c28aaSamw static void
163da6c28aaSamw smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd)
164da6c28aaSamw {
165da6c28aaSamw 	switch (cmd->usage) {
166da6c28aaSamw 	case HELP_ADD_MEMBER:
167da6c28aaSamw 		(void) fprintf(fp,
168da6c28aaSamw 		    gettext("\t%s -m member [[-m member] ...] group\n"),
169da6c28aaSamw 		    cmd->name);
170da6c28aaSamw 		return;
171da6c28aaSamw 
172da6c28aaSamw 	case HELP_CREATE:
173da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [-d description] group\n"),
174da6c28aaSamw 		    cmd->name);
175da6c28aaSamw 		return;
176da6c28aaSamw 
177da6c28aaSamw 	case HELP_DELETE:
178da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s group\n"), cmd->name);
179da6c28aaSamw 		return;
180da6c28aaSamw 
181*3db3f65cSamw 	case HELP_USER_DISABLE:
182*3db3f65cSamw 	case HELP_USER_ENABLE:
183da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s user\n"), cmd->name);
184da6c28aaSamw 		return;
185da6c28aaSamw 
186da6c28aaSamw 	case HELP_GET:
187da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"),
188da6c28aaSamw 		    cmd->name);
189da6c28aaSamw 		return;
190da6c28aaSamw 
191da6c28aaSamw 	case HELP_JOIN:
192da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s -u username domain\n"
193da6c28aaSamw 		    "\t%s -w workgroup\n"), cmd->name, cmd->name);
194da6c28aaSamw 		return;
195da6c28aaSamw 
196da6c28aaSamw 	case HELP_LIST:
197da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s\n"), cmd->name);
198da6c28aaSamw 		return;
199da6c28aaSamw 
200da6c28aaSamw 	case HELP_DEL_MEMBER:
201da6c28aaSamw 		(void) fprintf(fp,
202da6c28aaSamw 		    gettext("\t%s -m member [[-m member] ...] group\n"),
203da6c28aaSamw 		    cmd->name);
204da6c28aaSamw 		return;
205da6c28aaSamw 
206da6c28aaSamw 	case HELP_RENAME:
207da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s group new-group\n"),
208da6c28aaSamw 		    cmd->name);
209da6c28aaSamw 		return;
210da6c28aaSamw 
211da6c28aaSamw 	case HELP_SET:
212da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s -p property=value "
213da6c28aaSamw 		    "[[-p property=value] ...] group\n"), cmd->name);
214da6c28aaSamw 		return;
215da6c28aaSamw 
216da6c28aaSamw 	case HELP_SHOW:
217da6c28aaSamw 		(void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"),
218da6c28aaSamw 		    cmd->name);
219da6c28aaSamw 		return;
220da6c28aaSamw 
221*3db3f65cSamw 	default:
222*3db3f65cSamw 		break;
223da6c28aaSamw 	}
224da6c28aaSamw 
225da6c28aaSamw 	abort();
226da6c28aaSamw 	/* NOTREACHED */
227da6c28aaSamw }
228da6c28aaSamw 
229da6c28aaSamw static void
230da6c28aaSamw smbadm_usage(boolean_t requested)
231da6c28aaSamw {
232da6c28aaSamw 	FILE *fp = requested ? stdout : stderr;
233da6c28aaSamw 	boolean_t show_props = B_FALSE;
234da6c28aaSamw 	int i;
235da6c28aaSamw 
236da6c28aaSamw 	if (curcmd == NULL) {
237da6c28aaSamw 		(void) fprintf(fp,
238da6c28aaSamw 		    gettext("usage: %s [-h | <command> [options]]\n"),
239da6c28aaSamw 		    progname);
240da6c28aaSamw 		(void) fprintf(fp,
241da6c28aaSamw 		    gettext("where 'command' is one of the following:\n\n"));
242da6c28aaSamw 
243da6c28aaSamw 		for (i = 0; i < SMBADM_NCMD; i++)
244da6c28aaSamw 			smbadm_cmdusage(fp, &smbadm_cmdtable[i]);
245da6c28aaSamw 
246da6c28aaSamw 		(void) fprintf(fp,
247da6c28aaSamw 		    gettext("\nFor property list, run %s %s|%s\n"),
248da6c28aaSamw 		    progname, "get", "set");
249da6c28aaSamw 
250da6c28aaSamw 		exit(requested ? 0 : 2);
251da6c28aaSamw 	}
252da6c28aaSamw 
253da6c28aaSamw 	(void) fprintf(fp, gettext("usage:\n"));
254da6c28aaSamw 	smbadm_cmdusage(fp, curcmd);
255da6c28aaSamw 
256da6c28aaSamw 	if (strcmp(curcmd->name, "get") == 0 ||
257da6c28aaSamw 	    strcmp(curcmd->name, "set") == 0)
258da6c28aaSamw 		show_props = B_TRUE;
259da6c28aaSamw 
260da6c28aaSamw 	if (show_props) {
261da6c28aaSamw 		(void) fprintf(fp,
262da6c28aaSamw 		    gettext("\nThe following properties are supported:\n"));
263da6c28aaSamw 
264da6c28aaSamw 		(void) fprintf(fp, "\n\t%-16s   %s\n\n",
265da6c28aaSamw 		    "PROPERTY", "VALUES");
266da6c28aaSamw 
267da6c28aaSamw 		for (i = 0; i < SMBADM_NPROP; i++) {
268da6c28aaSamw 			(void) fprintf(fp, "\t%-16s   %s\n",
269da6c28aaSamw 			    smbadm_ptable[i].p_name,
270da6c28aaSamw 			    smbadm_ptable[i].p_dispvalue);
271da6c28aaSamw 		}
272da6c28aaSamw 	}
273da6c28aaSamw 
274da6c28aaSamw 	exit(requested ? 0 : 2);
275da6c28aaSamw }
276da6c28aaSamw 
277da6c28aaSamw /*
278da6c28aaSamw  * smbadm_join
279da6c28aaSamw  *
280da6c28aaSamw  * Join the given domain/workgroup
281da6c28aaSamw  */
282da6c28aaSamw static int
283da6c28aaSamw smbadm_join(int argc, char **argv)
284da6c28aaSamw {
285da6c28aaSamw 	char option;
286da6c28aaSamw 	smb_joininfo_t jdi;
287da6c28aaSamw 	boolean_t join_w = B_FALSE;
288da6c28aaSamw 	boolean_t join_d = B_FALSE;
289da6c28aaSamw 	uint32_t status;
2908c10a865Sas 	char curdom[MAXHOSTNAMELEN];
291da6c28aaSamw 
292da6c28aaSamw 	bzero(&jdi, sizeof (jdi));
293da6c28aaSamw 
294da6c28aaSamw 	while ((option = getopt(argc, argv, "u:w:")) != -1) {
295da6c28aaSamw 		switch (option) {
296da6c28aaSamw 		case 'w':
297da6c28aaSamw 			(void) strlcpy(jdi.domain_name, optarg,
298da6c28aaSamw 			    sizeof (jdi.domain_name));
299da6c28aaSamw 			jdi.mode = SMB_SECMODE_WORKGRP;
300da6c28aaSamw 			join_w = B_TRUE;
301da6c28aaSamw 			break;
302da6c28aaSamw 
303da6c28aaSamw 		case 'u':
304da6c28aaSamw 			/* admin username */
305da6c28aaSamw 			(void) strlcpy(jdi.domain_username, optarg,
306da6c28aaSamw 			    sizeof (jdi.domain_username));
307da6c28aaSamw 			jdi.mode = SMB_SECMODE_DOMAIN;
308da6c28aaSamw 			join_d = B_TRUE;
309da6c28aaSamw 			break;
310da6c28aaSamw 
311da6c28aaSamw 		default:
312da6c28aaSamw 			smbadm_usage(B_FALSE);
313da6c28aaSamw 		}
314da6c28aaSamw 	}
315da6c28aaSamw 
316da6c28aaSamw 	if (join_w && join_d) {
317da6c28aaSamw 		(void) fprintf(stderr,
318da6c28aaSamw 		    gettext("domain and workgroup "
319da6c28aaSamw 		    "can not be specified together\n"));
320da6c28aaSamw 		smbadm_usage(B_FALSE);
321da6c28aaSamw 	}
322da6c28aaSamw 
323da6c28aaSamw 	if (join_d && (argv[optind] != NULL)) {
324da6c28aaSamw 		(void) strlcpy(jdi.domain_name, argv[optind],
325da6c28aaSamw 		    sizeof (jdi.domain_name));
326da6c28aaSamw 	}
327da6c28aaSamw 
328da6c28aaSamw 	if (*jdi.domain_name == '\0') {
329da6c28aaSamw 		(void) fprintf(stderr, gettext("missing %s name\n"),
330da6c28aaSamw 		    (join_d) ? "domain" : "workgroup");
331da6c28aaSamw 		smbadm_usage(B_FALSE);
332da6c28aaSamw 	}
333da6c28aaSamw 
334da6c28aaSamw 	if (join_d && *jdi.domain_username == '\0') {
335da6c28aaSamw 		(void) fprintf(stderr, gettext("missing username\n"));
336da6c28aaSamw 		smbadm_usage(B_FALSE);
337da6c28aaSamw 	}
338da6c28aaSamw 
339da6c28aaSamw 	if (join_w) {
340da6c28aaSamw 		status = smb_join(&jdi);
341da6c28aaSamw 		if (status == NT_STATUS_SUCCESS) {
342da6c28aaSamw 			(void) printf(
343da6c28aaSamw 			    gettext("Successfully joined workgroup '%s'\n"),
344da6c28aaSamw 			    jdi.domain_name);
345da6c28aaSamw 			return (0);
346da6c28aaSamw 		}
347da6c28aaSamw 
348da6c28aaSamw 		(void) fprintf(stderr,
349da6c28aaSamw 		    gettext("failed to join workgroup '%s' (%s)\n"),
350da6c28aaSamw 		    jdi.domain_name, xlate_nt_status(status));
351da6c28aaSamw 
352da6c28aaSamw 		return (1);
353da6c28aaSamw 	}
354da6c28aaSamw 
3558c10a865Sas 	if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
3568c10a865Sas 		(void) smb_getdomainname(curdom, MAXHOSTNAMELEN);
3578c10a865Sas 		if (*curdom != 0 && strncasecmp(curdom, jdi.domain_name,
3588c10a865Sas 		    strlen(curdom))) {
359faa1795aSjb 			char reply[8];
360faa1795aSjb 
3618c10a865Sas 			(void) printf(gettext("This system has already "
3628c10a865Sas 			    "joined to '%s' domain.\n"
3638c10a865Sas 			    "Would you like to join the new domain "
3648c10a865Sas 			    "[yes/no]? "),
3658c10a865Sas 			    curdom);
366faa1795aSjb 			(void) scanf("%8s", reply);
367faa1795aSjb 			(void) trim_whitespace(reply);
368faa1795aSjb 			if (strncasecmp(reply, "yes", 3) != 0)
369faa1795aSjb 				return (0);
370faa1795aSjb 		}
371faa1795aSjb 	}
372faa1795aSjb 
373da6c28aaSamw 	/* Join the domain */
374da6c28aaSamw 	if (*jdi.domain_passwd == '\0') {
375da6c28aaSamw 		char *p = NULL;
376da6c28aaSamw 		char *prompt = gettext("Enter domain password: ");
377da6c28aaSamw 		p = getpassphrase(prompt);
378da6c28aaSamw 		if (!p) {
379da6c28aaSamw 			(void) fprintf(stderr, gettext("missing password\n"));
380da6c28aaSamw 			smbadm_usage(B_FALSE);
381da6c28aaSamw 		}
382da6c28aaSamw 
383da6c28aaSamw 		(void) strlcpy(jdi.domain_passwd, p,
384da6c28aaSamw 		    sizeof (jdi.domain_passwd));
385da6c28aaSamw 	}
386da6c28aaSamw 
387da6c28aaSamw 	(void) printf(gettext("Joining '%s' ... this may take a minute ...\n"),
388da6c28aaSamw 	    jdi.domain_name);
389da6c28aaSamw 
390da6c28aaSamw 	status = smb_join(&jdi);
391da6c28aaSamw 
392da6c28aaSamw 	switch (status) {
393da6c28aaSamw 	case NT_STATUS_SUCCESS:
394da6c28aaSamw 		(void) printf(gettext("Successfully joined domain '%s'\n"),
395da6c28aaSamw 		    jdi.domain_name);
3966537f381Sas 
397da6c28aaSamw 		return (0);
398da6c28aaSamw 
399da6c28aaSamw 	case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
400da6c28aaSamw 		(void) fprintf(stderr, gettext("failed to find "
401da6c28aaSamw 		    "any domain controllers for '%s'\n"),
402da6c28aaSamw 		    jdi.domain_name);
403da6c28aaSamw 		break;
404da6c28aaSamw 
405da6c28aaSamw 	default:
406da6c28aaSamw 		(void) fprintf(stderr,
407da6c28aaSamw 		    gettext("failed to join domain '%s' (%s)\n"),
408da6c28aaSamw 		    jdi.domain_name, xlate_nt_status(status));
409da6c28aaSamw 	}
410da6c28aaSamw 
411da6c28aaSamw 	return (1);
412da6c28aaSamw }
413da6c28aaSamw 
414da6c28aaSamw /*
415da6c28aaSamw  * smbadm_list
416da6c28aaSamw  *
417da6c28aaSamw  * Displays current security mode and domain/workgroup name.
418da6c28aaSamw  */
419da6c28aaSamw /*ARGSUSED*/
420da6c28aaSamw static int
421da6c28aaSamw smbadm_list(int argc, char **argv)
422da6c28aaSamw {
423faa1795aSjb 	char domain[MAXHOSTNAMELEN];
424faa1795aSjb 	char modename[16];
425faa1795aSjb 	int rc;
426da6c28aaSamw 
427faa1795aSjb 	rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename));
428faa1795aSjb 	if (rc != SMBD_SMF_OK) {
429da6c28aaSamw 		(void) fprintf(stderr,
430da6c28aaSamw 		    gettext("failed to get the security mode\n"));
431da6c28aaSamw 		return (1);
432da6c28aaSamw 	}
433da6c28aaSamw 
434faa1795aSjb 	(void) printf(gettext("security mode: %s\n"), modename);
435da6c28aaSamw 
436faa1795aSjb 	if (smb_getdomainname(domain, sizeof (domain)) != 0) {
437faa1795aSjb 		(void) fprintf(stderr, gettext("failed to get the %s name\n"),
438faa1795aSjb 		    modename);
439da6c28aaSamw 		return (1);
440da6c28aaSamw 	}
441da6c28aaSamw 
442faa1795aSjb 	(void) printf(gettext("%s name: %s\n"), modename, domain);
443da6c28aaSamw 	return (0);
444da6c28aaSamw }
445da6c28aaSamw 
446da6c28aaSamw /*
447da6c28aaSamw  * smbadm_group_create
448da6c28aaSamw  *
449da6c28aaSamw  * Creates a local SMB group
450da6c28aaSamw  */
451da6c28aaSamw static int
452da6c28aaSamw smbadm_group_create(int argc, char **argv)
453da6c28aaSamw {
454da6c28aaSamw 	char *gname = NULL;
455da6c28aaSamw 	char *desc = NULL;
456da6c28aaSamw 	char option;
457dc20a302Sas 	int status;
458da6c28aaSamw 
459da6c28aaSamw 	while ((option = getopt(argc, argv, "d:")) != -1) {
460da6c28aaSamw 		switch (option) {
461da6c28aaSamw 		case 'd':
462da6c28aaSamw 			desc = optarg;
463da6c28aaSamw 			break;
464da6c28aaSamw 
465da6c28aaSamw 		default:
466da6c28aaSamw 			smbadm_usage(B_FALSE);
467da6c28aaSamw 		}
468da6c28aaSamw 	}
469da6c28aaSamw 
470da6c28aaSamw 	gname = argv[optind];
471da6c28aaSamw 	if (optind >= argc || gname == NULL || *gname == '\0') {
472da6c28aaSamw 		(void) fprintf(stderr, gettext("missing group name\n"));
473da6c28aaSamw 		smbadm_usage(B_FALSE);
474da6c28aaSamw 	}
475da6c28aaSamw 
476da6c28aaSamw 	if (getgrnam(gname) == NULL) {
477da6c28aaSamw 		(void) fprintf(stderr,
478dc20a302Sas 		    gettext("failed to get the Solaris group '%s'\n"), gname);
479da6c28aaSamw 		(void) fprintf(stderr,
480dc20a302Sas 		    gettext("use 'groupadd' to add '%s'\n"), gname);
481da6c28aaSamw 		return (1);
482da6c28aaSamw 	}
483da6c28aaSamw 
484dc20a302Sas 	status = smb_lgrp_add(gname, desc);
485dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
486da6c28aaSamw 		(void) fprintf(stderr,
487da6c28aaSamw 		    gettext("failed to create the group (%s)\n"),
488dc20a302Sas 		    smb_lgrp_strerror(status));
489da6c28aaSamw 	} else {
490dc20a302Sas 		(void) printf(gettext("'%s' created.\n"),
491da6c28aaSamw 		    gname);
492da6c28aaSamw 	}
493da6c28aaSamw 
494da6c28aaSamw 	return (status);
495da6c28aaSamw }
496da6c28aaSamw 
497da6c28aaSamw /*
498da6c28aaSamw  * smbadm_group_dump_members
499da6c28aaSamw  *
500da6c28aaSamw  * Dump group members details.
501da6c28aaSamw  */
502da6c28aaSamw static void
503dc20a302Sas smbadm_group_dump_members(smb_gsid_t *members, int num)
504da6c28aaSamw {
5056537f381Sas 	char sidstr[SMB_SID_STRSZ];
506da6c28aaSamw 	int i;
507da6c28aaSamw 
508dc20a302Sas 	if (num == 0) {
509da6c28aaSamw 		(void) printf(gettext("\tNo members\n"));
510da6c28aaSamw 		return;
511da6c28aaSamw 	}
512da6c28aaSamw 
513da6c28aaSamw 	(void) printf(gettext("\tMembers:\n"));
514dc20a302Sas 	for (i = 0; i < num; i++) {
5158c10a865Sas 		*sidstr = '\0';
5168c10a865Sas 		if (smb_lookup_sid(members[i].gs_sid, sidstr,
5178c10a865Sas 		    sizeof (sidstr)) == NT_STATUS_SUCCESS)
5188c10a865Sas 			(void) printf(gettext("\t\t%s\n"), sidstr);
5198c10a865Sas 		else
5208c10a865Sas 			(void) printf(gettext("\t\tERROR! Invalid SID\n"));
521da6c28aaSamw 	}
522da6c28aaSamw }
523da6c28aaSamw 
524da6c28aaSamw /*
525da6c28aaSamw  * smbadm_group_dump_privs
526da6c28aaSamw  *
527da6c28aaSamw  * Dump group privilege details.
528da6c28aaSamw  */
529da6c28aaSamw static void
530dc20a302Sas smbadm_group_dump_privs(smb_privset_t *privs)
531da6c28aaSamw {
532dc20a302Sas 	smb_privinfo_t *pinfo;
533dc20a302Sas 	char *pstatus;
534da6c28aaSamw 	int i;
535da6c28aaSamw 
536da6c28aaSamw 	(void) printf(gettext("\tPrivileges: \n"));
537da6c28aaSamw 
538dc20a302Sas 	for (i = 0; i < privs->priv_cnt; i++) {
539dc20a302Sas 		pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part);
540dc20a302Sas 		if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0)
541da6c28aaSamw 			continue;
542da6c28aaSamw 
543dc20a302Sas 		switch (privs->priv[i].attrs) {
544dc20a302Sas 		case SE_PRIVILEGE_ENABLED:
545dc20a302Sas 			pstatus = "On";
546dc20a302Sas 			break;
547dc20a302Sas 		case SE_PRIVILEGE_DISABLED:
548dc20a302Sas 			pstatus = "Off";
549dc20a302Sas 			break;
550dc20a302Sas 		default:
551dc20a302Sas 			pstatus = "Unknown";
552dc20a302Sas 			break;
553da6c28aaSamw 		}
554dc20a302Sas 		(void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus);
555da6c28aaSamw 	}
556da6c28aaSamw 
557dc20a302Sas 	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  */
566dc20a302Sas static void
567dc20a302Sas smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
568da6c28aaSamw {
5696537f381Sas 	char sidstr[SMB_SID_STRSZ];
570da6c28aaSamw 
571dc20a302Sas 	(void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);
572da6c28aaSamw 
5736537f381Sas 	smb_sid_tostr(grp->sg_id.gs_sid, sidstr);
574dc20a302Sas 	(void) printf(gettext("\tSID: %s\n"), sidstr);
575da6c28aaSamw 
576dc20a302Sas 	if (show_privs)
577dc20a302Sas 		smbadm_group_dump_privs(grp->sg_privs);
578da6c28aaSamw 
579dc20a302Sas 	if (show_mem)
580dc20a302Sas 		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;
594dc20a302Sas 	int status;
595dc20a302Sas 	smb_group_t grp;
596dc20a302Sas 	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 
618dc20a302Sas 	if (strcmp(gname, "*")) {
619dc20a302Sas 		status = smb_lgrp_getbyname(gname, &grp);
620dc20a302Sas 		if (status == SMB_LGRP_SUCCESS) {
621dc20a302Sas 			smbadm_group_dump(&grp, show_members, show_privs);
622dc20a302Sas 			smb_lgrp_free(&grp);
623dc20a302Sas 		} else {
624da6c28aaSamw 			(void) fprintf(stderr,
625dc20a302Sas 			    gettext("failed to find '%s' (%s)\n"),
626dc20a302Sas 			    gname, smb_lgrp_strerror(status));
627da6c28aaSamw 		}
628dc20a302Sas 		return (status);
629dc20a302Sas 	}
630da6c28aaSamw 
6316537f381Sas 	if ((status = smb_lgrp_iteropen(&gi)) != SMB_LGRP_SUCCESS) {
632dc20a302Sas 		(void) fprintf(stderr,
633dc20a302Sas 		    gettext("failed to list groups (%s)\n"),
634dc20a302Sas 		    smb_lgrp_strerror(status));
635dc20a302Sas 		return (status);
636dc20a302Sas 	}
637da6c28aaSamw 
6386537f381Sas 	while ((status = smb_lgrp_iterate(&gi, &grp)) == SMB_LGRP_SUCCESS) {
639dc20a302Sas 		smbadm_group_dump(&grp, show_members, show_privs);
640dc20a302Sas 		smb_lgrp_free(&grp);
641da6c28aaSamw 	}
6426537f381Sas 
643dc20a302Sas 	smb_lgrp_iterclose(&gi);
644da6c28aaSamw 
6456537f381Sas 	if (status != SMB_LGRP_NO_MORE) {
6466537f381Sas 		(void) fprintf(stderr,
6476537f381Sas 		    gettext("failed to get all the groups (%s)\n"),
6486537f381Sas 		    smb_lgrp_strerror(status));
6496537f381Sas 		return (status);
6506537f381Sas 	}
6516537f381Sas 
652dc20a302Sas 	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;
662dc20a302Sas 	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 
670dc20a302Sas 	status = smb_lgrp_delete(gname);
671dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
672da6c28aaSamw 		(void) fprintf(stderr,
673da6c28aaSamw 		    gettext("failed to delete the group (%s)\n"),
674dc20a302Sas 		    smb_lgrp_strerror(status));
675da6c28aaSamw 	} else {
676dc20a302Sas 		(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;
691dc20a302Sas 	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 
705dc20a302Sas 	if (getgrnam(ngname) == NULL) {
706da6c28aaSamw 		(void) fprintf(stderr,
707dc20a302Sas 		    gettext("failed to get the Solaris group '%s'\n"), ngname);
708da6c28aaSamw 		(void) fprintf(stderr,
709dc20a302Sas 		    gettext("use 'groupadd' to add '%s'\n"), ngname);
710da6c28aaSamw 		return (1);
711da6c28aaSamw 	}
712da6c28aaSamw 
713dc20a302Sas 	status = smb_lgrp_rename(gname, ngname);
714dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
715dc20a302Sas 		if (status == SMB_LGRP_EXISTS)
716dc20a302Sas 			(void) fprintf(stderr,
717dc20a302Sas 			    gettext("failed to rename '%s' (%s already "
718dc20a302Sas 			    "exists)\n"), gname, ngname);
719dc20a302Sas 		else
720dc20a302Sas 			(void) fprintf(stderr,
721dc20a302Sas 			    gettext("failed to rename '%s' (%s)\n"), gname,
722dc20a302Sas 			    smb_lgrp_strerror(status));
723da6c28aaSamw 	} else {
724dc20a302Sas 		(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 
758dc20a302Sas 			if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
759dc20a302Sas 				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 
818dc20a302Sas 			if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
819dc20a302Sas 				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;
864dc20a302Sas 	smb_gsid_t msid;
865dc20a302Sas 	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 
908dc20a302Sas 		if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
909dc20a302Sas 			(void) fprintf(stderr,
910dc20a302Sas 			    gettext("failed to add %s "
911dc20a302Sas 			    "(could not obtain the SID)\n"),
912dc20a302Sas 			    mname[i]);
913dc20a302Sas 			continue;
914dc20a302Sas 		}
915dc20a302Sas 
916dc20a302Sas 		status = smb_lgrp_add_member(gname, msid.gs_sid, msid.gs_type);
917dc20a302Sas 		free(msid.gs_sid);
918dc20a302Sas 		if (status != SMB_LGRP_SUCCESS) {
919da6c28aaSamw 			(void) fprintf(stderr,
920da6c28aaSamw 			    gettext("failed to add %s (%s)\n"),
921dc20a302Sas 			    mname[i], smb_lgrp_strerror(status));
922da6c28aaSamw 			ret = 1;
923dc20a302Sas 		} else {
924dc20a302Sas 			(void) printf(gettext("'%s' is now a member of '%s'\n"),
925da6c28aaSamw 			    mname[i], gname);
926dc20a302Sas 		}
927da6c28aaSamw 	}
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;
942dc20a302Sas 	smb_gsid_t msid;
943dc20a302Sas 	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 
985dc20a302Sas 		if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
986dc20a302Sas 			(void) fprintf(stderr,
987dc20a302Sas 			    gettext("failed to remove %s "
988dc20a302Sas 			    "(could not obtain the SID)\n"),
989dc20a302Sas 			    mname[i]);
990dc20a302Sas 			continue;
991dc20a302Sas 		}
992dc20a302Sas 
993dc20a302Sas 		status = smb_lgrp_del_member(gname, msid.gs_sid, msid.gs_type);
994dc20a302Sas 		free(msid.gs_sid);
995dc20a302Sas 		if (status != SMB_LGRP_SUCCESS) {
996da6c28aaSamw 			(void) fprintf(stderr,
997da6c28aaSamw 			    gettext("failed to remove %s (%s)\n"),
998dc20a302Sas 			    mname[i], smb_lgrp_strerror(status));
999da6c28aaSamw 			ret = 1;
1000da6c28aaSamw 		} else {
1001da6c28aaSamw 			(void) printf(
1002dc20a302Sas 			    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 {
1056dc20a302Sas 	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 
1099*3db3f65cSamw 			if ((ret = smbadm_init()) != 0)
1100faa1795aSjb 				return (ret);
1101dc20a302Sas 
1102dc20a302Sas 			ret = curcmd->func(argc - 1, &argv[1]);
1103faa1795aSjb 
1104*3db3f65cSamw 			smbadm_fini();
1105dc20a302Sas 			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 
1115faa1795aSjb static int
1116*3db3f65cSamw smbadm_init(void)
1117faa1795aSjb {
1118faa1795aSjb 	int rc;
1119faa1795aSjb 
1120*3db3f65cSamw 	switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) {
1121*3db3f65cSamw 	case SMBADM_CMDF_GROUP:
1122faa1795aSjb 		if (smb_idmap_start() != 0) {
1123faa1795aSjb 			(void) fprintf(stderr,
1124faa1795aSjb 			    gettext("failed to contact idmap service\n"));
1125faa1795aSjb 			return (1);
1126faa1795aSjb 		}
1127faa1795aSjb 
1128faa1795aSjb 		if ((rc = smb_lgrp_start()) != SMB_LGRP_SUCCESS) {
1129faa1795aSjb 			(void) fprintf(stderr,
1130faa1795aSjb 			    gettext("failed to initialize (%s)\n"),
1131faa1795aSjb 			    smb_lgrp_strerror(rc));
1132faa1795aSjb 			smb_idmap_stop();
1133faa1795aSjb 			return (1);
1134faa1795aSjb 		}
1135*3db3f65cSamw 		break;
1136*3db3f65cSamw 
1137*3db3f65cSamw 	case SMBADM_CMDF_USER:
1138*3db3f65cSamw 		smb_pwd_init(B_FALSE);
1139*3db3f65cSamw 		break;
1140*3db3f65cSamw 
1141*3db3f65cSamw 	default:
1142*3db3f65cSamw 		break;
1143faa1795aSjb 	}
1144faa1795aSjb 
1145faa1795aSjb 	return (0);
1146faa1795aSjb }
1147faa1795aSjb 
1148faa1795aSjb static void
1149*3db3f65cSamw smbadm_fini(void)
1150faa1795aSjb {
1151*3db3f65cSamw 	switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) {
1152*3db3f65cSamw 	case SMBADM_CMDF_GROUP:
1153faa1795aSjb 		smb_lgrp_stop();
1154faa1795aSjb 		smb_idmap_stop();
1155*3db3f65cSamw 		break;
1156*3db3f65cSamw 
1157*3db3f65cSamw 	case SMBADM_CMDF_USER:
1158*3db3f65cSamw 		smb_pwd_fini();
1159*3db3f65cSamw 		break;
1160*3db3f65cSamw 
1161*3db3f65cSamw 	default:
1162*3db3f65cSamw 		break;
1163faa1795aSjb 	}
1164faa1795aSjb }
1165faa1795aSjb 
1166da6c28aaSamw static boolean_t
1167da6c28aaSamw smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval)
1168da6c28aaSamw {
1169da6c28aaSamw 	smbadm_prop_handle_t *pinfo;
1170da6c28aaSamw 	int i;
1171da6c28aaSamw 
1172da6c28aaSamw 	for (i = 0; i < SMBADM_NPROP; i++) {
1173da6c28aaSamw 		pinfo = &smbadm_ptable[i];
1174da6c28aaSamw 		if (strcmp(pinfo->p_name, prop->p_name) == 0) {
1175da6c28aaSamw 			if (pinfo->p_chkfn && chkval)
1176da6c28aaSamw 				return (pinfo->p_chkfn(prop));
1177da6c28aaSamw 
1178da6c28aaSamw 			return (B_TRUE);
1179da6c28aaSamw 		}
1180da6c28aaSamw 	}
1181da6c28aaSamw 
1182da6c28aaSamw 	(void) fprintf(stderr,
1183da6c28aaSamw 	    gettext("unrecognized property '%s'\n"), prop->p_name);
1184da6c28aaSamw 
1185da6c28aaSamw 	return (B_FALSE);
1186da6c28aaSamw }
1187da6c28aaSamw 
1188da6c28aaSamw static int
1189da6c28aaSamw smbadm_prop_parse(char *arg, smbadm_prop_t *prop)
1190da6c28aaSamw {
1191da6c28aaSamw 	boolean_t parse_value;
1192da6c28aaSamw 	char *equal;
1193da6c28aaSamw 
1194da6c28aaSamw 	if (arg == NULL)
1195da6c28aaSamw 		return (2);
1196da6c28aaSamw 
1197da6c28aaSamw 	prop->p_name = prop->p_value = NULL;
1198da6c28aaSamw 
1199da6c28aaSamw 	if (strcmp(curcmd->name, "set") == 0)
1200da6c28aaSamw 		parse_value = B_TRUE;
1201da6c28aaSamw 	else
1202da6c28aaSamw 		parse_value = B_FALSE;
1203da6c28aaSamw 
1204da6c28aaSamw 	prop->p_name = arg;
1205da6c28aaSamw 
1206da6c28aaSamw 	if (parse_value) {
1207da6c28aaSamw 		equal = strchr(arg, '=');
1208da6c28aaSamw 		if (equal == NULL)
1209da6c28aaSamw 			return (2);
1210da6c28aaSamw 
1211da6c28aaSamw 		*equal++ = '\0';
1212da6c28aaSamw 		prop->p_value = equal;
1213da6c28aaSamw 	}
1214da6c28aaSamw 
1215da6c28aaSamw 	if (smbadm_prop_validate(prop, parse_value) == B_FALSE)
1216da6c28aaSamw 		return (2);
1217da6c28aaSamw 
1218da6c28aaSamw 	return (0);
1219da6c28aaSamw }
1220da6c28aaSamw 
1221da6c28aaSamw static smbadm_prop_handle_t *
1222da6c28aaSamw smbadm_prop_gethandle(char *pname)
1223da6c28aaSamw {
1224da6c28aaSamw 	int i;
1225da6c28aaSamw 
1226da6c28aaSamw 	for (i = 0; i < SMBADM_NPROP; i++)
1227da6c28aaSamw 		if (strcmp(pname, smbadm_ptable[i].p_name) == 0)
1228da6c28aaSamw 			return (&smbadm_ptable[i]);
1229da6c28aaSamw 
1230da6c28aaSamw 	return (NULL);
1231da6c28aaSamw }
1232da6c28aaSamw 
1233da6c28aaSamw static int
1234da6c28aaSamw smbadm_setprop_desc(char *gname, smbadm_prop_t *prop)
1235da6c28aaSamw {
1236dc20a302Sas 	int status;
1237da6c28aaSamw 
1238dc20a302Sas 	status = smb_lgrp_setcmnt(gname, prop->p_value);
1239dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
1240da6c28aaSamw 		(void) fprintf(stderr,
1241da6c28aaSamw 		    gettext("failed to modify the group description (%s)\n"),
1242dc20a302Sas 		    smb_lgrp_strerror(status));
1243da6c28aaSamw 		return (1);
1244da6c28aaSamw 	}
1245da6c28aaSamw 
1246da6c28aaSamw 	(void) printf(gettext("Successfully modified "
1247da6c28aaSamw 	    "'%s' description\n"), gname);
1248da6c28aaSamw 
1249da6c28aaSamw 	return (0);
1250da6c28aaSamw }
1251da6c28aaSamw 
1252da6c28aaSamw static int
1253da6c28aaSamw smbadm_getprop_desc(char *gname, smbadm_prop_t *prop)
1254da6c28aaSamw {
1255dc20a302Sas 	char *cmnt = NULL;
1256dc20a302Sas 	int status;
1257da6c28aaSamw 
1258dc20a302Sas 	status = smb_lgrp_getcmnt(gname, &cmnt);
1259dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
1260da6c28aaSamw 		(void) fprintf(stderr,
1261dc20a302Sas 		    gettext("failed to get the group description (%s)\n"),
1262dc20a302Sas 		    smb_lgrp_strerror(status));
1263da6c28aaSamw 		return (1);
1264da6c28aaSamw 	}
1265da6c28aaSamw 
1266dc20a302Sas 	(void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt);
1267dc20a302Sas 	free(cmnt);
1268da6c28aaSamw 	return (0);
1269da6c28aaSamw }
1270da6c28aaSamw 
1271da6c28aaSamw static int
1272dc20a302Sas smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1273da6c28aaSamw {
1274dc20a302Sas 	boolean_t enable;
1275dc20a302Sas 	int status;
1276da6c28aaSamw 	int ret;
1277da6c28aaSamw 
1278da6c28aaSamw 	if (strcasecmp(prop->p_value, "on") == 0) {
1279da6c28aaSamw 		(void) printf(gettext("Enabling %s privilege "), prop->p_name);
1280dc20a302Sas 		enable = B_TRUE;
1281da6c28aaSamw 	} else {
1282da6c28aaSamw 		(void) printf(gettext("Disabling %s privilege "), prop->p_name);
1283dc20a302Sas 		enable = B_FALSE;
1284da6c28aaSamw 	}
1285da6c28aaSamw 
1286dc20a302Sas 	status = smb_lgrp_setpriv(gname, priv_id, enable);
1287dc20a302Sas 	if (status == SMB_LGRP_SUCCESS) {
1288da6c28aaSamw 		(void) printf(gettext("succeeded\n"));
1289da6c28aaSamw 		ret = 0;
1290da6c28aaSamw 	} else {
1291dc20a302Sas 		(void) printf(gettext("failed: %s\n"),
1292dc20a302Sas 		    smb_lgrp_strerror(status));
1293da6c28aaSamw 		ret = 1;
1294da6c28aaSamw 	}
1295da6c28aaSamw 
1296da6c28aaSamw 	return (ret);
1297da6c28aaSamw }
1298da6c28aaSamw 
1299da6c28aaSamw static int
1300dc20a302Sas smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1301da6c28aaSamw {
1302dc20a302Sas 	boolean_t enable;
1303dc20a302Sas 	int status;
1304da6c28aaSamw 
1305dc20a302Sas 	status = smb_lgrp_getpriv(gname, priv_id, &enable);
1306dc20a302Sas 	if (status != SMB_LGRP_SUCCESS) {
1307da6c28aaSamw 		(void) fprintf(stderr, gettext("failed to get %s (%s)\n"),
1308dc20a302Sas 		    prop->p_name, smb_lgrp_strerror(status));
1309da6c28aaSamw 		return (1);
1310da6c28aaSamw 	}
1311da6c28aaSamw 
1312dc20a302Sas 	(void) printf(gettext("\t%s: %s\n"), prop->p_name,
1313dc20a302Sas 	    (enable) ? "On" : "Off");
1314da6c28aaSamw 
1315da6c28aaSamw 	return (0);
1316da6c28aaSamw }
1317da6c28aaSamw 
1318da6c28aaSamw static int
1319da6c28aaSamw smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop)
1320da6c28aaSamw {
1321da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1322da6c28aaSamw }
1323da6c28aaSamw 
1324da6c28aaSamw static int
1325da6c28aaSamw smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop)
1326da6c28aaSamw {
1327da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1328da6c28aaSamw }
1329da6c28aaSamw 
1330da6c28aaSamw static int
1331da6c28aaSamw smbadm_setprop_backup(char *gname, smbadm_prop_t *prop)
1332da6c28aaSamw {
1333da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_BACKUP_LUID, prop));
1334da6c28aaSamw }
1335da6c28aaSamw 
1336da6c28aaSamw static int
1337da6c28aaSamw smbadm_getprop_backup(char *gname, smbadm_prop_t *prop)
1338da6c28aaSamw {
1339da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_BACKUP_LUID, prop));
1340da6c28aaSamw }
1341da6c28aaSamw 
1342da6c28aaSamw static int
1343da6c28aaSamw smbadm_setprop_restore(char *gname, smbadm_prop_t *prop)
1344da6c28aaSamw {
1345da6c28aaSamw 	return (smbadm_group_setpriv(gname, SE_RESTORE_LUID, prop));
1346da6c28aaSamw }
1347da6c28aaSamw 
1348da6c28aaSamw static int
1349da6c28aaSamw smbadm_getprop_restore(char *gname, smbadm_prop_t *prop)
1350da6c28aaSamw {
1351da6c28aaSamw 	return (smbadm_group_getpriv(gname, SE_RESTORE_LUID, prop));
1352da6c28aaSamw }
1353da6c28aaSamw 
1354da6c28aaSamw static boolean_t
1355da6c28aaSamw smbadm_chkprop_priv(smbadm_prop_t *prop)
1356da6c28aaSamw {
1357da6c28aaSamw 	if (prop->p_value == NULL || *prop->p_value == '\0') {
1358da6c28aaSamw 		(void) fprintf(stderr,
1359da6c28aaSamw 		    gettext("missing value for '%s'\n"), prop->p_name);
1360da6c28aaSamw 		return (B_FALSE);
1361da6c28aaSamw 	}
1362da6c28aaSamw 
1363da6c28aaSamw 	if (strcasecmp(prop->p_value, "on") == 0)
1364da6c28aaSamw 		return (B_TRUE);
1365da6c28aaSamw 
1366da6c28aaSamw 	if (strcasecmp(prop->p_value, "off") == 0)
1367da6c28aaSamw 		return (B_TRUE);
1368da6c28aaSamw 
1369da6c28aaSamw 	(void) fprintf(stderr,
1370da6c28aaSamw 	    gettext("%s: unrecognized value for '%s' property\n"),
1371da6c28aaSamw 	    prop->p_value, prop->p_name);
1372da6c28aaSamw 
1373da6c28aaSamw 	return (B_FALSE);
1374da6c28aaSamw }
1375da6c28aaSamw 
1376da6c28aaSamw static const char *
1377da6c28aaSamw smbadm_pwd_strerror(int error)
1378da6c28aaSamw {
1379da6c28aaSamw 	switch (error) {
1380da6c28aaSamw 	case SMB_PWE_SUCCESS:
1381da6c28aaSamw 		return (gettext("Success."));
1382da6c28aaSamw 
1383da6c28aaSamw 	case SMB_PWE_USER_UNKNOWN:
1384da6c28aaSamw 		return (gettext("User does not exist."));
1385da6c28aaSamw 
1386da6c28aaSamw 	case SMB_PWE_USER_DISABLE:
1387da6c28aaSamw 		return (gettext("User is disable."));
1388da6c28aaSamw 
1389da6c28aaSamw 	case SMB_PWE_CLOSE_FAILED:
1390da6c28aaSamw 	case SMB_PWE_OPEN_FAILED:
1391da6c28aaSamw 	case SMB_PWE_WRITE_FAILED:
1392da6c28aaSamw 	case SMB_PWE_UPDATE_FAILED:
1393da6c28aaSamw 		return (gettext("Unexpected failure. "
1394da6c28aaSamw 		    "SMB password database unchanged."));
1395da6c28aaSamw 
1396da6c28aaSamw 	case SMB_PWE_STAT_FAILED:
1397da6c28aaSamw 		return (gettext("stat of SMB password file failed."));
1398da6c28aaSamw 
1399da6c28aaSamw 	case SMB_PWE_BUSY:
1400da6c28aaSamw 		return (gettext("SMB password database busy. "
1401da6c28aaSamw 		    "Try again later."));
1402da6c28aaSamw 
1403da6c28aaSamw 	case SMB_PWE_DENIED:
1404da6c28aaSamw 		return (gettext("Operation not permitted."));
1405da6c28aaSamw 
1406da6c28aaSamw 	case SMB_PWE_SYSTEM_ERROR:
1407da6c28aaSamw 		return (gettext("System error."));
1408*3db3f65cSamw 
1409*3db3f65cSamw 	default:
1410*3db3f65cSamw 		break;
1411da6c28aaSamw 	}
1412da6c28aaSamw 
1413da6c28aaSamw 	return (gettext("Unknown error code."));
1414da6c28aaSamw }
1415da6c28aaSamw 
1416da6c28aaSamw /*
1417da6c28aaSamw  * Enable libumem debugging by default on DEBUG builds.
1418da6c28aaSamw  */
1419da6c28aaSamw #ifdef DEBUG
1420da6c28aaSamw const char *
1421da6c28aaSamw _umem_debug_init(void)
1422da6c28aaSamw {
1423da6c28aaSamw 	return ("default,verbose"); /* $UMEM_DEBUG setting */
1424da6c28aaSamw }
1425da6c28aaSamw 
1426da6c28aaSamw const char *
1427da6c28aaSamw _umem_logging_init(void)
1428da6c28aaSamw {
1429da6c28aaSamw 	return ("fail,contents"); /* $UMEM_LOGGING setting */
1430da6c28aaSamw }
1431da6c28aaSamw #endif
1432