Print this page
NEX-15391 smbadm man page needs updating
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-15391 smbadm man page needs updating
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-15041 method to delete local SMB users
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15041 method to delete local SMB users
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
SUP-549 Can't remove the Domain Admin from the local administrators group. (fix copyrights)
SUP-549 Can't remove the Domain Admin from the local administrators group.
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-2667 Wrong error when join domain with wrong password
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-2286 smbadm join error messages are uninformative
NEX-1852 re-enable Kerberos-style AD join (try 2)
SMB-106 Add '-y' flag to 'smbadm join' command
NEX-816 smbadm dumps core during first join attempt
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/smbsrv/smbadm/smbadm.c
+++ new/usr/src/cmd/smbsrv/smbadm/smbadm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * This module contains smbadm CLI which offers smb configuration
28 28 * functionalities.
29 29 */
30 30 #include <errno.h>
31 31 #include <err.h>
32 32 #include <ctype.h>
33 33 #include <stdlib.h>
34 34 #include <unistd.h>
35 35 #include <stdio.h>
36 36 #include <syslog.h>
37 37 #include <strings.h>
38 38 #include <limits.h>
39 39 #include <getopt.h>
40 40 #include <libintl.h>
41 41 #include <zone.h>
42 42 #include <pwd.h>
43 43 #include <grp.h>
44 44 #include <libgen.h>
45 45 #include <netinet/in.h>
46 46 #include <auth_attr.h>
47 47 #include <locale.h>
48 48 #include <smbsrv/libsmb.h>
49 49 #include <smbsrv/libsmbns.h>
50 50
51 51 #if !defined(TEXT_DOMAIN)
52 52 #define TEXT_DOMAIN "SYS_TEST"
53 53 #endif
54 54
55 55 typedef enum {
56 56 HELP_ADD_MEMBER,
57 57 HELP_CREATE,
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
58 58 HELP_DELETE,
59 59 HELP_DEL_MEMBER,
60 60 HELP_GET,
61 61 HELP_JOIN,
62 62 HELP_LIST,
63 63 HELP_LOOKUP,
64 64 HELP_RENAME,
65 65 HELP_SET,
66 66 HELP_SHOW,
67 67 HELP_USER_DISABLE,
68 - HELP_USER_ENABLE
68 + HELP_USER_ENABLE,
69 + HELP_USER_DELETE
69 70 } smbadm_help_t;
70 71
71 72 #define SMBADM_CMDF_NONE 0x00
72 73 #define SMBADM_CMDF_USER 0x01
73 74 #define SMBADM_CMDF_GROUP 0x02
74 75 #define SMBADM_CMDF_TYPEMASK 0x0F
75 76
76 77 typedef enum {
77 78 SMBADM_GRP_ADDMEMBER = 0,
78 79 SMBADM_GRP_DELMEMBER,
79 80 } smbadm_grp_action_t;
80 81
81 82 #define SMBADM_ANSBUFSIZ 64
82 83
83 84 typedef struct smbadm_cmdinfo {
84 85 char *name;
85 86 int (*func)(int, char **);
86 87 smbadm_help_t usage;
87 88 uint32_t flags;
88 89 char *auth;
89 90 } smbadm_cmdinfo_t;
90 91
91 92 smbadm_cmdinfo_t *curcmd;
92 93 static char *progname;
93 94
94 95 #define SMBADM_ACTION_AUTH "solaris.smf.manage.smb"
95 96 #define SMBADM_VALUE_AUTH "solaris.smf.value.smb"
96 97 #define SMBADM_BASIC_AUTH "solaris.network.hosts.read"
97 98
98 99 static boolean_t smbadm_checkauth(const char *);
99 100
100 101 static void smbadm_usage(boolean_t);
101 102 static int smbadm_join_workgroup(const char *, boolean_t);
102 103 static int smbadm_join_domain(const char *, const char *, boolean_t);
103 104 static void smbadm_extract_domain(char *, char **, char **);
104 105
105 106 static int smbadm_join(int, char **);
106 107 static int smbadm_list(int, char **);
107 108 static int smbadm_lookup(int, char **);
108 109 static void smbadm_lookup_name(char *);
109 110 static void smbadm_lookup_sid(char *);
110 111 static int smbadm_group_create(int, char **);
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
111 112 static int smbadm_group_delete(int, char **);
112 113 static int smbadm_group_rename(int, char **);
113 114 static int smbadm_group_show(int, char **);
114 115 static void smbadm_group_show_name(const char *, const char *);
115 116 static int smbadm_group_getprop(int, char **);
116 117 static int smbadm_group_setprop(int, char **);
117 118 static int smbadm_group_addmember(int, char **);
118 119 static int smbadm_group_delmember(int, char **);
119 120 static int smbadm_group_add_del_member(char *, char *, smbadm_grp_action_t);
120 121
122 +static int smbadm_user_delete(int, char **);
121 123 static int smbadm_user_disable(int, char **);
122 124 static int smbadm_user_enable(int, char **);
123 125
126 +/* Please keep the order consistent with smbadm(1M) man page */
124 127 static smbadm_cmdinfo_t smbadm_cmdtable[] =
125 128 {
126 - { "add-member", smbadm_group_addmember, HELP_ADD_MEMBER,
127 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
128 129 { "create", smbadm_group_create, HELP_CREATE,
129 130 SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
130 131 { "delete", smbadm_group_delete, HELP_DELETE,
131 132 SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
133 + { "rename", smbadm_group_rename, HELP_RENAME,
134 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
135 + { "show", smbadm_group_show, HELP_SHOW,
136 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
137 + { "get", smbadm_group_getprop, HELP_GET,
138 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
139 + { "set", smbadm_group_setprop, HELP_SET,
140 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
141 + { "add-member", smbadm_group_addmember, HELP_ADD_MEMBER,
142 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
143 + { "remove-member", smbadm_group_delmember, HELP_DEL_MEMBER,
144 + SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
145 + { "delete-user", smbadm_user_delete, HELP_USER_DELETE,
146 + SMBADM_CMDF_USER, SMBADM_ACTION_AUTH },
132 147 { "disable-user", smbadm_user_disable, HELP_USER_DISABLE,
133 148 SMBADM_CMDF_USER, SMBADM_ACTION_AUTH },
134 149 { "enable-user", smbadm_user_enable, HELP_USER_ENABLE,
135 150 SMBADM_CMDF_USER, SMBADM_ACTION_AUTH },
136 - { "get", smbadm_group_getprop, HELP_GET,
137 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
138 151 { "join", smbadm_join, HELP_JOIN,
139 152 SMBADM_CMDF_NONE, SMBADM_VALUE_AUTH },
140 153 { "list", smbadm_list, HELP_LIST,
141 154 SMBADM_CMDF_NONE, SMBADM_BASIC_AUTH },
142 155 { "lookup", smbadm_lookup, HELP_LOOKUP,
143 156 SMBADM_CMDF_NONE, SMBADM_BASIC_AUTH },
144 - { "remove-member", smbadm_group_delmember, HELP_DEL_MEMBER,
145 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
146 - { "rename", smbadm_group_rename, HELP_RENAME,
147 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
148 - { "set", smbadm_group_setprop, HELP_SET,
149 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
150 - { "show", smbadm_group_show, HELP_SHOW,
151 - SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH },
152 157 };
153 158
154 159 #define SMBADM_NCMD (sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0]))
155 160
156 161 typedef struct smbadm_prop {
157 162 char *p_name;
158 163 char *p_value;
159 164 } smbadm_prop_t;
160 165
161 166 typedef struct smbadm_prop_handle {
162 167 char *p_name;
163 168 char *p_dispvalue;
164 169 int (*p_setfn)(char *, smbadm_prop_t *);
165 170 int (*p_getfn)(char *, smbadm_prop_t *);
166 171 boolean_t (*p_chkfn)(smbadm_prop_t *);
167 172 } smbadm_prop_handle_t;
168 173
169 174 static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval);
170 175 static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop);
171 176 static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname);
172 177
173 178 static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop);
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
174 179 static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop);
175 180 static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop);
176 181 static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop);
177 182 static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop);
178 183 static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop);
179 184 static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop);
180 185 static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop);
181 186 static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop);
182 187
183 188 static smbadm_prop_handle_t smbadm_ptable[] = {
184 - {"backup", "on | off", smbadm_setprop_backup,
189 + {"backup", "on|off", smbadm_setprop_backup,
185 190 smbadm_getprop_backup, smbadm_chkprop_priv },
186 - {"restore", "on | off", smbadm_setprop_restore,
191 + {"restore", "on|off", smbadm_setprop_restore,
187 192 smbadm_getprop_restore, smbadm_chkprop_priv },
188 - {"take-ownership", "on | off", smbadm_setprop_tkowner,
193 + {"take-ownership", "on|off", smbadm_setprop_tkowner,
189 194 smbadm_getprop_tkowner, smbadm_chkprop_priv },
190 195 {"description", "<string>", smbadm_setprop_desc,
191 196 smbadm_getprop_desc, NULL },
192 197 };
193 198
194 199 static int smbadm_init(void);
195 200 static void smbadm_fini(void);
196 201 static const char *smbadm_pwd_strerror(int error);
197 202
198 203 /*
199 204 * Number of supported properties
200 205 */
201 206 #define SMBADM_NPROP (sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0]))
202 207
203 208 static void
204 209 smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd)
205 210 {
206 211 switch (cmd->usage) {
207 212 case HELP_ADD_MEMBER:
208 213 (void) fprintf(fp,
209 - gettext("\t%s -m member [[-m member] ...] group\n"),
214 + gettext("\t%s -m <member> [-m <member>]... <group>\n"),
210 215 cmd->name);
211 216 return;
212 217
213 218 case HELP_CREATE:
214 - (void) fprintf(fp, gettext("\t%s [-d description] group\n"),
219 + (void) fprintf(fp, gettext("\t%s [-d <description>] <group>\n"),
215 220 cmd->name);
216 221 return;
217 222
218 223 case HELP_DELETE:
219 - (void) fprintf(fp, gettext("\t%s group\n"), cmd->name);
224 + (void) fprintf(fp, gettext("\t%s <group>\n"), cmd->name);
220 225 return;
221 226
227 + case HELP_USER_DELETE:
222 228 case HELP_USER_DISABLE:
223 229 case HELP_USER_ENABLE:
224 - (void) fprintf(fp, gettext("\t%s user\n"), cmd->name);
230 + (void) fprintf(fp, gettext("\t%s <username>\n"), cmd->name);
225 231 return;
226 232
227 233 case HELP_GET:
228 - (void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"),
234 + (void) fprintf(fp, gettext("\t%s [-p <property>]... <group>\n"),
229 235 cmd->name);
230 236 return;
231 237
232 238 case HELP_JOIN:
233 -#if 0 /* Don't document "-p" yet, still needs work (NX 11960) */
234 - (void) fprintf(fp, gettext("\t%s [-y] -p domain\n"
235 - "\t%s [-y] -u username domain\n\t%s [-y] -w workgroup\n"),
239 +#if 0 /* Don't document "-p" yet, still needs work (NEX-11960) */
240 + (void) fprintf(fp, gettext("\t%s [-y] -p <domain>\n"
241 + "\t%s [-y] -u <username domain>\n"
242 + "\t%s [-y] -w <workgroup>\n"),
236 243 cmd->name, cmd->name, cmd->name);
237 244 #else
238 - (void) fprintf(fp, gettext("\t%s [-y] -u username domain\n"
239 - "\t%s [-y] -w workgroup\n"), cmd->name, cmd->name);
245 + (void) fprintf(fp, gettext("\t%s [-y] -u <username> <domain>\n"
246 + "\t%s [-y] -w <workgroup>\n"), cmd->name, cmd->name);
240 247 #endif
241 248 return;
242 249
243 250 case HELP_LIST:
244 251 (void) fprintf(fp, gettext("\t%s\n"), cmd->name);
245 - (void) fprintf(fp,
246 - gettext("\t\t[*] primary domain\n"));
247 - (void) fprintf(fp, gettext("\t\t[.] local domain\n"));
248 - (void) fprintf(fp, gettext("\t\t[-] other domains\n"));
249 - (void) fprintf(fp,
250 - gettext("\t\t[+] selected domain controller\n"));
251 252 return;
252 253
253 254 case HELP_LOOKUP:
254 255 (void) fprintf(fp,
255 - gettext("\t%s user-or-group-name\n"),
256 + gettext("\t%s <account-name>\n"),
256 257 cmd->name);
257 258 return;
258 259
259 260 case HELP_DEL_MEMBER:
260 261 (void) fprintf(fp,
261 - gettext("\t%s -m member [[-m member] ...] group\n"),
262 + gettext("\t%s -m <member> [-m <member>]... <group>\n"),
262 263 cmd->name);
263 264 return;
264 265
265 266 case HELP_RENAME:
266 - (void) fprintf(fp, gettext("\t%s group new-group\n"),
267 + (void) fprintf(fp, gettext("\t%s <group> <new-group>\n"),
267 268 cmd->name);
268 269 return;
269 270
270 271 case HELP_SET:
271 - (void) fprintf(fp, gettext("\t%s -p property=value "
272 - "[[-p property=value] ...] group\n"), cmd->name);
272 + (void) fprintf(fp, gettext("\t%s -p <property>=<value> "
273 + "[-p <property>=<value>]... <group>\n"), cmd->name);
273 274 return;
274 275
275 276 case HELP_SHOW:
276 - (void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"),
277 + (void) fprintf(fp, gettext("\t%s [-mp] [<group>]\n"),
277 278 cmd->name);
278 279 return;
279 280
280 281 default:
281 282 break;
282 283 }
283 284
284 285 abort();
285 286 /* NOTREACHED */
286 287 }
287 288
288 289 static void
289 290 smbadm_usage(boolean_t requested)
290 291 {
291 292 FILE *fp = requested ? stdout : stderr;
292 293 boolean_t show_props = B_FALSE;
293 294 int i;
294 295
295 296 if (curcmd == NULL) {
296 297 (void) fprintf(fp,
297 - gettext("usage: %s [-h | <command> [options]]\n"),
298 + gettext("usage: %s <subcommand> <args> ...\n"),
298 299 progname);
299 - (void) fprintf(fp,
300 - gettext("where 'command' is one of the following:\n\n"));
301 300
302 301 for (i = 0; i < SMBADM_NCMD; i++)
303 302 smbadm_cmdusage(fp, &smbadm_cmdtable[i]);
304 303
305 304 (void) fprintf(fp,
306 305 gettext("\nFor property list, run %s %s|%s\n"),
307 306 progname, "get", "set");
308 307
309 308 exit(requested ? 0 : 2);
310 309 }
311 310
312 311 (void) fprintf(fp, gettext("usage:\n"));
313 312 smbadm_cmdusage(fp, curcmd);
314 313
315 314 if (strcmp(curcmd->name, "get") == 0 ||
316 315 strcmp(curcmd->name, "set") == 0)
317 316 show_props = B_TRUE;
318 317
319 318 if (show_props) {
320 319 (void) fprintf(fp,
321 320 gettext("\nThe following properties are supported:\n"));
322 321
323 322 (void) fprintf(fp, "\n\t%-16s %s\n\n",
324 323 "PROPERTY", "VALUES");
325 324
326 325 for (i = 0; i < SMBADM_NPROP; i++) {
327 326 (void) fprintf(fp, "\t%-16s %s\n",
328 327 smbadm_ptable[i].p_name,
329 328 smbadm_ptable[i].p_dispvalue);
330 329 }
331 330 }
332 331
333 332 exit(requested ? 0 : 2);
334 333 }
335 334
336 335 /*
337 336 * smbadm_strcasecmplist
338 337 *
339 338 * Find a string 's' within a list of strings.
340 339 *
341 340 * Returns the index of the matching string or -1 if there is no match.
342 341 */
343 342 static int
344 343 smbadm_strcasecmplist(const char *s, ...)
345 344 {
346 345 va_list ap;
347 346 char *p;
348 347 int ndx;
349 348
350 349 va_start(ap, s);
351 350
352 351 for (ndx = 0; ((p = va_arg(ap, char *)) != NULL); ++ndx) {
353 352 if (strcasecmp(s, p) == 0) {
354 353 va_end(ap);
355 354 return (ndx);
356 355 }
357 356 }
358 357
359 358 va_end(ap);
360 359 return (-1);
361 360 }
362 361
363 362 /*
364 363 * smbadm_answer_prompt
365 364 *
366 365 * Prompt for the answer to a question. A default response must be
367 366 * specified, which will be used if the user presses <enter> without
368 367 * answering the question.
369 368 */
370 369 static int
371 370 smbadm_answer_prompt(const char *prompt, char *answer, const char *dflt)
372 371 {
373 372 char buf[SMBADM_ANSBUFSIZ];
374 373 char *p;
375 374
376 375 (void) printf(gettext("%s [%s]: "), prompt, dflt);
377 376
378 377 if (fgets(buf, SMBADM_ANSBUFSIZ, stdin) == NULL)
379 378 return (-1);
380 379
381 380 if ((p = strchr(buf, '\n')) != NULL)
382 381 *p = '\0';
383 382
384 383 if (*buf == '\0')
385 384 (void) strlcpy(answer, dflt, SMBADM_ANSBUFSIZ);
386 385 else
387 386 (void) strlcpy(answer, buf, SMBADM_ANSBUFSIZ);
388 387
389 388 return (0);
390 389 }
391 390
392 391 /*
393 392 * smbadm_confirm
394 393 *
395 394 * Ask a question that requires a yes/no answer.
396 395 * A default response must be specified.
397 396 */
398 397 static boolean_t
399 398 smbadm_confirm(const char *prompt, const char *dflt)
400 399 {
401 400 char buf[SMBADM_ANSBUFSIZ];
402 401
403 402 for (;;) {
404 403 if (smbadm_answer_prompt(prompt, buf, dflt) < 0)
405 404 return (B_FALSE);
406 405
407 406 if (smbadm_strcasecmplist(buf, "n", "no", 0) >= 0)
408 407 return (B_FALSE);
409 408
410 409 if (smbadm_strcasecmplist(buf, "y", "yes", 0) >= 0)
411 410 return (B_TRUE);
412 411
413 412 (void) printf(gettext("Please answer yes or no.\n"));
414 413 }
415 414 }
416 415
417 416 static boolean_t
418 417 smbadm_join_prompt(const char *domain)
419 418 {
420 419 (void) printf(gettext("After joining %s the smb service will be "
421 420 "restarted automatically.\n"), domain);
422 421
423 422 return (smbadm_confirm("Would you like to continue?", "no"));
424 423 }
425 424
426 425 static void
427 426 smbadm_restart_service(void)
428 427 {
429 428 if (smb_smf_restart_service() != 0) {
430 429 (void) fprintf(stderr,
431 430 gettext("Unable to restart smb service. "
432 431 "Run 'svcs -xv smb/server' for more information."));
433 432 }
434 433 }
435 434
436 435 /*
437 436 * smbadm_join
438 437 *
439 438 * Join a domain or workgroup.
440 439 *
441 440 * When joining a domain, we may receive the username, password and
442 441 * domain name in any of the following combinations. Note that the
443 442 * password is optional on the command line: if it is not provided,
444 443 * we will prompt for it later.
445 444 *
446 445 * username+password domain
447 446 * domain\username+password
448 447 * domain/username+password
449 448 * username@domain
450 449 *
451 450 * We allow domain\name+password or domain/name+password but not
452 451 * name+password@domain because @ is a valid password character.
453 452 *
454 453 * If the username and domain name are passed as separate command
455 454 * line arguments, we process them directly. Otherwise we separate
456 455 * them and continue as if they were separate command line arguments.
457 456 */
458 457 static int
459 458 smbadm_join(int argc, char **argv)
460 459 {
461 460 char buf[MAXHOSTNAMELEN * 2];
462 461 char *domain = NULL;
463 462 char *username = NULL;
464 463 uint32_t mode = 0;
465 464 boolean_t do_prompt = B_TRUE;
466 465 char option;
467 466
468 467 while ((option = getopt(argc, argv, "pu:wy")) != -1) {
469 468 if (mode != 0) {
470 469 (void) fprintf(stderr, gettext(
471 470 "join options are mutually exclusive\n"));
472 471 smbadm_usage(B_FALSE);
473 472 }
474 473 switch (option) {
475 474 case 'p':
476 475 mode = SMB_SECMODE_DOMAIN;
477 476 /* leave username = NULL */
478 477 break;
479 478
480 479 case 'u':
481 480 mode = SMB_SECMODE_DOMAIN;
482 481 username = optarg;
483 482 break;
484 483
485 484 case 'w':
486 485 mode = SMB_SECMODE_WORKGRP;
487 486 break;
488 487
489 488 case 'y':
490 489 do_prompt = B_FALSE;
491 490 break;
492 491
493 492 default:
494 493 smbadm_usage(B_FALSE);
495 494 break;
496 495 }
497 496 }
498 497
499 498 if (optind < argc)
500 499 domain = argv[optind];
501 500
502 501 if (username != NULL && domain == NULL) {
503 502 /*
504 503 * The domain was not specified as a separate
505 504 * argument, check for the combination forms.
506 505 */
507 506 (void) strlcpy(buf, username, sizeof (buf));
508 507 smbadm_extract_domain(buf, &username, &domain);
509 508 }
510 509
511 510 if ((domain == NULL) || (*domain == '\0')) {
512 511 (void) fprintf(stderr, gettext("missing %s name\n"),
513 512 (mode == SMB_SECMODE_WORKGRP) ? "workgroup" : "domain");
514 513 smbadm_usage(B_FALSE);
515 514 }
516 515
517 516 if (mode == SMB_SECMODE_WORKGRP) {
518 517 return (smbadm_join_workgroup(domain, do_prompt));
519 518 }
520 519 return (smbadm_join_domain(domain, username, do_prompt));
521 520 }
522 521
523 522 /*
524 523 * Workgroups comprise a collection of standalone, independently administered
525 524 * computers that use a common workgroup name. This is a peer-to-peer model
526 525 * with no formal membership mechanism.
527 526 */
528 527 static int
529 528 smbadm_join_workgroup(const char *workgroup, boolean_t prompt)
530 529 {
531 530 smb_joininfo_t jdi;
532 531 smb_joinres_t jdres;
533 532 uint32_t status;
534 533
535 534 bzero(&jdres, sizeof (jdres));
536 535 bzero(&jdi, sizeof (jdi));
537 536 jdi.mode = SMB_SECMODE_WORKGRP;
538 537 (void) strlcpy(jdi.domain_name, workgroup, sizeof (jdi.domain_name));
539 538 (void) strtrim(jdi.domain_name, " \t\n");
540 539
541 540 if (smb_name_validate_workgroup(jdi.domain_name) != ERROR_SUCCESS) {
542 541 (void) fprintf(stderr, gettext("workgroup name is invalid\n"));
543 542 smbadm_usage(B_FALSE);
544 543 }
545 544
546 545 if (prompt && !smbadm_join_prompt(jdi.domain_name))
547 546 return (0);
548 547
549 548 if ((status = smb_join(&jdi, &jdres)) != NT_STATUS_SUCCESS) {
550 549 (void) fprintf(stderr, gettext("failed to join %s: %s\n"),
551 550 jdi.domain_name, xlate_nt_status(status));
552 551 return (1);
553 552 }
554 553
555 554 (void) printf(gettext("Successfully joined %s\n"), jdi.domain_name);
556 555 smbadm_restart_service();
557 556 return (0);
558 557 }
559 558
560 559 /*
561 560 * Domains comprise a centrally administered group of computers and accounts
562 561 * that share a common security and administration policy and database.
563 562 * Computers must join a domain and become domain members, which requires
564 563 * an administrator level account name.
565 564 *
566 565 * The '+' character is invalid within a username. We allow the password
567 566 * to be appended to the username using '+' as a scripting convenience.
568 567 */
569 568 static int
570 569 smbadm_join_domain(const char *domain, const char *username, boolean_t prompt)
571 570 {
572 571 smb_joininfo_t jdi;
573 572 smb_joinres_t jdres;
574 573 char *passwd_prompt;
575 574 char *p;
576 575 int len, rc;
577 576
578 577 bzero(&jdres, sizeof (jdres));
579 578 bzero(&jdi, sizeof (jdi));
580 579 jdi.mode = SMB_SECMODE_DOMAIN;
581 580 (void) strlcpy(jdi.domain_name, domain, sizeof (jdi.domain_name));
582 581 (void) strtrim(jdi.domain_name, " \t\n");
583 582
584 583 if (smb_name_validate_domain(jdi.domain_name) != ERROR_SUCCESS) {
585 584 (void) fprintf(stderr, gettext("domain name is invalid\n"));
586 585 smbadm_usage(B_FALSE);
587 586 }
588 587
589 588 if (prompt && !smbadm_join_prompt(jdi.domain_name))
590 589 return (0);
591 590
592 591 /*
593 592 * Note: username is null for "unsecure join"
594 593 * (join using a pre-created computer account)
595 594 * No password either.
596 595 */
597 596 if (username != NULL) {
598 597 if ((p = strchr(username, '+')) != NULL) {
599 598 ++p;
600 599
601 600 len = (int)(p - username);
602 601 if (len > sizeof (jdi.domain_name))
603 602 len = sizeof (jdi.domain_name);
604 603
605 604 (void) strlcpy(jdi.domain_username, username, len);
606 605 (void) strlcpy(jdi.domain_passwd, p,
607 606 sizeof (jdi.domain_passwd));
608 607 } else {
609 608 (void) strlcpy(jdi.domain_username, username,
610 609 sizeof (jdi.domain_username));
611 610 }
612 611
613 612 if (smb_name_validate_account(jdi.domain_username)
614 613 != ERROR_SUCCESS) {
615 614 (void) fprintf(stderr,
616 615 gettext("username contains invalid characters\n"));
617 616 smbadm_usage(B_FALSE);
618 617 }
619 618
620 619 if (*jdi.domain_passwd == '\0') {
621 620 passwd_prompt = gettext("Enter domain password: ");
622 621
623 622 if ((p = getpassphrase(passwd_prompt)) == NULL) {
624 623 (void) fprintf(stderr, gettext(
625 624 "missing password\n"));
626 625 smbadm_usage(B_FALSE);
627 626 }
628 627
629 628 (void) strlcpy(jdi.domain_passwd, p,
630 629 sizeof (jdi.domain_passwd));
631 630 }
632 631 }
633 632
634 633 (void) printf(gettext("Joining %s ... this may take a minute ...\n"),
635 634 jdi.domain_name);
636 635
637 636 rc = smb_join(&jdi, &jdres);
638 637 if (rc != 0) {
639 638 (void) printf(gettext("Cannot call the SMB service. "
640 639 " (error %d: %s) "
641 640 "Please check the service status "
642 641 "(svcs -vx network/smb/server)\n"),
643 642 rc, strerror(rc));
644 643 bzero(&jdi, sizeof (jdi));
645 644 return (1);
646 645 }
647 646
648 647 switch (jdres.status) {
649 648 case NT_STATUS_SUCCESS:
650 649 (void) printf(gettext(
651 650 "Successfully joined domain %s using AD server %s\n"),
652 651 jdi.domain_name, jdres.dc_name);
653 652 bzero(&jdi, sizeof (jdi));
654 653 smbadm_restart_service();
655 654 return (0);
656 655
657 656 case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
658 657 /* See: smb_ads_lookup_msdcs */
659 658 (void) fprintf(stderr, gettext(
660 659 "failed to find any AD servers for domain: %s\n"),
661 660 jdi.domain_name);
662 661 goto common;
663 662
664 663 case NT_STATUS_BAD_NETWORK_PATH:
665 664 /* See: smbrdr_ctx_new / smb_ctx_resolve */
666 665 (void) fprintf(stderr, gettext(
667 666 "failed to resolve address of AD server: %s\n"),
668 667 jdres.dc_name);
669 668 goto common;
670 669
671 670 case NT_STATUS_NETWORK_ACCESS_DENIED:
672 671 /* See: smbrdr_ctx_new / smb_ctx_get_ssn */
673 672 (void) fprintf(stderr, gettext(
674 673 "failed to authenticate with AD server: %s\n"),
675 674 jdres.dc_name);
676 675 goto common;
677 676
678 677 case NT_STATUS_BAD_NETWORK_NAME:
679 678 /*
680 679 * See: smbrdr_ctx_new / smb_ctx_get_tree
681 680 * and: ndr_rpc_bind / smb_fh_open
682 681 */
683 682 (void) fprintf(stderr, gettext(
684 683 "failed connecting to services on AD server: %s\n"),
685 684 jdres.dc_name);
686 685 goto common;
687 686
688 687 default:
689 688 (void) fprintf(stderr, gettext(
690 689 "failed to join domain %s\n"),
691 690 jdi.domain_name);
692 691 if (jdres.dc_name[0] != '\0') {
693 692 (void) fprintf(stderr, gettext(
694 693 "using AD server: %s\n"),
695 694 jdres.dc_name);
696 695 }
697 696 /* FALLTHROUGH */
698 697 common:
699 698 if (jdres.join_err != 0) {
700 699 (void) fprintf(stderr, "%s\n",
701 700 smb_ads_strerror(jdres.join_err));
702 701 } else if (jdres.status != 0) {
703 702 (void) fprintf(stderr, "(%s)\n",
704 703 xlate_nt_status(jdres.status));
705 704 }
706 705 (void) fprintf(stderr, gettext("Please refer to the "
707 706 "service log for more information.\n"));
708 707 bzero(&jdi, sizeof (jdi));
709 708 return (1);
710 709 }
711 710 }
712 711
713 712 /*
714 713 * We want to process the user and domain names as separate strings.
715 714 * Check for names of the forms below and separate the components as
716 715 * required.
717 716 *
718 717 * name@domain
719 718 * domain\name
720 719 * domain/name
721 720 *
722 721 * If we encounter any of the forms above in arg, the @, / or \
723 722 * separator is replaced by \0 and the username and domain pointers
724 723 * are changed to point to the appropriate components (in arg).
725 724 *
726 725 * If none of the separators are encountered, the username and domain
727 726 * pointers remain unchanged.
728 727 */
729 728 static void
730 729 smbadm_extract_domain(char *arg, char **username, char **domain)
731 730 {
732 731 char *p;
733 732
734 733 if ((p = strpbrk(arg, "/\\@")) != NULL) {
735 734 if (*p == '@') {
736 735 *p = '\0';
737 736 ++p;
738 737
739 738 if (strchr(arg, '+') != NULL)
740 739 return;
741 740
742 741 *domain = p;
743 742 *username = arg;
744 743 } else {
745 744 *p = '\0';
746 745 ++p;
747 746 *username = p;
748 747 *domain = arg;
749 748 }
750 749 }
751 750 }
752 751
753 752 /*
754 753 * smbadm_list
755 754 *
756 755 * Displays current security mode and domain/workgroup name.
757 756 */
758 757 /*ARGSUSED*/
759 758 static int
760 759 smbadm_list(int argc, char **argv)
761 760 {
762 761 char domain[MAXHOSTNAMELEN];
763 762 char fqdn[MAXHOSTNAMELEN];
764 763 char srvname[MAXHOSTNAMELEN];
765 764 char modename[16];
766 765 int rc;
767 766 smb_inaddr_t srvipaddr;
768 767 char ipstr[INET6_ADDRSTRLEN];
769 768
770 769 rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename));
771 770 if (rc != SMBD_SMF_OK) {
772 771 (void) fprintf(stderr,
773 772 gettext("cannot determine the operational mode\n"));
774 773 return (1);
775 774 }
776 775
777 776 if (smb_getdomainname(domain, sizeof (domain)) != 0) {
778 777 (void) fprintf(stderr, gettext("failed to get the %s name\n"),
779 778 modename);
780 779 return (1);
781 780 }
782 781
783 782 if (strcmp(modename, "workgroup") == 0) {
784 783 (void) printf(gettext("[*] [%s]\n"), domain);
785 784 return (0);
786 785 }
787 786
788 787 (void) printf(gettext("[*] [%s]\n"), domain);
789 788 if ((smb_getfqdomainname(fqdn, sizeof (fqdn)) == 0) && (*fqdn != '\0'))
790 789 (void) printf(gettext("[*] [%s]\n"), fqdn);
791 790
792 791 if ((smb_get_dcinfo(srvname, MAXHOSTNAMELEN, &srvipaddr)
793 792 == NT_STATUS_SUCCESS) && (*srvname != '\0') &&
794 793 (!smb_inet_iszero(&srvipaddr))) {
795 794 (void) smb_inet_ntop(&srvipaddr, ipstr,
796 795 SMB_IPSTRLEN(srvipaddr.a_family));
797 796 (void) printf(gettext("\t[+%s] [%s]\n"),
798 797 srvname, ipstr);
799 798 }
800 799
801 800 /* Print the local and domain SID. */
802 801 smb_domain_show();
803 802 return (0);
804 803 }
805 804
806 805 /*
807 806 * smbadm_lookup
808 807 *
809 808 * Lookup the SID for a given account (user or group)
810 809 */
811 810 static int
812 811 smbadm_lookup(int argc, char **argv)
813 812 {
814 813 int i;
815 814
816 815 if (argc < 2) {
817 816 (void) fprintf(stderr, gettext("missing account name\n"));
818 817 smbadm_usage(B_FALSE);
819 818 }
820 819
821 820 for (i = 1; i < argc; i++) {
822 821 if (strncmp(argv[i], "S-1-", 4) == 0)
823 822 smbadm_lookup_sid(argv[i]);
824 823 else
825 824 smbadm_lookup_name(argv[i]);
826 825 }
827 826 return (0);
828 827 }
829 828
830 829 static void
831 830 smbadm_lookup_name(char *name)
832 831 {
833 832 lsa_account_t acct;
834 833 int rc;
835 834
836 835 if ((rc = smb_lookup_name(name, SidTypeUnknown, &acct)) != 0) {
837 836 (void) fprintf(stderr, gettext(
838 837 "\t\t%s: lookup name failed, rc=%d\n"),
839 838 name, rc);
840 839 return;
841 840 }
842 841 if (acct.a_status != NT_STATUS_SUCCESS) {
843 842 (void) fprintf(stderr, gettext("\t\t%s [%s]\n"),
844 843 name, xlate_nt_status(acct.a_status));
845 844 return;
846 845 }
847 846 (void) printf("\t%s\n", acct.a_sid);
848 847 }
849 848
850 849 static void
851 850 smbadm_lookup_sid(char *sidstr)
852 851 {
853 852 lsa_account_t acct;
854 853 int rc;
855 854
856 855 if ((rc = smb_lookup_sid(sidstr, &acct)) != 0) {
857 856 (void) fprintf(stderr, gettext(
858 857 "\t\t%s: lookup SID failed, rc=%d\n"),
859 858 sidstr, rc);
860 859 return;
861 860 }
862 861 if (acct.a_status != NT_STATUS_SUCCESS) {
863 862 (void) fprintf(stderr, gettext("\t\t%s [%s]\n"),
864 863 sidstr, xlate_nt_status(acct.a_status));
865 864 return;
866 865 }
867 866 (void) printf("\t%s\\%s\n", acct.a_domain, acct.a_name);
868 867 }
869 868
870 869 /*
871 870 * smbadm_group_create
872 871 *
873 872 * Creates a local SMB group
874 873 */
875 874 static int
876 875 smbadm_group_create(int argc, char **argv)
877 876 {
878 877 char *gname = NULL;
879 878 char *desc = NULL;
880 879 char option;
881 880 int status;
882 881
883 882 while ((option = getopt(argc, argv, "d:")) != -1) {
884 883 switch (option) {
885 884 case 'd':
886 885 desc = optarg;
887 886 break;
888 887
889 888 default:
890 889 smbadm_usage(B_FALSE);
891 890 }
892 891 }
893 892
894 893 gname = argv[optind];
895 894 if (optind >= argc || gname == NULL || *gname == '\0') {
896 895 (void) fprintf(stderr, gettext("missing group name\n"));
897 896 smbadm_usage(B_FALSE);
898 897 }
899 898
900 899 status = smb_lgrp_add(gname, desc);
901 900 if (status != SMB_LGRP_SUCCESS) {
902 901 (void) fprintf(stderr,
903 902 gettext("failed to create %s (%s)\n"), gname,
904 903 smb_lgrp_strerror(status));
905 904 } else {
906 905 (void) printf(gettext("%s created\n"), gname);
907 906 }
908 907
909 908 return (status);
910 909 }
911 910
912 911 /*
913 912 * smbadm_group_dump_members
914 913 *
915 914 * Dump group members details.
916 915 */
917 916 static void
918 917 smbadm_group_dump_members(smb_gsid_t *members, int num)
919 918 {
920 919 char sidstr[SMB_SID_STRSZ];
921 920 lsa_account_t acct;
922 921 int i;
923 922
924 923 if (num == 0) {
925 924 (void) printf(gettext("\tNo members\n"));
926 925 return;
927 926 }
928 927
929 928 (void) printf(gettext("\tMembers:\n"));
930 929 for (i = 0; i < num; i++) {
931 930 smb_sid_tostr(members[i].gs_sid, sidstr);
932 931
933 932 if (smb_lookup_sid(sidstr, &acct) == 0) {
934 933 if (acct.a_status == NT_STATUS_SUCCESS)
935 934 smbadm_group_show_name(acct.a_domain,
936 935 acct.a_name);
937 936 else
938 937 (void) printf(gettext("\t\t%s [%s]\n"),
939 938 sidstr, xlate_nt_status(acct.a_status));
940 939 } else {
941 940 (void) printf(gettext("\t\t%s\n"), sidstr);
942 941 }
943 942 }
944 943 }
945 944
946 945 static void
947 946 smbadm_group_show_name(const char *domain, const char *name)
948 947 {
949 948 if (strchr(domain, '.') != NULL)
950 949 (void) printf("\t\t%s@%s\n", name, domain);
951 950 else
952 951 (void) printf("\t\t%s\\%s\n", domain, name);
953 952 }
954 953
955 954 /*
956 955 * smbadm_group_dump_privs
957 956 *
958 957 * Dump group privilege details.
959 958 */
960 959 static void
961 960 smbadm_group_dump_privs(smb_privset_t *privs)
962 961 {
963 962 smb_privinfo_t *pinfo;
964 963 char *pstatus;
965 964 int i;
966 965
967 966 (void) printf(gettext("\tPrivileges: \n"));
968 967
969 968 for (i = 0; i < privs->priv_cnt; i++) {
970 969 pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part);
971 970 if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0)
972 971 continue;
973 972
974 973 switch (privs->priv[i].attrs) {
975 974 case SE_PRIVILEGE_ENABLED:
976 975 pstatus = "On";
977 976 break;
978 977 case SE_PRIVILEGE_DISABLED:
979 978 pstatus = "Off";
980 979 break;
981 980 default:
982 981 pstatus = "Unknown";
983 982 break;
984 983 }
985 984 (void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus);
986 985 }
987 986
988 987 if (privs->priv_cnt == 0)
989 988 (void) printf(gettext("\t\tNo privileges\n"));
990 989 }
991 990
992 991 /*
993 992 * smbadm_group_dump
994 993 *
995 994 * Dump group details.
996 995 */
997 996 static void
998 997 smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
999 998 {
1000 999 char sidstr[SMB_SID_STRSZ];
1001 1000
1002 1001 (void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);
1003 1002
1004 1003 smb_sid_tostr(grp->sg_id.gs_sid, sidstr);
1005 1004 (void) printf(gettext("\tSID: %s\n"), sidstr);
1006 1005
1007 1006 if (show_privs)
1008 1007 smbadm_group_dump_privs(grp->sg_privs);
1009 1008
1010 1009 if (show_mem)
1011 1010 smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers);
1012 1011 }
1013 1012
1014 1013 /*
1015 1014 * smbadm_group_show
1016 1015 *
1017 1016 */
1018 1017 static int
1019 1018 smbadm_group_show(int argc, char **argv)
1020 1019 {
1021 1020 char *gname = NULL;
1022 1021 boolean_t show_privs;
1023 1022 boolean_t show_members;
1024 1023 char option;
1025 1024 int status;
1026 1025 smb_group_t grp;
1027 1026 smb_giter_t gi;
1028 1027
1029 1028 show_privs = show_members = B_FALSE;
1030 1029
1031 1030 while ((option = getopt(argc, argv, "mp")) != -1) {
1032 1031 switch (option) {
1033 1032 case 'm':
1034 1033 show_members = B_TRUE;
1035 1034 break;
1036 1035 case 'p':
1037 1036 show_privs = B_TRUE;
1038 1037 break;
1039 1038
1040 1039 default:
1041 1040 smbadm_usage(B_FALSE);
1042 1041 }
1043 1042 }
1044 1043
1045 1044 gname = argv[optind];
1046 1045 if (optind >= argc || gname == NULL || *gname == '\0')
1047 1046 gname = "*";
1048 1047
1049 1048 if (strcmp(gname, "*")) {
1050 1049 status = smb_lgrp_getbyname(gname, &grp);
1051 1050 if (status == SMB_LGRP_SUCCESS) {
1052 1051 smbadm_group_dump(&grp, show_members, show_privs);
1053 1052 smb_lgrp_free(&grp);
1054 1053 } else {
1055 1054 (void) fprintf(stderr,
1056 1055 gettext("failed to find %s (%s)\n"),
1057 1056 gname, smb_lgrp_strerror(status));
1058 1057 }
1059 1058 return (status);
1060 1059 }
1061 1060
1062 1061 if ((status = smb_lgrp_iteropen(&gi)) != SMB_LGRP_SUCCESS) {
1063 1062 (void) fprintf(stderr, gettext("failed to list groups (%s)\n"),
1064 1063 smb_lgrp_strerror(status));
1065 1064 return (status);
1066 1065 }
1067 1066
1068 1067 while ((status = smb_lgrp_iterate(&gi, &grp)) == SMB_LGRP_SUCCESS) {
1069 1068 smbadm_group_dump(&grp, show_members, show_privs);
1070 1069 smb_lgrp_free(&grp);
1071 1070 }
1072 1071
1073 1072 smb_lgrp_iterclose(&gi);
1074 1073
1075 1074 if ((status != SMB_LGRP_NO_MORE) || smb_lgrp_itererror(&gi)) {
1076 1075 if (status != SMB_LGRP_NO_MORE)
1077 1076 smb_syslog(LOG_ERR, "smb_lgrp_iterate: %s",
1078 1077 smb_lgrp_strerror(status));
1079 1078
1080 1079 (void) fprintf(stderr,
1081 1080 gettext("\nAn error occurred while retrieving group data.\n"
1082 1081 "Check the system log for more information.\n"));
1083 1082 return (status);
1084 1083 }
1085 1084
1086 1085 return (0);
1087 1086 }
1088 1087
1089 1088 /*
1090 1089 * smbadm_group_delete
1091 1090 */
1092 1091 static int
1093 1092 smbadm_group_delete(int argc, char **argv)
1094 1093 {
1095 1094 char *gname = NULL;
1096 1095 int status;
1097 1096
1098 1097 gname = argv[optind];
1099 1098 if (optind >= argc || gname == NULL || *gname == '\0') {
1100 1099 (void) fprintf(stderr, gettext("missing group name\n"));
1101 1100 smbadm_usage(B_FALSE);
1102 1101 }
1103 1102
1104 1103 status = smb_lgrp_delete(gname);
1105 1104 if (status != SMB_LGRP_SUCCESS) {
1106 1105 (void) fprintf(stderr,
1107 1106 gettext("failed to delete %s (%s)\n"), gname,
1108 1107 smb_lgrp_strerror(status));
1109 1108 } else {
1110 1109 (void) printf(gettext("%s deleted\n"), gname);
1111 1110 }
1112 1111
1113 1112 return (status);
1114 1113 }
1115 1114
1116 1115 /*
1117 1116 * smbadm_group_rename
1118 1117 */
1119 1118 static int
1120 1119 smbadm_group_rename(int argc, char **argv)
1121 1120 {
1122 1121 char *gname = NULL;
1123 1122 char *ngname = NULL;
1124 1123 int status;
1125 1124
1126 1125 gname = argv[optind];
1127 1126 if (optind++ >= argc || gname == NULL || *gname == '\0') {
1128 1127 (void) fprintf(stderr, gettext("missing group name\n"));
1129 1128 smbadm_usage(B_FALSE);
1130 1129 }
1131 1130
1132 1131 ngname = argv[optind];
1133 1132 if (optind >= argc || ngname == NULL || *ngname == '\0') {
1134 1133 (void) fprintf(stderr, gettext("missing new group name\n"));
1135 1134 smbadm_usage(B_FALSE);
1136 1135 }
1137 1136
1138 1137 status = smb_lgrp_rename(gname, ngname);
1139 1138 if (status != SMB_LGRP_SUCCESS) {
1140 1139 if (status == SMB_LGRP_EXISTS)
1141 1140 (void) fprintf(stderr,
1142 1141 gettext("failed to rename '%s' (%s already "
1143 1142 "exists)\n"), gname, ngname);
1144 1143 else
1145 1144 (void) fprintf(stderr,
1146 1145 gettext("failed to rename '%s' (%s)\n"), gname,
1147 1146 smb_lgrp_strerror(status));
1148 1147 } else {
1149 1148 (void) printf(gettext("'%s' renamed to '%s'\n"), gname, ngname);
1150 1149 }
1151 1150
1152 1151 return (status);
1153 1152 }
1154 1153
1155 1154 /*
1156 1155 * smbadm_group_setprop
1157 1156 *
1158 1157 * Set the group properties.
1159 1158 */
1160 1159 static int
1161 1160 smbadm_group_setprop(int argc, char **argv)
1162 1161 {
1163 1162 char *gname = NULL;
1164 1163 smbadm_prop_t props[SMBADM_NPROP];
1165 1164 smbadm_prop_handle_t *phandle;
1166 1165 char option;
1167 1166 int pcnt = 0;
1168 1167 int ret;
1169 1168 int p;
1170 1169
1171 1170 bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t));
1172 1171
1173 1172 while ((option = getopt(argc, argv, "p:")) != -1) {
1174 1173 switch (option) {
1175 1174 case 'p':
1176 1175 if (pcnt >= SMBADM_NPROP) {
1177 1176 (void) fprintf(stderr,
1178 1177 gettext("exceeded number of supported"
1179 1178 " properties\n"));
1180 1179 smbadm_usage(B_FALSE);
1181 1180 }
1182 1181
1183 1182 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
1184 1183 smbadm_usage(B_FALSE);
1185 1184 break;
1186 1185
1187 1186 default:
1188 1187 smbadm_usage(B_FALSE);
1189 1188 }
1190 1189 }
1191 1190
1192 1191 if (pcnt == 0) {
1193 1192 (void) fprintf(stderr,
1194 1193 gettext("missing property=value argument\n"));
1195 1194 smbadm_usage(B_FALSE);
1196 1195 }
1197 1196
1198 1197 gname = argv[optind];
1199 1198 if (optind >= argc || gname == NULL || *gname == '\0') {
1200 1199 (void) fprintf(stderr, gettext("missing group name\n"));
1201 1200 smbadm_usage(B_FALSE);
1202 1201 }
1203 1202
1204 1203 for (p = 0; p < pcnt; p++) {
1205 1204 phandle = smbadm_prop_gethandle(props[p].p_name);
1206 1205 if (phandle) {
1207 1206 if (phandle->p_setfn(gname, &props[p]) != 0)
1208 1207 ret = 1;
1209 1208 }
1210 1209 }
1211 1210
1212 1211 return (ret);
1213 1212 }
1214 1213
1215 1214 /*
1216 1215 * smbadm_group_getprop
1217 1216 *
1218 1217 * Get the group properties.
1219 1218 */
1220 1219 static int
1221 1220 smbadm_group_getprop(int argc, char **argv)
1222 1221 {
1223 1222 char *gname = NULL;
1224 1223 smbadm_prop_t props[SMBADM_NPROP];
1225 1224 smbadm_prop_handle_t *phandle;
1226 1225 char option;
1227 1226 int pcnt = 0;
1228 1227 int ret;
1229 1228 int p;
1230 1229
1231 1230 bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t));
1232 1231
1233 1232 while ((option = getopt(argc, argv, "p:")) != -1) {
1234 1233 switch (option) {
1235 1234 case 'p':
1236 1235 if (pcnt >= SMBADM_NPROP) {
1237 1236 (void) fprintf(stderr,
1238 1237 gettext("exceeded number of supported"
1239 1238 " properties\n"));
1240 1239 smbadm_usage(B_FALSE);
1241 1240 }
1242 1241
1243 1242 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
1244 1243 smbadm_usage(B_FALSE);
1245 1244 break;
1246 1245
1247 1246 default:
1248 1247 smbadm_usage(B_FALSE);
1249 1248 }
1250 1249 }
1251 1250
1252 1251 gname = argv[optind];
1253 1252 if (optind >= argc || gname == NULL || *gname == '\0') {
1254 1253 (void) fprintf(stderr, gettext("missing group name\n"));
1255 1254 smbadm_usage(B_FALSE);
1256 1255 }
1257 1256
1258 1257 if (pcnt == 0) {
1259 1258 /*
1260 1259 * If no property has be specified then get
1261 1260 * all the properties.
1262 1261 */
1263 1262 pcnt = SMBADM_NPROP;
1264 1263 for (p = 0; p < pcnt; p++)
1265 1264 props[p].p_name = smbadm_ptable[p].p_name;
1266 1265 }
1267 1266
1268 1267 for (p = 0; p < pcnt; p++) {
1269 1268 phandle = smbadm_prop_gethandle(props[p].p_name);
1270 1269 if (phandle) {
1271 1270 if (phandle->p_getfn(gname, &props[p]) != 0)
1272 1271 ret = 1;
1273 1272 }
1274 1273 }
1275 1274
1276 1275 return (ret);
1277 1276 }
1278 1277
1279 1278 /*
1280 1279 * smbadm_group_addmember
1281 1280 *
1282 1281 */
1283 1282 static int
1284 1283 smbadm_group_addmember(int argc, char **argv)
1285 1284 {
1286 1285 char *gname = NULL;
1287 1286 char **mname;
1288 1287 char option;
1289 1288 int mcnt = 0;
1290 1289 int ret = 0;
1291 1290 int i;
1292 1291
1293 1292
1294 1293 mname = (char **)malloc(argc * sizeof (char *));
1295 1294 if (mname == NULL) {
1296 1295 warn(gettext("failed to add group member"));
1297 1296 return (1);
1298 1297 }
1299 1298 bzero(mname, argc * sizeof (char *));
1300 1299
1301 1300 while ((option = getopt(argc, argv, "m:")) != -1) {
1302 1301 switch (option) {
1303 1302 case 'm':
1304 1303 mname[mcnt++] = optarg;
1305 1304 break;
1306 1305
1307 1306 default:
1308 1307 free(mname);
1309 1308 smbadm_usage(B_FALSE);
1310 1309 }
1311 1310 }
1312 1311
1313 1312 if (mcnt == 0) {
1314 1313 (void) fprintf(stderr, gettext("missing member name\n"));
1315 1314 free(mname);
1316 1315 smbadm_usage(B_FALSE);
1317 1316 }
1318 1317
1319 1318 gname = argv[optind];
1320 1319 if (optind >= argc || gname == NULL || *gname == 0) {
1321 1320 (void) fprintf(stderr, gettext("missing group name\n"));
1322 1321 free(mname);
1323 1322 smbadm_usage(B_FALSE);
1324 1323 }
1325 1324
1326 1325 for (i = 0; i < mcnt; i++) {
1327 1326 if (mname[i] == NULL)
1328 1327 continue;
1329 1328 ret |= smbadm_group_add_del_member(
1330 1329 gname, mname[i], SMBADM_GRP_ADDMEMBER);
1331 1330 }
1332 1331
1333 1332 free(mname);
1334 1333 return (ret);
1335 1334 }
1336 1335
1337 1336 /*
1338 1337 * smbadm_group_delmember
1339 1338 */
1340 1339 static int
1341 1340 smbadm_group_delmember(int argc, char **argv)
1342 1341 {
1343 1342 char *gname = NULL;
1344 1343 char **mname;
1345 1344 char option;
1346 1345 int mcnt = 0;
1347 1346 int ret = 0;
1348 1347 int i;
1349 1348
1350 1349 mname = (char **)malloc(argc * sizeof (char *));
1351 1350 if (mname == NULL) {
1352 1351 warn(gettext("failed to delete group member"));
1353 1352 return (1);
1354 1353 }
1355 1354 bzero(mname, argc * sizeof (char *));
1356 1355
1357 1356 while ((option = getopt(argc, argv, "m:")) != -1) {
1358 1357 switch (option) {
1359 1358 case 'm':
1360 1359 mname[mcnt++] = optarg;
1361 1360 break;
1362 1361
1363 1362 default:
1364 1363 free(mname);
1365 1364 smbadm_usage(B_FALSE);
1366 1365 }
1367 1366 }
1368 1367
1369 1368 if (mcnt == 0) {
1370 1369 (void) fprintf(stderr, gettext("missing member name\n"));
1371 1370 free(mname);
1372 1371 smbadm_usage(B_FALSE);
1373 1372 }
1374 1373
1375 1374 gname = argv[optind];
1376 1375 if (optind >= argc || gname == NULL || *gname == 0) {
1377 1376 (void) fprintf(stderr, gettext("missing group name\n"));
1378 1377 free(mname);
1379 1378 smbadm_usage(B_FALSE);
1380 1379 }
1381 1380
1382 1381
1383 1382 for (i = 0; i < mcnt; i++) {
1384 1383 ret = 0;
1385 1384 if (mname[i] == NULL)
1386 1385 continue;
|
↓ open down ↓ |
1076 lines elided |
↑ open up ↑ |
1387 1386 ret |= smbadm_group_add_del_member(
1388 1387 gname, mname[i], SMBADM_GRP_DELMEMBER);
1389 1388 }
1390 1389
1391 1390 free(mname);
1392 1391 return (ret);
1393 1392 }
1394 1393
1395 1394 static int
1396 1395 smbadm_group_add_del_member(char *gname, char *mname,
1397 - smbadm_grp_action_t act)
1396 + smbadm_grp_action_t act)
1398 1397 {
1399 1398 lsa_account_t acct;
1400 1399 smb_gsid_t msid;
1401 1400 char *sidstr;
1402 1401 char *act_str;
1403 1402 int rc;
1404 1403
1405 1404 if (strncmp(mname, "S-1-", 4) == 0) {
1406 1405 /*
1407 1406 * We are given a SID. Just use it.
1408 1407 *
1409 1408 * We'e like the real account type if we can get it,
1410 1409 * but don't want to error out if we can't get it.
1410 + * Lacking other info, assume it's a group.
1411 1411 */
1412 1412 sidstr = mname;
1413 1413 rc = smb_lookup_sid(sidstr, &acct);
1414 1414 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS))
1415 - acct.a_sidtype = SidTypeUnknown;
1415 + acct.a_sidtype = SidTypeGroup;
1416 1416 } else {
1417 1417 rc = smb_lookup_name(mname, SidTypeUnknown, &acct);
1418 1418 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS)) {
1419 1419 (void) fprintf(stderr,
1420 1420 gettext("%s: name lookup failed\n"), mname);
1421 1421 return (1);
1422 1422 }
1423 1423 sidstr = acct.a_sid;
1424 1424 }
1425 1425
1426 1426 msid.gs_type = acct.a_sidtype;
1427 1427 if ((msid.gs_sid = smb_sid_fromstr(sidstr)) == NULL) {
1428 1428 (void) fprintf(stderr,
1429 1429 gettext("%s: no memory for SID\n"), sidstr);
1430 1430 return (1);
1431 1431 }
1432 1432
1433 1433 switch (act) {
1434 1434 case SMBADM_GRP_ADDMEMBER:
1435 1435 act_str = gettext("add");
1436 1436 rc = smb_lgrp_add_member(gname,
1437 1437 msid.gs_sid, msid.gs_type);
1438 1438 break;
1439 1439 case SMBADM_GRP_DELMEMBER:
1440 1440 act_str = gettext("remove");
1441 1441 rc = smb_lgrp_del_member(gname,
1442 1442 msid.gs_sid, msid.gs_type);
1443 1443 break;
1444 1444 default:
1445 1445 rc = SMB_LGRP_INTERNAL_ERROR;
1446 1446 break;
1447 1447 }
1448 1448
1449 1449 smb_sid_free(msid.gs_sid);
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
1450 1450
1451 1451 if (rc != SMB_LGRP_SUCCESS) {
1452 1452 (void) fprintf(stderr,
1453 1453 gettext("failed to %s %s (%s)\n"),
1454 1454 act_str, mname, smb_lgrp_strerror(rc));
1455 1455 return (1);
1456 1456 }
1457 1457 return (0);
1458 1458 }
1459 1459
1460 +static int
1461 +smbadm_user_delete(int argc, char **argv)
1462 +{
1463 + int error;
1464 + char *user = NULL;
1465 +
1466 + user = argv[optind];
1467 + if (optind >= argc || user == NULL || *user == '\0') {
1468 + (void) fprintf(stderr, gettext("missing user name\n"));
1469 + smbadm_usage(B_FALSE);
1470 + }
1471 +
1472 + error = smb_pwd_setcntl(user, SMB_PWC_DELETE);
1473 + if (error == SMB_PWE_SUCCESS)
1474 + (void) printf(gettext("%s has been deleted.\n"), user);
1475 + else
1476 + (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1477 +
1478 + return (error);
1479 +}
1480 +
1460 1481 static int
1461 1482 smbadm_user_disable(int argc, char **argv)
1462 1483 {
1463 1484 int error;
1464 1485 char *user = NULL;
1465 1486
1466 1487 user = argv[optind];
1467 1488 if (optind >= argc || user == NULL || *user == '\0') {
1468 1489 (void) fprintf(stderr, gettext("missing user name\n"));
1469 1490 smbadm_usage(B_FALSE);
1470 1491 }
1471 1492
1472 1493 error = smb_pwd_setcntl(user, SMB_PWC_DISABLE);
1473 1494 if (error == SMB_PWE_SUCCESS)
1474 1495 (void) printf(gettext("%s is disabled.\n"), user);
1475 1496 else
1476 1497 (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1477 1498
1478 1499 return (error);
1479 1500 }
1480 1501
1481 1502 static int
1482 1503 smbadm_user_enable(int argc, char **argv)
1483 1504 {
1484 1505 int error;
1485 1506 char *user = NULL;
1486 1507
1487 1508 user = argv[optind];
1488 1509 if (optind >= argc || user == NULL || *user == '\0') {
1489 1510 (void) fprintf(stderr, gettext("missing user name\n"));
1490 1511 smbadm_usage(B_FALSE);
1491 1512 }
1492 1513
1493 1514 error = smb_pwd_setcntl(user, SMB_PWC_ENABLE);
1494 1515 if (error == SMB_PWE_SUCCESS)
1495 1516 (void) printf(gettext("%s is enabled.\n"), user);
1496 1517 else
1497 1518 (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1498 1519
1499 1520 return (error);
1500 1521 }
1501 1522
1502 1523
1503 1524 int
1504 1525 main(int argc, char **argv)
1505 1526 {
1506 1527 int ret;
1507 1528 int i;
1508 1529
1509 1530 (void) setlocale(LC_ALL, "");
1510 1531 (void) textdomain(TEXT_DOMAIN);
1511 1532
1512 1533 (void) malloc(0); /* satisfy libumem dependency */
1513 1534
1514 1535 progname = basename(argv[0]);
1515 1536
1516 1537 if (is_system_labeled()) {
1517 1538 (void) fprintf(stderr,
1518 1539 gettext("Trusted Extensions not supported\n"));
1519 1540 return (1);
1520 1541 }
1521 1542
1522 1543 if (argc < 2) {
1523 1544 (void) fprintf(stderr, gettext("missing command\n"));
1524 1545 smbadm_usage(B_FALSE);
1525 1546 }
1526 1547
1527 1548 /*
1528 1549 * Special case "cmd --help/-?"
1529 1550 */
1530 1551 if (strcmp(argv[1], "-?") == 0 ||
1531 1552 strcmp(argv[1], "--help") == 0 ||
1532 1553 strcmp(argv[1], "-h") == 0)
1533 1554 smbadm_usage(B_TRUE);
1534 1555
1535 1556 for (i = 0; i < SMBADM_NCMD; ++i) {
1536 1557 curcmd = &smbadm_cmdtable[i];
1537 1558 if (strcasecmp(argv[1], curcmd->name) == 0) {
1538 1559 if (argc > 2) {
1539 1560 /* cmd subcmd --help/-? */
1540 1561 if (strcmp(argv[2], "-?") == 0 ||
1541 1562 strcmp(argv[2], "--help") == 0 ||
1542 1563 strcmp(argv[2], "-h") == 0)
1543 1564 smbadm_usage(B_TRUE);
1544 1565 }
1545 1566
1546 1567 if (!smbadm_checkauth(curcmd->auth)) {
1547 1568 (void) fprintf(stderr,
1548 1569 gettext("%s: %s: authorization denied\n"),
1549 1570 progname, curcmd->name);
1550 1571 return (1);
1551 1572 }
1552 1573
1553 1574 if ((ret = smbadm_init()) != 0)
1554 1575 return (ret);
1555 1576
1556 1577 ret = curcmd->func(argc - 1, &argv[1]);
1557 1578
1558 1579 smbadm_fini();
1559 1580 return (ret);
1560 1581 }
1561 1582 }
1562 1583
1563 1584 curcmd = NULL;
1564 1585 (void) fprintf(stderr, gettext("unknown subcommand (%s)\n"), argv[1]);
1565 1586 smbadm_usage(B_FALSE);
1566 1587 return (2);
1567 1588 }
1568 1589
1569 1590 static int
1570 1591 smbadm_init(void)
1571 1592 {
1572 1593 int rc;
1573 1594
1574 1595 switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) {
1575 1596 case SMBADM_CMDF_GROUP:
1576 1597 if ((rc = smb_lgrp_start()) != SMB_LGRP_SUCCESS) {
1577 1598 (void) fprintf(stderr,
1578 1599 gettext("failed to initialize (%s)\n"),
1579 1600 smb_lgrp_strerror(rc));
1580 1601 return (1);
1581 1602 }
1582 1603 break;
1583 1604
1584 1605 case SMBADM_CMDF_USER:
1585 1606 smb_pwd_init(B_FALSE);
1586 1607 break;
1587 1608
1588 1609 default:
1589 1610 break;
1590 1611 }
1591 1612
1592 1613 return (0);
1593 1614 }
1594 1615
1595 1616 static void
1596 1617 smbadm_fini(void)
1597 1618 {
1598 1619 switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) {
1599 1620 case SMBADM_CMDF_GROUP:
1600 1621 smb_lgrp_stop();
1601 1622 break;
1602 1623
1603 1624 case SMBADM_CMDF_USER:
1604 1625 smb_pwd_fini();
1605 1626 break;
1606 1627
1607 1628 default:
1608 1629 break;
1609 1630 }
1610 1631 }
1611 1632
1612 1633 static boolean_t
1613 1634 smbadm_checkauth(const char *auth)
1614 1635 {
1615 1636 struct passwd *pw;
1616 1637
1617 1638 if ((pw = getpwuid(getuid())) == NULL)
1618 1639 return (B_FALSE);
1619 1640
1620 1641 if (chkauthattr(auth, pw->pw_name) == 0)
1621 1642 return (B_FALSE);
1622 1643
1623 1644 return (B_TRUE);
1624 1645 }
1625 1646
1626 1647 static boolean_t
1627 1648 smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval)
1628 1649 {
1629 1650 smbadm_prop_handle_t *pinfo;
1630 1651 int i;
1631 1652
1632 1653 for (i = 0; i < SMBADM_NPROP; i++) {
1633 1654 pinfo = &smbadm_ptable[i];
1634 1655 if (strcmp(pinfo->p_name, prop->p_name) == 0) {
1635 1656 if (pinfo->p_chkfn && chkval)
1636 1657 return (pinfo->p_chkfn(prop));
1637 1658
1638 1659 return (B_TRUE);
1639 1660 }
1640 1661 }
1641 1662
1642 1663 (void) fprintf(stderr, gettext("unrecognized property '%s'\n"),
1643 1664 prop->p_name);
1644 1665
1645 1666 return (B_FALSE);
1646 1667 }
1647 1668
1648 1669 static int
1649 1670 smbadm_prop_parse(char *arg, smbadm_prop_t *prop)
1650 1671 {
1651 1672 boolean_t parse_value;
1652 1673 char *equal;
1653 1674
1654 1675 if (arg == NULL)
1655 1676 return (2);
1656 1677
1657 1678 prop->p_name = prop->p_value = NULL;
1658 1679
1659 1680 if (strcmp(curcmd->name, "set") == 0)
1660 1681 parse_value = B_TRUE;
1661 1682 else
1662 1683 parse_value = B_FALSE;
1663 1684
1664 1685 prop->p_name = arg;
1665 1686
1666 1687 if (parse_value) {
1667 1688 equal = strchr(arg, '=');
1668 1689 if (equal == NULL)
1669 1690 return (2);
1670 1691
1671 1692 *equal++ = '\0';
1672 1693 prop->p_value = equal;
1673 1694 }
1674 1695
1675 1696 if (smbadm_prop_validate(prop, parse_value) == B_FALSE)
1676 1697 return (2);
1677 1698
1678 1699 return (0);
1679 1700 }
1680 1701
1681 1702 static smbadm_prop_handle_t *
1682 1703 smbadm_prop_gethandle(char *pname)
1683 1704 {
1684 1705 int i;
1685 1706
1686 1707 for (i = 0; i < SMBADM_NPROP; i++)
1687 1708 if (strcmp(pname, smbadm_ptable[i].p_name) == 0)
1688 1709 return (&smbadm_ptable[i]);
1689 1710
1690 1711 return (NULL);
1691 1712 }
1692 1713
1693 1714 static int
1694 1715 smbadm_setprop_desc(char *gname, smbadm_prop_t *prop)
1695 1716 {
1696 1717 int status;
1697 1718
1698 1719 status = smb_lgrp_setcmnt(gname, prop->p_value);
1699 1720 if (status != SMB_LGRP_SUCCESS) {
1700 1721 (void) fprintf(stderr,
1701 1722 gettext("failed to modify the group description (%s)\n"),
1702 1723 smb_lgrp_strerror(status));
1703 1724 return (1);
1704 1725 }
1705 1726
1706 1727 (void) printf(gettext("%s: description modified\n"), gname);
1707 1728 return (0);
1708 1729 }
1709 1730
1710 1731 static int
1711 1732 smbadm_getprop_desc(char *gname, smbadm_prop_t *prop)
1712 1733 {
1713 1734 char *cmnt = NULL;
1714 1735 int status;
1715 1736
1716 1737 status = smb_lgrp_getcmnt(gname, &cmnt);
1717 1738 if (status != SMB_LGRP_SUCCESS) {
1718 1739 (void) fprintf(stderr,
1719 1740 gettext("failed to get the group description (%s)\n"),
1720 1741 smb_lgrp_strerror(status));
1721 1742 return (1);
1722 1743 }
1723 1744
1724 1745 (void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt);
1725 1746 free(cmnt);
1726 1747 return (0);
1727 1748 }
1728 1749
1729 1750 static int
1730 1751 smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1731 1752 {
1732 1753 boolean_t enable;
1733 1754 int status;
1734 1755 int ret;
1735 1756
1736 1757 if (strcasecmp(prop->p_value, "on") == 0) {
1737 1758 (void) printf(gettext("Enabling %s privilege "), prop->p_name);
1738 1759 enable = B_TRUE;
1739 1760 } else {
1740 1761 (void) printf(gettext("Disabling %s privilege "), prop->p_name);
1741 1762 enable = B_FALSE;
1742 1763 }
1743 1764
1744 1765 status = smb_lgrp_setpriv(gname, priv_id, enable);
1745 1766 if (status == SMB_LGRP_SUCCESS) {
1746 1767 (void) printf(gettext("succeeded\n"));
1747 1768 ret = 0;
1748 1769 } else {
1749 1770 (void) printf(gettext("failed: %s\n"),
1750 1771 smb_lgrp_strerror(status));
1751 1772 ret = 1;
1752 1773 }
1753 1774
1754 1775 return (ret);
1755 1776 }
1756 1777
1757 1778 static int
1758 1779 smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
1759 1780 {
1760 1781 boolean_t enable;
1761 1782 int status;
1762 1783
1763 1784 status = smb_lgrp_getpriv(gname, priv_id, &enable);
1764 1785 if (status != SMB_LGRP_SUCCESS) {
1765 1786 (void) fprintf(stderr, gettext("failed to get %s (%s)\n"),
1766 1787 prop->p_name, smb_lgrp_strerror(status));
1767 1788 return (1);
1768 1789 }
1769 1790
1770 1791 (void) printf(gettext("\t%s: %s\n"), prop->p_name,
1771 1792 (enable) ? "On" : "Off");
1772 1793
1773 1794 return (0);
1774 1795 }
1775 1796
1776 1797 static int
1777 1798 smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop)
1778 1799 {
1779 1800 return (smbadm_group_setpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1780 1801 }
1781 1802
1782 1803 static int
1783 1804 smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop)
1784 1805 {
1785 1806 return (smbadm_group_getpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop));
1786 1807 }
1787 1808
1788 1809 static int
1789 1810 smbadm_setprop_backup(char *gname, smbadm_prop_t *prop)
1790 1811 {
1791 1812 return (smbadm_group_setpriv(gname, SE_BACKUP_LUID, prop));
1792 1813 }
1793 1814
1794 1815 static int
1795 1816 smbadm_getprop_backup(char *gname, smbadm_prop_t *prop)
1796 1817 {
1797 1818 return (smbadm_group_getpriv(gname, SE_BACKUP_LUID, prop));
1798 1819 }
1799 1820
1800 1821 static int
1801 1822 smbadm_setprop_restore(char *gname, smbadm_prop_t *prop)
1802 1823 {
1803 1824 return (smbadm_group_setpriv(gname, SE_RESTORE_LUID, prop));
1804 1825 }
1805 1826
1806 1827 static int
1807 1828 smbadm_getprop_restore(char *gname, smbadm_prop_t *prop)
1808 1829 {
1809 1830 return (smbadm_group_getpriv(gname, SE_RESTORE_LUID, prop));
1810 1831 }
1811 1832
1812 1833 static boolean_t
1813 1834 smbadm_chkprop_priv(smbadm_prop_t *prop)
1814 1835 {
1815 1836 if (prop->p_value == NULL || *prop->p_value == '\0') {
1816 1837 (void) fprintf(stderr,
1817 1838 gettext("missing value for '%s'\n"), prop->p_name);
1818 1839 return (B_FALSE);
1819 1840 }
1820 1841
1821 1842 if (strcasecmp(prop->p_value, "on") == 0)
1822 1843 return (B_TRUE);
1823 1844
1824 1845 if (strcasecmp(prop->p_value, "off") == 0)
1825 1846 return (B_TRUE);
1826 1847
1827 1848 (void) fprintf(stderr,
1828 1849 gettext("%s: unrecognized value for '%s' property\n"),
1829 1850 prop->p_value, prop->p_name);
1830 1851
1831 1852 return (B_FALSE);
1832 1853 }
1833 1854
1834 1855 static const char *
1835 1856 smbadm_pwd_strerror(int error)
1836 1857 {
1837 1858 switch (error) {
1838 1859 case SMB_PWE_SUCCESS:
1839 1860 return (gettext("Success."));
1840 1861
1841 1862 case SMB_PWE_USER_UNKNOWN:
1842 1863 return (gettext("User does not exist."));
1843 1864
1844 1865 case SMB_PWE_USER_DISABLE:
1845 1866 return (gettext("User is disabled."));
1846 1867
1847 1868 case SMB_PWE_CLOSE_FAILED:
1848 1869 case SMB_PWE_OPEN_FAILED:
1849 1870 case SMB_PWE_WRITE_FAILED:
1850 1871 case SMB_PWE_UPDATE_FAILED:
1851 1872 return (gettext("Unexpected failure. "
1852 1873 "SMB password database unchanged."));
1853 1874
1854 1875 case SMB_PWE_STAT_FAILED:
1855 1876 return (gettext("stat of SMB password file failed."));
1856 1877
1857 1878 case SMB_PWE_BUSY:
1858 1879 return (gettext("SMB password database busy. "
1859 1880 "Try again later."));
1860 1881
1861 1882 case SMB_PWE_DENIED:
1862 1883 return (gettext("Operation not permitted."));
1863 1884
1864 1885 case SMB_PWE_SYSTEM_ERROR:
1865 1886 return (gettext("System error."));
1866 1887
1867 1888 default:
1868 1889 break;
1869 1890 }
1870 1891
1871 1892 return (gettext("Unknown error code."));
1872 1893 }
1873 1894
1874 1895 /*
1875 1896 * Enable libumem debugging by default on DEBUG builds.
1876 1897 */
1877 1898 #ifdef DEBUG
1878 1899 const char *
1879 1900 _umem_debug_init(void)
1880 1901 {
1881 1902 return ("default,verbose"); /* $UMEM_DEBUG setting */
1882 1903 }
1883 1904
1884 1905 const char *
1885 1906 _umem_logging_init(void)
1886 1907 {
1887 1908 return ("fail,contents"); /* $UMEM_LOGGING setting */
1888 1909 }
1889 1910 #endif
|
↓ open down ↓ |
420 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX