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