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