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


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * This module contains smbadm CLI which offers smb configuration
  28  * functionalities.
  29  */
  30 #include <errno.h>
  31 #include <err.h>
  32 #include <ctype.h>
  33 #include <stdlib.h>
  34 #include <unistd.h>
  35 #include <stdio.h>
  36 #include <syslog.h>
  37 #include <strings.h>
  38 #include <limits.h>
  39 #include <getopt.h>
  40 #include <libintl.h>
  41 #include <zone.h>
  42 #include <pwd.h>
  43 #include <grp.h>


  48 #include <smbsrv/libsmb.h>
  49 #include <smbsrv/libsmbns.h>
  50 
  51 #if !defined(TEXT_DOMAIN)
  52 #define TEXT_DOMAIN "SYS_TEST"
  53 #endif
  54 
  55 typedef enum {
  56         HELP_ADD_MEMBER,
  57         HELP_CREATE,
  58         HELP_DELETE,
  59         HELP_DEL_MEMBER,
  60         HELP_GET,
  61         HELP_JOIN,
  62         HELP_LIST,
  63         HELP_LOOKUP,
  64         HELP_RENAME,
  65         HELP_SET,
  66         HELP_SHOW,
  67         HELP_USER_DISABLE,
  68         HELP_USER_ENABLE

  69 } smbadm_help_t;
  70 
  71 #define SMBADM_CMDF_NONE        0x00
  72 #define SMBADM_CMDF_USER        0x01
  73 #define SMBADM_CMDF_GROUP       0x02
  74 #define SMBADM_CMDF_TYPEMASK    0x0F
  75 
  76 typedef enum {
  77         SMBADM_GRP_ADDMEMBER = 0,
  78         SMBADM_GRP_DELMEMBER,
  79 } smbadm_grp_action_t;
  80 
  81 #define SMBADM_ANSBUFSIZ        64
  82 
  83 typedef struct smbadm_cmdinfo {
  84         char *name;
  85         int (*func)(int, char **);
  86         smbadm_help_t usage;
  87         uint32_t flags;
  88         char *auth;


 101 static int smbadm_join_workgroup(const char *, boolean_t);
 102 static int smbadm_join_domain(const char *, const char *, boolean_t);
 103 static void smbadm_extract_domain(char *, char **, char **);
 104 
 105 static int smbadm_join(int, char **);
 106 static int smbadm_list(int, char **);
 107 static int smbadm_lookup(int, char **);
 108 static void smbadm_lookup_name(char *);
 109 static void smbadm_lookup_sid(char *);
 110 static int smbadm_group_create(int, char **);
 111 static int smbadm_group_delete(int, char **);
 112 static int smbadm_group_rename(int, char **);
 113 static int smbadm_group_show(int, char **);
 114 static void smbadm_group_show_name(const char *, const char *);
 115 static int smbadm_group_getprop(int, char **);
 116 static int smbadm_group_setprop(int, char **);
 117 static int smbadm_group_addmember(int, char **);
 118 static int smbadm_group_delmember(int, char **);
 119 static int smbadm_group_add_del_member(char *, char *, smbadm_grp_action_t);
 120 

 121 static int smbadm_user_disable(int, char **);
 122 static int smbadm_user_enable(int, char **);
 123 

 124 static smbadm_cmdinfo_t smbadm_cmdtable[] =
 125 {
 126         { "add-member",         smbadm_group_addmember, HELP_ADD_MEMBER,
 127                 SMBADM_CMDF_GROUP,      SMBADM_ACTION_AUTH },
 128         { "create",             smbadm_group_create,    HELP_CREATE,
 129                 SMBADM_CMDF_GROUP,      SMBADM_ACTION_AUTH },
 130         { "delete",             smbadm_group_delete,    HELP_DELETE,
 131                 SMBADM_CMDF_GROUP,      SMBADM_ACTION_AUTH },














 132         { "disable-user",       smbadm_user_disable,    HELP_USER_DISABLE,
 133                 SMBADM_CMDF_USER,       SMBADM_ACTION_AUTH },
 134         { "enable-user",        smbadm_user_enable,     HELP_USER_ENABLE,
 135                 SMBADM_CMDF_USER,       SMBADM_ACTION_AUTH },
 136         { "get",                smbadm_group_getprop,   HELP_GET,
 137                 SMBADM_CMDF_GROUP,      SMBADM_ACTION_AUTH },
 138         { "join",               smbadm_join,            HELP_JOIN,
 139                 SMBADM_CMDF_NONE,       SMBADM_VALUE_AUTH },
 140         { "list",               smbadm_list,            HELP_LIST,
 141                 SMBADM_CMDF_NONE,       SMBADM_BASIC_AUTH },
 142         { "lookup",             smbadm_lookup,          HELP_LOOKUP,
 143                 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 };
 153 
 154 #define SMBADM_NCMD     (sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0]))
 155 
 156 typedef struct smbadm_prop {
 157         char *p_name;
 158         char *p_value;
 159 } smbadm_prop_t;
 160 
 161 typedef struct smbadm_prop_handle {
 162         char *p_name;
 163         char *p_dispvalue;
 164         int (*p_setfn)(char *, smbadm_prop_t *);
 165         int (*p_getfn)(char *, smbadm_prop_t *);
 166         boolean_t (*p_chkfn)(smbadm_prop_t *);
 167 } smbadm_prop_handle_t;
 168 
 169 static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval);
 170 static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop);
 171 static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname);
 172 
 173 static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop);
 174 static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop);
 175 static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop);
 176 static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop);
 177 static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop);
 178 static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop);
 179 static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop);
 180 static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop);
 181 static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop);
 182 
 183 static smbadm_prop_handle_t smbadm_ptable[] = {
 184         {"backup",      "on | off",     smbadm_setprop_backup,
 185         smbadm_getprop_backup,  smbadm_chkprop_priv     },
 186         {"restore",     "on | off",     smbadm_setprop_restore,
 187         smbadm_getprop_restore, smbadm_chkprop_priv     },
 188         {"take-ownership", "on | off",  smbadm_setprop_tkowner,
 189         smbadm_getprop_tkowner, smbadm_chkprop_priv     },
 190         {"description", "<string>",       smbadm_setprop_desc,
 191         smbadm_getprop_desc,    NULL                    },
 192 };
 193 
 194 static int smbadm_init(void);
 195 static void smbadm_fini(void);
 196 static const char *smbadm_pwd_strerror(int error);
 197 
 198 /*
 199  * Number of supported properties
 200  */
 201 #define SMBADM_NPROP    (sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0]))
 202 
 203 static void
 204 smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd)
 205 {
 206         switch (cmd->usage) {
 207         case HELP_ADD_MEMBER:
 208                 (void) fprintf(fp,
 209                     gettext("\t%s -m member [[-m member] ...] group\n"),
 210                     cmd->name);
 211                 return;
 212 
 213         case HELP_CREATE:
 214                 (void) fprintf(fp, gettext("\t%s [-d description] group\n"),
 215                     cmd->name);
 216                 return;
 217 
 218         case HELP_DELETE:
 219                 (void) fprintf(fp, gettext("\t%s group\n"), cmd->name);
 220                 return;
 221 

 222         case HELP_USER_DISABLE:
 223         case HELP_USER_ENABLE:
 224                 (void) fprintf(fp, gettext("\t%s user\n"), cmd->name);
 225                 return;
 226 
 227         case HELP_GET:
 228                 (void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"),
 229                     cmd->name);
 230                 return;
 231 
 232         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"),

 236                     cmd->name, cmd->name, cmd->name);
 237 #else
 238                 (void) fprintf(fp, gettext("\t%s [-y] -u username domain\n"
 239                     "\t%s [-y] -w workgroup\n"), cmd->name, cmd->name);
 240 #endif
 241                 return;
 242 
 243         case HELP_LIST:
 244                 (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                 return;
 252 
 253         case HELP_LOOKUP:
 254                 (void) fprintf(fp,
 255                     gettext("\t%s user-or-group-name\n"),
 256                     cmd->name);
 257                 return;
 258 
 259         case HELP_DEL_MEMBER:
 260                 (void) fprintf(fp,
 261                     gettext("\t%s -m member [[-m member] ...] group\n"),
 262                     cmd->name);
 263                 return;
 264 
 265         case HELP_RENAME:
 266                 (void) fprintf(fp, gettext("\t%s group new-group\n"),
 267                     cmd->name);
 268                 return;
 269 
 270         case HELP_SET:
 271                 (void) fprintf(fp, gettext("\t%s -p property=value "
 272                     "[[-p property=value] ...] group\n"), cmd->name);
 273                 return;
 274 
 275         case HELP_SHOW:
 276                 (void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"),
 277                     cmd->name);
 278                 return;
 279 
 280         default:
 281                 break;
 282         }
 283 
 284         abort();
 285         /* NOTREACHED */
 286 }
 287 
 288 static void
 289 smbadm_usage(boolean_t requested)
 290 {
 291         FILE *fp = requested ? stdout : stderr;
 292         boolean_t show_props = B_FALSE;
 293         int i;
 294 
 295         if (curcmd == NULL) {
 296                 (void) fprintf(fp,
 297                     gettext("usage: %s [-h | <command> [options]]\n"),
 298                     progname);
 299                 (void) fprintf(fp,
 300                     gettext("where 'command' is one of the following:\n\n"));
 301 
 302                 for (i = 0; i < SMBADM_NCMD; i++)
 303                         smbadm_cmdusage(fp, &smbadm_cmdtable[i]);
 304 
 305                 (void) fprintf(fp,
 306                     gettext("\nFor property list, run %s %s|%s\n"),
 307                     progname, "get", "set");
 308 
 309                 exit(requested ? 0 : 2);
 310         }
 311 
 312         (void) fprintf(fp, gettext("usage:\n"));
 313         smbadm_cmdusage(fp, curcmd);
 314 
 315         if (strcmp(curcmd->name, "get") == 0 ||
 316             strcmp(curcmd->name, "set") == 0)
 317                 show_props = B_TRUE;
 318 
 319         if (show_props) {
 320                 (void) fprintf(fp,


1391         free(mname);
1392         return (ret);
1393 }
1394 
1395 static int
1396 smbadm_group_add_del_member(char *gname, char *mname,
1397         smbadm_grp_action_t act)
1398 {
1399         lsa_account_t   acct;
1400         smb_gsid_t msid;
1401         char *sidstr;
1402         char *act_str;
1403         int rc;
1404 
1405         if (strncmp(mname, "S-1-", 4) == 0) {
1406                 /*
1407                  * We are given a SID.  Just use it.
1408                  *
1409                  * We'e like the real account type if we can get it,
1410                  * but don't want to error out if we can't get it.

1411                  */
1412                 sidstr = mname;
1413                 rc = smb_lookup_sid(sidstr, &acct);
1414                 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS))
1415                         acct.a_sidtype = SidTypeUnknown;
1416         } else {
1417                 rc = smb_lookup_name(mname, SidTypeUnknown, &acct);
1418                 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS)) {
1419                         (void) fprintf(stderr,
1420                             gettext("%s: name lookup failed\n"), mname);
1421                         return (1);
1422                 }
1423                 sidstr = acct.a_sid;
1424         }
1425 
1426         msid.gs_type = acct.a_sidtype;
1427         if ((msid.gs_sid = smb_sid_fromstr(sidstr)) == NULL) {
1428                 (void) fprintf(stderr,
1429                     gettext("%s: no memory for SID\n"), sidstr);
1430                 return (1);
1431         }
1432 
1433         switch (act) {
1434         case SMBADM_GRP_ADDMEMBER:
1435                 act_str = gettext("add");


1440                 act_str = gettext("remove");
1441                 rc = smb_lgrp_del_member(gname,
1442                     msid.gs_sid, msid.gs_type);
1443                 break;
1444         default:
1445                 rc = SMB_LGRP_INTERNAL_ERROR;
1446                 break;
1447         }
1448 
1449         smb_sid_free(msid.gs_sid);
1450 
1451         if (rc != SMB_LGRP_SUCCESS) {
1452                 (void) fprintf(stderr,
1453                     gettext("failed to %s %s (%s)\n"),
1454                     act_str, mname, smb_lgrp_strerror(rc));
1455                 return (1);
1456         }
1457         return (0);
1458 }
1459 





















1460 static int
1461 smbadm_user_disable(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_DISABLE);
1473         if (error == SMB_PWE_SUCCESS)
1474                 (void) printf(gettext("%s is disabled.\n"), user);
1475         else
1476                 (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1477 
1478         return (error);
1479 }




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * This module contains smbadm CLI which offers smb configuration
  28  * functionalities.
  29  */
  30 #include <errno.h>
  31 #include <err.h>
  32 #include <ctype.h>
  33 #include <stdlib.h>
  34 #include <unistd.h>
  35 #include <stdio.h>
  36 #include <syslog.h>
  37 #include <strings.h>
  38 #include <limits.h>
  39 #include <getopt.h>
  40 #include <libintl.h>
  41 #include <zone.h>
  42 #include <pwd.h>
  43 #include <grp.h>


  48 #include <smbsrv/libsmb.h>
  49 #include <smbsrv/libsmbns.h>
  50 
  51 #if !defined(TEXT_DOMAIN)
  52 #define TEXT_DOMAIN "SYS_TEST"
  53 #endif
  54 
  55 typedef enum {
  56         HELP_ADD_MEMBER,
  57         HELP_CREATE,
  58         HELP_DELETE,
  59         HELP_DEL_MEMBER,
  60         HELP_GET,
  61         HELP_JOIN,
  62         HELP_LIST,
  63         HELP_LOOKUP,
  64         HELP_RENAME,
  65         HELP_SET,
  66         HELP_SHOW,
  67         HELP_USER_DISABLE,
  68         HELP_USER_ENABLE,
  69         HELP_USER_DELETE
  70 } smbadm_help_t;
  71 
  72 #define SMBADM_CMDF_NONE        0x00
  73 #define SMBADM_CMDF_USER        0x01
  74 #define SMBADM_CMDF_GROUP       0x02
  75 #define SMBADM_CMDF_TYPEMASK    0x0F
  76 
  77 typedef enum {
  78         SMBADM_GRP_ADDMEMBER = 0,
  79         SMBADM_GRP_DELMEMBER,
  80 } smbadm_grp_action_t;
  81 
  82 #define SMBADM_ANSBUFSIZ        64
  83 
  84 typedef struct smbadm_cmdinfo {
  85         char *name;
  86         int (*func)(int, char **);
  87         smbadm_help_t usage;
  88         uint32_t flags;
  89         char *auth;


 102 static int smbadm_join_workgroup(const char *, boolean_t);
 103 static int smbadm_join_domain(const char *, const char *, boolean_t);
 104 static void smbadm_extract_domain(char *, char **, char **);
 105 
 106 static int smbadm_join(int, char **);
 107 static int smbadm_list(int, char **);
 108 static int smbadm_lookup(int, char **);
 109 static void smbadm_lookup_name(char *);
 110 static void smbadm_lookup_sid(char *);
 111 static int smbadm_group_create(int, char **);
 112 static int smbadm_group_delete(int, char **);
 113 static int smbadm_group_rename(int, char **);
 114 static int smbadm_group_show(int, char **);
 115 static void smbadm_group_show_name(const char *, const char *);
 116 static int smbadm_group_getprop(int, char **);
 117 static int smbadm_group_setprop(int, char **);
 118 static int smbadm_group_addmember(int, char **);
 119 static int smbadm_group_delmember(int, char **);
 120 static int smbadm_group_add_del_member(char *, char *, smbadm_grp_action_t);
 121 
 122 static int smbadm_user_delete(int, char **);
 123 static int smbadm_user_disable(int, char **);
 124 static int smbadm_user_enable(int, char **);
 125 
 126 /* Please keep the order consistent with smbadm(1M) man page */
 127 static smbadm_cmdinfo_t smbadm_cmdtable[] =
 128 {


 129         { "create",             smbadm_group_create,    HELP_CREATE,
 130                 SMBADM_CMDF_GROUP,      SMBADM_ACTION_AUTH },
 131         { "delete",             smbadm_group_delete,    HELP_DELETE,
 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 },
 147         { "disable-user",       smbadm_user_disable,    HELP_USER_DISABLE,
 148                 SMBADM_CMDF_USER,       SMBADM_ACTION_AUTH },
 149         { "enable-user",        smbadm_user_enable,     HELP_USER_ENABLE,
 150                 SMBADM_CMDF_USER,       SMBADM_ACTION_AUTH },


 151         { "join",               smbadm_join,            HELP_JOIN,
 152                 SMBADM_CMDF_NONE,       SMBADM_VALUE_AUTH },
 153         { "list",               smbadm_list,            HELP_LIST,
 154                 SMBADM_CMDF_NONE,       SMBADM_BASIC_AUTH },
 155         { "lookup",             smbadm_lookup,          HELP_LOOKUP,
 156                 SMBADM_CMDF_NONE,       SMBADM_BASIC_AUTH },








 157 };
 158 
 159 #define SMBADM_NCMD     (sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0]))
 160 
 161 typedef struct smbadm_prop {
 162         char *p_name;
 163         char *p_value;
 164 } smbadm_prop_t;
 165 
 166 typedef struct smbadm_prop_handle {
 167         char *p_name;
 168         char *p_dispvalue;
 169         int (*p_setfn)(char *, smbadm_prop_t *);
 170         int (*p_getfn)(char *, smbadm_prop_t *);
 171         boolean_t (*p_chkfn)(smbadm_prop_t *);
 172 } smbadm_prop_handle_t;
 173 
 174 static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval);
 175 static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop);
 176 static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname);
 177 
 178 static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop);
 179 static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop);
 180 static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop);
 181 static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop);
 182 static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop);
 183 static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop);
 184 static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop);
 185 static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop);
 186 static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop);
 187 
 188 static smbadm_prop_handle_t smbadm_ptable[] = {
 189         {"backup",      "on|off",       smbadm_setprop_backup,
 190         smbadm_getprop_backup,  smbadm_chkprop_priv     },
 191         {"restore",     "on|off",       smbadm_setprop_restore,
 192         smbadm_getprop_restore, smbadm_chkprop_priv     },
 193         {"take-ownership", "on|off",    smbadm_setprop_tkowner,
 194         smbadm_getprop_tkowner, smbadm_chkprop_priv     },
 195         {"description", "<string>",       smbadm_setprop_desc,
 196         smbadm_getprop_desc,    NULL                    },
 197 };
 198 
 199 static int smbadm_init(void);
 200 static void smbadm_fini(void);
 201 static const char *smbadm_pwd_strerror(int error);
 202 
 203 /*
 204  * Number of supported properties
 205  */
 206 #define SMBADM_NPROP    (sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0]))
 207 
 208 static void
 209 smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd)
 210 {
 211         switch (cmd->usage) {
 212         case HELP_ADD_MEMBER:
 213                 (void) fprintf(fp,
 214                     gettext("\t%s -m <member> [-m <member>]... <group>\n"),
 215                     cmd->name);
 216                 return;
 217 
 218         case HELP_CREATE:
 219                 (void) fprintf(fp, gettext("\t%s [-d <description>] <group>\n"),
 220                     cmd->name);
 221                 return;
 222 
 223         case HELP_DELETE:
 224                 (void) fprintf(fp, gettext("\t%s <group>\n"), cmd->name);
 225                 return;
 226 
 227         case HELP_USER_DELETE:
 228         case HELP_USER_DISABLE:
 229         case HELP_USER_ENABLE:
 230                 (void) fprintf(fp, gettext("\t%s <username>\n"), cmd->name);
 231                 return;
 232 
 233         case HELP_GET:
 234                 (void) fprintf(fp, gettext("\t%s [-p <property>]... <group>\n"),
 235                     cmd->name);
 236                 return;
 237 
 238         case HELP_JOIN:
 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"),
 243                     cmd->name, cmd->name, cmd->name);
 244 #else
 245                 (void) fprintf(fp, gettext("\t%s [-y] -u <username> <domain>\n"
 246                     "\t%s [-y] -w <workgroup>\n"), cmd->name, cmd->name);
 247 #endif
 248                 return;
 249 
 250         case HELP_LIST:
 251                 (void) fprintf(fp, gettext("\t%s\n"), cmd->name);






 252                 return;
 253 
 254         case HELP_LOOKUP:
 255                 (void) fprintf(fp,
 256                     gettext("\t%s <account-name>\n"),
 257                     cmd->name);
 258                 return;
 259 
 260         case HELP_DEL_MEMBER:
 261                 (void) fprintf(fp,
 262                     gettext("\t%s -m <member> [-m <member>]... <group>\n"),
 263                     cmd->name);
 264                 return;
 265 
 266         case HELP_RENAME:
 267                 (void) fprintf(fp, gettext("\t%s <group> <new-group>\n"),
 268                     cmd->name);
 269                 return;
 270 
 271         case HELP_SET:
 272                 (void) fprintf(fp, gettext("\t%s -p <property>=<value> "
 273                     "[-p <property>=<value>]... <group>\n"), cmd->name);
 274                 return;
 275 
 276         case HELP_SHOW:
 277                 (void) fprintf(fp, gettext("\t%s [-mp] [<group>]\n"),
 278                     cmd->name);
 279                 return;
 280 
 281         default:
 282                 break;
 283         }
 284 
 285         abort();
 286         /* NOTREACHED */
 287 }
 288 
 289 static void
 290 smbadm_usage(boolean_t requested)
 291 {
 292         FILE *fp = requested ? stdout : stderr;
 293         boolean_t show_props = B_FALSE;
 294         int i;
 295 
 296         if (curcmd == NULL) {
 297                 (void) fprintf(fp,
 298                     gettext("usage: %s <subcommand> <args> ...\n"),
 299                     progname);


 300 
 301                 for (i = 0; i < SMBADM_NCMD; i++)
 302                         smbadm_cmdusage(fp, &smbadm_cmdtable[i]);
 303 
 304                 (void) fprintf(fp,
 305                     gettext("\nFor property list, run %s %s|%s\n"),
 306                     progname, "get", "set");
 307 
 308                 exit(requested ? 0 : 2);
 309         }
 310 
 311         (void) fprintf(fp, gettext("usage:\n"));
 312         smbadm_cmdusage(fp, curcmd);
 313 
 314         if (strcmp(curcmd->name, "get") == 0 ||
 315             strcmp(curcmd->name, "set") == 0)
 316                 show_props = B_TRUE;
 317 
 318         if (show_props) {
 319                 (void) fprintf(fp,


1390         free(mname);
1391         return (ret);
1392 }
1393 
1394 static int
1395 smbadm_group_add_del_member(char *gname, char *mname,
1396     smbadm_grp_action_t act)
1397 {
1398         lsa_account_t   acct;
1399         smb_gsid_t msid;
1400         char *sidstr;
1401         char *act_str;
1402         int rc;
1403 
1404         if (strncmp(mname, "S-1-", 4) == 0) {
1405                 /*
1406                  * We are given a SID.  Just use it.
1407                  *
1408                  * We'e like the real account type if we can get it,
1409                  * but don't want to error out if we can't get it.
1410                  * Lacking other info, assume it's a group.
1411                  */
1412                 sidstr = mname;
1413                 rc = smb_lookup_sid(sidstr, &acct);
1414                 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS))
1415                         acct.a_sidtype = SidTypeGroup;
1416         } else {
1417                 rc = smb_lookup_name(mname, SidTypeUnknown, &acct);
1418                 if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS)) {
1419                         (void) fprintf(stderr,
1420                             gettext("%s: name lookup failed\n"), mname);
1421                         return (1);
1422                 }
1423                 sidstr = acct.a_sid;
1424         }
1425 
1426         msid.gs_type = acct.a_sidtype;
1427         if ((msid.gs_sid = smb_sid_fromstr(sidstr)) == NULL) {
1428                 (void) fprintf(stderr,
1429                     gettext("%s: no memory for SID\n"), sidstr);
1430                 return (1);
1431         }
1432 
1433         switch (act) {
1434         case SMBADM_GRP_ADDMEMBER:
1435                 act_str = gettext("add");


1440                 act_str = gettext("remove");
1441                 rc = smb_lgrp_del_member(gname,
1442                     msid.gs_sid, msid.gs_type);
1443                 break;
1444         default:
1445                 rc = SMB_LGRP_INTERNAL_ERROR;
1446                 break;
1447         }
1448 
1449         smb_sid_free(msid.gs_sid);
1450 
1451         if (rc != SMB_LGRP_SUCCESS) {
1452                 (void) fprintf(stderr,
1453                     gettext("failed to %s %s (%s)\n"),
1454                     act_str, mname, smb_lgrp_strerror(rc));
1455                 return (1);
1456         }
1457         return (0);
1458 }
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 
1481 static int
1482 smbadm_user_disable(int argc, char **argv)
1483 {
1484         int error;
1485         char *user = NULL;
1486 
1487         user = argv[optind];
1488         if (optind >= argc || user == NULL || *user == '\0') {
1489                 (void) fprintf(stderr, gettext("missing user name\n"));
1490                 smbadm_usage(B_FALSE);
1491         }
1492 
1493         error = smb_pwd_setcntl(user, SMB_PWC_DISABLE);
1494         if (error == SMB_PWE_SUCCESS)
1495                 (void) printf(gettext("%s is disabled.\n"), user);
1496         else
1497                 (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error));
1498 
1499         return (error);
1500 }