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