Print this page
293 useradd/del/mod should be ZFS-aware


  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/param.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <ctype.h>
  41 #include <limits.h>
  42 #include <string.h>
  43 #include <userdefs.h>
  44 #include <user_attr.h>
  45 #include <nss_dbdefs.h>
  46 #include <errno.h>
  47 #include <project.h>
  48 #include "users.h"
  49 #include "messages.h"
  50 #include "funcs.h"
  51 
  52 /*
  53  *  usermod [-u uid [-o] | -g group | -G group [[,group]...] | -d dir [-m]

  54  *              | -s shell | -c comment | -l new_logname]
  55  *              | -f inactive | -e expire ]
  56  *              [ -A authorization [, authorization ...]]
  57  *              [ -P profile [, profile ...]]
  58  *              [ -R role [, role ...]]
  59  *              [ -K key=value ]
  60  *              [ -p project [, project]] login
  61  *
  62  *      This command adds new user logins to the system.  Arguments are:
  63  *
  64  *      uid - an integer less than MAXUID
  65  *      group - an existing group's integer ID or char string name
  66  *      dir - a directory
  67  *      shell - a program to be used as a shell
  68  *      comment - any text string
  69  *      skel_dir - a directory
  70  *      base_dir - a directory
  71  *      rid - an integer less than 2**16 (USHORT)
  72  *      login - a string of printable chars except colon (:)
  73  *      inactive - number of days a login maybe inactive before it is locked
  74  *      expire - date when a login is no longer valid
  75  *      authorization - One or more comma separated authorizations defined
  76  *                      in auth_attr(4).
  77  *      profile - One or more comma separated execution profiles defined
  78  *                in prof_attr(4)
  79  *      role - One or more comma-separated role names defined in user_attr(4)
  80  *      key=value - One or more -K options each specifying a valid user_attr(4)
  81  *              attribute.
  82  *
  83  */
  84 
  85 extern int **valid_lgroup(), isbusy();
  86 extern int valid_uid(), check_perm(), create_home(), move_dir();
  87 extern int valid_expire(), edit_group(), call_passmgmt();
  88 extern projid_t **valid_lproject();
  89 
  90 static uid_t uid;               /* new uid */
  91 static gid_t gid;                       /* gid of new login */
  92 static char *new_logname = NULL;        /* new login name with -l option */
  93 static char *uidstr = NULL;             /* uid from command line */
  94 static char *group = NULL;              /* group from command line */
  95 static char *grps = NULL;               /* multi groups from command line */
  96 static char *dir = NULL;                /* home dir from command line */
  97 static char *shell = NULL;              /* shell from command line */
  98 static char *comment = NULL;            /* comment from command line */
  99 static char *logname = NULL;            /* login name to add */
 100 static char *inactstr = NULL;           /* inactive from command line */
 101 static char *expire = NULL;             /* expiration date from command line */
 102 static char *projects = NULL;           /* project ids from command line */
 103 static char *usertype;
 104 
 105 char *cmdname;


 128         npw = malloc(sizeof (struct passwd));
 129 
 130         npw->pw_name = strcpmalloc(opw->pw_name);
 131         npw->pw_passwd = strcpmalloc(opw->pw_passwd);
 132         npw->pw_uid = opw->pw_uid;
 133         npw->pw_gid = opw->pw_gid;
 134         npw->pw_age = strcpmalloc(opw->pw_age);
 135         npw->pw_comment = strcpmalloc(opw->pw_comment);
 136         npw->pw_gecos  = strcpmalloc(opw->pw_gecos);
 137         npw->pw_dir = strcpmalloc(opw->pw_dir);
 138         npw->pw_shell = strcpmalloc(opw->pw_shell);
 139 
 140         return (npw);
 141 }
 142 
 143 int
 144 main(argc, argv)
 145 int argc;
 146 char **argv;
 147 {
 148         int ch, ret = EX_SUCCESS, call_pass = 0, oflag = 0;
 149         int tries, mflag = 0, inact, **gidlist, flag = 0;
 150         boolean_t fail_if_busy = B_FALSE;
 151         char *ptr;
 152         struct passwd *pstruct;         /* password struct for login */
 153         struct passwd *pw;
 154         struct group *g_ptr;    /* validated group from -g */
 155         struct stat statbuf;            /* status buffer for stat */
 156 #ifndef att
 157         FILE *pwf;              /* fille ptr for opened passwd file */
 158 #endif
 159         int warning;
 160         projid_t **projlist;
 161         char **nargv;                   /* arguments for execvp of passmgmt */
 162         int argindex;                   /* argument index into nargv */
 163         userattr_t *ua;
 164         char *val;
 165         int isrole;                     /* current account is role */
 166 
 167         cmdname = argv[0];
 168 
 169         if (geteuid() != 0) {
 170                 errmsg(M_PERM_DENIED);
 171                 exit(EX_NO_PERM);
 172         }
 173 
 174         opterr = 0;                     /* no print errors from getopt */
 175         /* get user type based on the program name */
 176         usertype = getusertype(argv[0]);
 177 
 178         while ((ch = getopt(argc, argv,
 179                                 "c:d:e:f:G:g:l:mop:s:u:A:P:R:K:")) != EOF)
 180                 switch (ch) {
 181                 case 'c':
 182                         comment = optarg;
 183                         flag++;
 184                         break;
 185                 case 'd':
 186                         dir = optarg;
 187                         fail_if_busy = B_TRUE;
 188                         flag++;
 189                         break;
 190                 case 'e':
 191                         expire = optarg;
 192                         flag++;
 193                         break;
 194                 case 'f':
 195                         inactstr = optarg;
 196                         flag++;
 197                         break;
 198                 case 'G':
 199                         grps = optarg;


 215                         fail_if_busy = B_TRUE;
 216                         break;
 217                 case 'o':
 218                         oflag++;
 219                         flag++;
 220                         fail_if_busy = B_TRUE;
 221                         break;
 222                 case 'p':
 223                         projects = optarg;
 224                         flag++;
 225                         break;
 226                 case 's':
 227                         shell = optarg;
 228                         flag++;
 229                         break;
 230                 case 'u':
 231                         uidstr = optarg;
 232                         flag++;
 233                         fail_if_busy = B_TRUE;
 234                         break;






 235                 case 'A':
 236                         change_key(USERATTR_AUTHS_KW, optarg);
 237                         flag++;
 238                         break;
 239                 case 'P':
 240                         change_key(USERATTR_PROFILES_KW, optarg);
 241                         flag++;
 242                         break;
 243                 case 'R':
 244                         change_key(USERATTR_ROLES_KW, optarg);
 245                         flag++;
 246                         break;
 247                 case 'K':
 248                         change_key(NULL, optarg);
 249                         flag++;
 250                         break;
 251                 default:
 252                 case '?':
 253                         if (is_role(usertype))
 254                                 errmsg(M_MRUSAGE);
 255                         else
 256                                 errmsg(M_MUSAGE);
 257                         exit(EX_SYNTAX);
 258                 }
 259 










 260         if (optind != argc - 1 || flag == 0) {
 261                 if (is_role(usertype))
 262                         errmsg(M_MRUSAGE);
 263                 else
 264                         errmsg(M_MUSAGE);
 265                 exit(EX_SYNTAX);
 266         }
 267 
 268         if ((!uidstr && oflag) || (mflag && !dir)) {
 269                 if (is_role(usertype))
 270                         errmsg(M_MRUSAGE);
 271                 else
 272                         errmsg(M_MUSAGE);
 273                 exit(EX_SYNTAX);
 274         }
 275 
 276         logname = argv[optind];
 277 
 278         /* Determine whether the account is a role or not */
 279         if ((ua = getusernam(logname)) == NULL ||


 473                 if (REL_PATH(dir)) {
 474                         errmsg(M_RELPATH, dir);
 475                         exit(EX_BADARG);
 476                 }
 477                 if (strcmp(pstruct->pw_dir, dir) == 0) {
 478                         /* home directory is the same so ignore dflag & mflag */
 479                         dir = NULL;
 480                         mflag = 0;
 481                 } else call_pass = 1;
 482         }
 483 
 484         if (mflag) {
 485                 if (stat(dir, &statbuf) == 0) {
 486                         /* Home directory exists */
 487                         if (check_perm(statbuf, pstruct->pw_uid,
 488                             pstruct->pw_gid, S_IWOTH|S_IXOTH) != 0) {
 489                                 errmsg(M_NO_PERM, logname, dir);
 490                                 exit(EX_NO_PERM);
 491                         }
 492 
 493                 } else ret = create_home(dir, NULL, uid, gid);







 494 
 495                 if (ret == EX_SUCCESS)
 496                         ret = move_dir(pstruct->pw_dir, dir, logname);

 497 
 498                 if (ret != EX_SUCCESS)
 499                         exit(ret);
 500         }
 501 
 502         if (shell) {
 503                 if (REL_PATH(shell)) {
 504                         errmsg(M_RELPATH, shell);
 505                         exit(EX_BADARG);
 506                 }
 507                 if (strcmp(pstruct->pw_shell, shell) == 0) {
 508                         /* ignore s option if shell is not different */
 509                         shell = NULL;
 510                 } else {
 511                         if (stat(shell, &statbuf) < 0 ||
 512                             (statbuf.st_mode & S_IFMT) != S_IFREG ||
 513                             (statbuf.st_mode & 0555) != 0555) {
 514 
 515                                 errmsg(M_INVALID, shell, "shell");
 516                                 exit(EX_BADARG);




  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/param.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <ctype.h>
  41 #include <limits.h>
  42 #include <string.h>
  43 #include <userdefs.h>
  44 #include <user_attr.h>
  45 #include <nss_dbdefs.h>
  46 #include <errno.h>
  47 #include <project.h>
  48 #include "users.h"
  49 #include "messages.h"
  50 #include "funcs.h"
  51 
  52 /*
  53  *  usermod [-u uid [-o] | -g group | -G group [[,group]...]
  54  *              | -d dir [-m [-z|Z]]
  55  *              | -s shell | -c comment | -l new_logname]
  56  *              | -f inactive | -e expire ]
  57  *              [ -A authorization [, authorization ...]]
  58  *              [ -P profile [, profile ...]]
  59  *              [ -R role [, role ...]]
  60  *              [ -K key=value ]
  61  *              [ -p project [, project]] login
  62  *
  63  *      This command adds new user logins to the system.  Arguments are:
  64  *
  65  *      uid - an integer less than MAXUID
  66  *      group - an existing group's integer ID or char string name
  67  *      dir - a directory
  68  *      shell - a program to be used as a shell
  69  *      comment - any text string
  70  *      skel_dir - a directory
  71  *      base_dir - a directory
  72  *      rid - an integer less than 2**16 (USHORT)
  73  *      login - a string of printable chars except colon (:)
  74  *      inactive - number of days a login maybe inactive before it is locked
  75  *      expire - date when a login is no longer valid
  76  *      authorization - One or more comma separated authorizations defined
  77  *                      in auth_attr(4).
  78  *      profile - One or more comma separated execution profiles defined
  79  *                in prof_attr(4)
  80  *      role - One or more comma-separated role names defined in user_attr(4)
  81  *      key=value - One or more -K options each specifying a valid user_attr(4)
  82  *              attribute.
  83  *
  84  */
  85 
  86 extern int **valid_lgroup(), isbusy(), get_default_zfs_flags();
  87 extern int valid_uid(), check_perm(), create_home(), move_dir();
  88 extern int valid_expire(), edit_group(), call_passmgmt();
  89 extern projid_t **valid_lproject();
  90 
  91 static uid_t uid;               /* new uid */
  92 static gid_t gid;                       /* gid of new login */
  93 static char *new_logname = NULL;        /* new login name with -l option */
  94 static char *uidstr = NULL;             /* uid from command line */
  95 static char *group = NULL;              /* group from command line */
  96 static char *grps = NULL;               /* multi groups from command line */
  97 static char *dir = NULL;                /* home dir from command line */
  98 static char *shell = NULL;              /* shell from command line */
  99 static char *comment = NULL;            /* comment from command line */
 100 static char *logname = NULL;            /* login name to add */
 101 static char *inactstr = NULL;           /* inactive from command line */
 102 static char *expire = NULL;             /* expiration date from command line */
 103 static char *projects = NULL;           /* project ids from command line */
 104 static char *usertype;
 105 
 106 char *cmdname;


 129         npw = malloc(sizeof (struct passwd));
 130 
 131         npw->pw_name = strcpmalloc(opw->pw_name);
 132         npw->pw_passwd = strcpmalloc(opw->pw_passwd);
 133         npw->pw_uid = opw->pw_uid;
 134         npw->pw_gid = opw->pw_gid;
 135         npw->pw_age = strcpmalloc(opw->pw_age);
 136         npw->pw_comment = strcpmalloc(opw->pw_comment);
 137         npw->pw_gecos  = strcpmalloc(opw->pw_gecos);
 138         npw->pw_dir = strcpmalloc(opw->pw_dir);
 139         npw->pw_shell = strcpmalloc(opw->pw_shell);
 140 
 141         return (npw);
 142 }
 143 
 144 int
 145 main(argc, argv)
 146 int argc;
 147 char **argv;
 148 {
 149         int ch, ret = EX_SUCCESS, call_pass = 0, oflag = 0, zfs_flags = 0;
 150         int tries, mflag = 0, inact, **gidlist, flag = 0, zflag = 0, Zflag = 0;
 151         boolean_t fail_if_busy = B_FALSE;
 152         char *ptr;
 153         struct passwd *pstruct;         /* password struct for login */
 154         struct passwd *pw;
 155         struct group *g_ptr;    /* validated group from -g */
 156         struct stat statbuf;            /* status buffer for stat */
 157 #ifndef att
 158         FILE *pwf;              /* fille ptr for opened passwd file */
 159 #endif
 160         int warning;
 161         projid_t **projlist;
 162         char **nargv;                   /* arguments for execvp of passmgmt */
 163         int argindex;                   /* argument index into nargv */
 164         userattr_t *ua;
 165         char *val;
 166         int isrole;                     /* current account is role */
 167 
 168         cmdname = argv[0];
 169 
 170         if (geteuid() != 0) {
 171                 errmsg(M_PERM_DENIED);
 172                 exit(EX_NO_PERM);
 173         }
 174 
 175         opterr = 0;                     /* no print errors from getopt */
 176         /* get user type based on the program name */
 177         usertype = getusertype(argv[0]);
 178 
 179         while ((ch = getopt(argc, argv,
 180                                 "c:d:e:f:G:g:l:mzZop:s:u:A:P:R:K:")) != EOF)
 181                 switch (ch) {
 182                 case 'c':
 183                         comment = optarg;
 184                         flag++;
 185                         break;
 186                 case 'd':
 187                         dir = optarg;
 188                         fail_if_busy = B_TRUE;
 189                         flag++;
 190                         break;
 191                 case 'e':
 192                         expire = optarg;
 193                         flag++;
 194                         break;
 195                 case 'f':
 196                         inactstr = optarg;
 197                         flag++;
 198                         break;
 199                 case 'G':
 200                         grps = optarg;


 216                         fail_if_busy = B_TRUE;
 217                         break;
 218                 case 'o':
 219                         oflag++;
 220                         flag++;
 221                         fail_if_busy = B_TRUE;
 222                         break;
 223                 case 'p':
 224                         projects = optarg;
 225                         flag++;
 226                         break;
 227                 case 's':
 228                         shell = optarg;
 229                         flag++;
 230                         break;
 231                 case 'u':
 232                         uidstr = optarg;
 233                         flag++;
 234                         fail_if_busy = B_TRUE;
 235                         break;
 236                 case 'Z':
 237                         Zflag++;
 238                         break;
 239                 case 'z':
 240                         zflag++;
 241                         break;
 242                 case 'A':
 243                         change_key(USERATTR_AUTHS_KW, optarg);
 244                         flag++;
 245                         break;
 246                 case 'P':
 247                         change_key(USERATTR_PROFILES_KW, optarg);
 248                         flag++;
 249                         break;
 250                 case 'R':
 251                         change_key(USERATTR_ROLES_KW, optarg);
 252                         flag++;
 253                         break;
 254                 case 'K':
 255                         change_key(NULL, optarg);
 256                         flag++;
 257                         break;
 258                 default:
 259                 case '?':
 260                         if (is_role(usertype))
 261                                 errmsg(M_MRUSAGE);
 262                         else
 263                                 errmsg(M_MUSAGE);
 264                         exit(EX_SYNTAX);
 265                 }
 266 
 267         if (((!mflag) && (zflag || Zflag)) || (zflag && Zflag) ||
 268             (mflag > 1 && (zflag || Zflag))) {
 269                 if (is_role(usertype))
 270                         errmsg(M_ARUSAGE);
 271                 else
 272                         errmsg(M_AUSAGE);
 273                 exit(EX_SYNTAX);
 274         }
 275 
 276 
 277         if (optind != argc - 1 || flag == 0) {
 278                 if (is_role(usertype))
 279                         errmsg(M_MRUSAGE);
 280                 else
 281                         errmsg(M_MUSAGE);
 282                 exit(EX_SYNTAX);
 283         }
 284 
 285         if ((!uidstr && oflag) || (mflag && !dir)) {
 286                 if (is_role(usertype))
 287                         errmsg(M_MRUSAGE);
 288                 else
 289                         errmsg(M_MUSAGE);
 290                 exit(EX_SYNTAX);
 291         }
 292 
 293         logname = argv[optind];
 294 
 295         /* Determine whether the account is a role or not */
 296         if ((ua = getusernam(logname)) == NULL ||


 490                 if (REL_PATH(dir)) {
 491                         errmsg(M_RELPATH, dir);
 492                         exit(EX_BADARG);
 493                 }
 494                 if (strcmp(pstruct->pw_dir, dir) == 0) {
 495                         /* home directory is the same so ignore dflag & mflag */
 496                         dir = NULL;
 497                         mflag = 0;
 498                 } else call_pass = 1;
 499         }
 500 
 501         if (mflag) {
 502                 if (stat(dir, &statbuf) == 0) {
 503                         /* Home directory exists */
 504                         if (check_perm(statbuf, pstruct->pw_uid,
 505                             pstruct->pw_gid, S_IWOTH|S_IXOTH) != 0) {
 506                                 errmsg(M_NO_PERM, logname, dir);
 507                                 exit(EX_NO_PERM);
 508                         }
 509 
 510                 } else {
 511                         zfs_flags = get_default_zfs_flags();
 512                         if (zflag || mflag > 1)
 513                                 zfs_flags |= CHANGE_ZFS_FS;
 514                         else if (Zflag)
 515                                 zfs_flags &= ~CHANGE_ZFS_FS;
 516                         ret = create_home(dir, NULL, uid, gid, zfs_flags);
 517                 }
 518 
 519                 if (ret == EX_SUCCESS)
 520                         ret = move_dir(pstruct->pw_dir, dir,
 521                             logname, zfs_flags);
 522 
 523                 if (ret != EX_SUCCESS)
 524                         exit(ret);
 525         }
 526 
 527         if (shell) {
 528                 if (REL_PATH(shell)) {
 529                         errmsg(M_RELPATH, shell);
 530                         exit(EX_BADARG);
 531                 }
 532                 if (strcmp(pstruct->pw_shell, shell) == 0) {
 533                         /* ignore s option if shell is not different */
 534                         shell = NULL;
 535                 } else {
 536                         if (stat(shell, &statbuf) < 0 ||
 537                             (statbuf.st_mode & S_IFMT) != S_IFREG ||
 538                             (statbuf.st_mode & 0555) != 0555) {
 539 
 540                                 errmsg(M_INVALID, shell, "shell");
 541                                 exit(EX_BADARG);