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


  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        <errno.h>
  45 #include        <project.h>
  46 #include        <unistd.h>
  47 #include        <user_attr.h>
  48 #include        <libcmdutils.h>
  49 #include        "users.h"
  50 #include        "messages.h"
  51 #include        "userdisp.h"
  52 #include        "funcs.h"
  53 
  54 /*
  55  *  useradd [-u uid [-o] | -g group | -G group [[, group]...] | -d dir [-m]

  56  *              | -s shell | -c comment | -k skel_dir | -b base_dir] ]
  57  *              [ -A authorization [, authorization ...]]
  58  *              [ -P profile [, profile ...]]
  59  *              [ -K key=value ]
  60  *              [ -R role [, role ...]] [-p project [, project ...]] login
  61  *  useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
  62  *              -s shell | -k skel_dir ]
  63  *              [ -A authorization [, authorization ...]]
  64  *              [ -P profile [, profile ...]] [ -K key=value ]
  65  *              [ -R role [, role ...]] [-p project [, project ...]] login
  66  *
  67  *      This command adds new user logins to the system.  Arguments are:
  68  *
  69  *      uid - an integer
  70  *      group - an existing group's integer ID or char string name
  71  *      dir - home directory
  72  *      shell - a program to be used as a shell
  73  *      comment - any text string
  74  *      skel_dir - a skeleton directory
  75  *      base_dir - a directory


  79  *      profile - One or more comma separated execution profiles defined
  80  *                in prof_attr(4)
  81  *      role - One or more comma-separated role names defined in user_attr(4)
  82  *      project - One or more comma-separated project names or numbers
  83  *
  84  */
  85 
  86 extern struct userdefs *getusrdef();
  87 extern void dispusrdef();
  88 
  89 static void cleanup();
  90 
  91 extern int check_perm(), valid_expire();
  92 extern int putusrdef(), valid_uid();
  93 extern int call_passmgmt(), edit_group(), create_home();
  94 extern int edit_project();
  95 extern int **valid_lgroup();
  96 extern projid_t **valid_lproject();
  97 extern void update_def(struct userdefs *);
  98 extern void import_def(struct userdefs *);

  99 
 100 static uid_t uid;                       /* new uid */
 101 static char *logname;                   /* login name to add */
 102 static struct userdefs *usrdefs;        /* defaults for useradd */
 103 
 104 char *cmdname;
 105 
 106 static char homedir[ PATH_MAX + 1 ];    /* home directory */
 107 static char gidstring[32];              /* group id string representation */
 108 static gid_t gid;                       /* gid of new login */
 109 static char uidstring[32];              /* user id string representation */
 110 static char *uidstr = NULL;             /* uid from command line */
 111 static char *base_dir = NULL;           /* base_dir from command line */
 112 static char *group = NULL;              /* group from command line */
 113 static char *grps = NULL;               /* multi groups from command line */
 114 static char *dir = NULL;                /* home dir from command line */
 115 static char *shell = NULL;              /* shell from command line */
 116 static char *comment = NULL;            /* comment from command line */
 117 static char *skel_dir = NULL;           /* skel dir from command line */
 118 static long inact;                      /* inactive days */


 120 static char inactstring[10];            /* inactivity string representation */
 121 static char *expirestr = NULL;          /* expiration date from command line */
 122 static char *projects = NULL;           /* project id's from command line */
 123 
 124 static char *usertype = NULL;   /* type of user, either role or normal */
 125 
 126 typedef enum {
 127         BASEDIR = 0,
 128         SKELDIR,
 129         SHELL
 130 } path_opt_t;
 131 
 132 
 133 static void valid_input(path_opt_t, const char *);
 134 
 135 int
 136 main(argc, argv)
 137 int argc;
 138 char *argv[];
 139 {
 140         int ch, ret, mflag = 0, oflag = 0, Dflag = 0, **gidlist = NULL;

 141         projid_t **projlist = NULL;
 142         char *ptr;                      /* loc in a str, may be set by strtol */
 143         struct group *g_ptr;
 144         struct project p_ptr;
 145         char mybuf[PROJECT_BUFSZ];
 146         struct stat statbuf;            /* status buffer for stat */
 147         int warning;
 148         int busy = 0;
 149         char **nargv;                   /* arguments for execvp of passmgmt */
 150         int argindex;                   /* argument index into nargv */

 151 
 152         cmdname = argv[0];
 153 
 154         if (geteuid() != 0) {
 155                 errmsg(M_PERM_DENIED);
 156                 exit(EX_NO_PERM);
 157         }
 158 
 159         opterr = 0;                     /* no print errors from getopt */
 160         usertype = getusertype(argv[0]);
 161 
 162         change_key(USERATTR_TYPE_KW, usertype);
 163 
 164         while ((ch = getopt(argc, argv,
 165                     "b:c:Dd:e:f:G:g:k:mop:s:u:A:P:R:K:")) != EOF)
 166                 switch (ch) {
 167                 case 'b':
 168                         base_dir = optarg;
 169                         break;
 170 
 171                 case 'c':
 172                         comment = optarg;
 173                         break;
 174 
 175                 case 'D':
 176                         Dflag++;
 177                         break;
 178 
 179                 case 'd':
 180                         dir = optarg;
 181                         break;
 182 
 183                 case 'e':
 184                         expirestr = optarg;
 185                         break;


 203                 case 'm':
 204                         mflag++;
 205                         break;
 206 
 207                 case 'o':
 208                         oflag++;
 209                         break;
 210 
 211                 case 'p':
 212                         projects = optarg;
 213                         break;
 214 
 215                 case 's':
 216                         shell = optarg;
 217                         break;
 218 
 219                 case 'u':
 220                         uidstr = optarg;
 221                         break;
 222 








 223                 case 'A':
 224                         change_key(USERATTR_AUTHS_KW, optarg);
 225                         break;
 226 
 227                 case 'P':
 228                         change_key(USERATTR_PROFILES_KW, optarg);
 229                         break;
 230 
 231                 case 'R':
 232                         if (is_role(usertype)) {
 233                                 errmsg(M_ARUSAGE);
 234                                 exit(EX_SYNTAX);
 235                         }
 236                         change_key(USERATTR_ROLES_KW, optarg);
 237                         break;
 238 
 239                 case 'K':
 240                         change_key(NULL, optarg);
 241                         break;
 242 
 243                 default:
 244                 case '?':
 245                         if (is_role(usertype))
 246                                 errmsg(M_ARUSAGE);
 247                         else
 248                                 errmsg(M_AUSAGE);
 249                         exit(EX_SYNTAX);
 250                 }
 251 










 252         /* get defaults for adding new users */
 253         usrdefs = getusrdef(usertype);
 254 
 255         if (Dflag) {
 256                 /* DISPLAY mode */
 257 
 258                 /* check syntax */
 259                 if (optind != argc) {
 260                         if (is_role(usertype))
 261                                 errmsg(M_ARUSAGE);
 262                         else
 263                                 errmsg(M_AUSAGE);
 264                         exit(EX_SYNTAX);
 265                 }
 266 
 267                 if (uidstr != NULL || oflag || grps != NULL ||
 268                     dir != NULL || mflag || comment != NULL) {
 269                         if (is_role(usertype))
 270                                 errmsg(M_ARUSAGE);
 271                         else


 669                 errmsg(M_UPDATE, "created");
 670                 exit(ret);
 671         }
 672 
 673         /* add group entry */
 674         if ((grps != NULL) && edit_group(logname, (char *)0, gidlist, 0)) {
 675                 errmsg(M_UPDATE, "created");
 676                 cleanup(logname);
 677                 exit(EX_UPDATE);
 678         }
 679 
 680         /* update project database */
 681         if ((projects != NULL) &&
 682             edit_project(logname, (char *)NULL, projlist, 0)) {
 683                 errmsg(M_UPDATE, "created");
 684                 cleanup(logname);
 685                 exit(EX_UPDATE);
 686         }
 687 
 688         /* create home directory */
 689         if (mflag &&
 690             (create_home(homedir, skel_dir, uid, gid) != EX_SUCCESS)) {










 691                 (void) edit_group(logname, (char *)0, (int **)0, 1);
 692                 cleanup(logname);
 693                 exit(EX_HOMEDIR);
 694         }
 695 
 696         return (ret);
 697 }
 698 
 699 static void
 700 cleanup(logname)
 701 char *logname;
 702 {
 703         char *nargv[4];
 704 
 705         nargv[0] = PASSMGMT;
 706         nargv[1] = "-d";
 707         nargv[2] = logname;
 708         nargv[3] = NULL;
 709 
 710         switch (call_passmgmt(nargv)) {




  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        <errno.h>
  45 #include        <project.h>
  46 #include        <unistd.h>
  47 #include        <user_attr.h>
  48 #include        <libcmdutils.h>
  49 #include        "users.h"
  50 #include        "messages.h"
  51 #include        "userdisp.h"
  52 #include        "funcs.h"
  53 
  54 /*
  55  *  useradd [-u uid [-o] | -g group | -G group [[, group]...]
  56  *              | -d dir [-m [-z|Z]]
  57  *              | -s shell | -c comment | -k skel_dir | -b base_dir] ]
  58  *              [ -A authorization [, authorization ...]]
  59  *              [ -P profile [, profile ...]]
  60  *              [ -K key=value ]
  61  *              [ -R role [, role ...]] [-p project [, project ...]] login
  62  *  useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
  63  *              -s shell | -k skel_dir ]
  64  *              [ -A authorization [, authorization ...]]
  65  *              [ -P profile [, profile ...]] [ -K key=value ]
  66  *              [ -R role [, role ...]] [-p project [, project ...]] login
  67  *
  68  *      This command adds new user logins to the system.  Arguments are:
  69  *
  70  *      uid - an integer
  71  *      group - an existing group's integer ID or char string name
  72  *      dir - home directory
  73  *      shell - a program to be used as a shell
  74  *      comment - any text string
  75  *      skel_dir - a skeleton directory
  76  *      base_dir - a directory


  80  *      profile - One or more comma separated execution profiles defined
  81  *                in prof_attr(4)
  82  *      role - One or more comma-separated role names defined in user_attr(4)
  83  *      project - One or more comma-separated project names or numbers
  84  *
  85  */
  86 
  87 extern struct userdefs *getusrdef();
  88 extern void dispusrdef();
  89 
  90 static void cleanup();
  91 
  92 extern int check_perm(), valid_expire();
  93 extern int putusrdef(), valid_uid();
  94 extern int call_passmgmt(), edit_group(), create_home();
  95 extern int edit_project();
  96 extern int **valid_lgroup();
  97 extern projid_t **valid_lproject();
  98 extern void update_def(struct userdefs *);
  99 extern void import_def(struct userdefs *);
 100 extern int get_default_zfs_flags();
 101 
 102 static uid_t uid;                       /* new uid */
 103 static char *logname;                   /* login name to add */
 104 static struct userdefs *usrdefs;        /* defaults for useradd */
 105 
 106 char *cmdname;
 107 
 108 static char homedir[ PATH_MAX + 1 ];    /* home directory */
 109 static char gidstring[32];              /* group id string representation */
 110 static gid_t gid;                       /* gid of new login */
 111 static char uidstring[32];              /* user id string representation */
 112 static char *uidstr = NULL;             /* uid from command line */
 113 static char *base_dir = NULL;           /* base_dir from command line */
 114 static char *group = NULL;              /* group from command line */
 115 static char *grps = NULL;               /* multi groups from command line */
 116 static char *dir = NULL;                /* home dir from command line */
 117 static char *shell = NULL;              /* shell from command line */
 118 static char *comment = NULL;            /* comment from command line */
 119 static char *skel_dir = NULL;           /* skel dir from command line */
 120 static long inact;                      /* inactive days */


 122 static char inactstring[10];            /* inactivity string representation */
 123 static char *expirestr = NULL;          /* expiration date from command line */
 124 static char *projects = NULL;           /* project id's from command line */
 125 
 126 static char *usertype = NULL;   /* type of user, either role or normal */
 127 
 128 typedef enum {
 129         BASEDIR = 0,
 130         SKELDIR,
 131         SHELL
 132 } path_opt_t;
 133 
 134 
 135 static void valid_input(path_opt_t, const char *);
 136 
 137 int
 138 main(argc, argv)
 139 int argc;
 140 char *argv[];
 141 {
 142         int ch, ret, mflag = 0, oflag = 0, Dflag = 0;
 143         int zflag = 0, Zflag = 0, **gidlist = NULL;
 144         projid_t **projlist = NULL;
 145         char *ptr;                      /* loc in a str, may be set by strtol */
 146         struct group *g_ptr;
 147         struct project p_ptr;
 148         char mybuf[PROJECT_BUFSZ];
 149         struct stat statbuf;            /* status buffer for stat */
 150         int warning;
 151         int busy = 0;
 152         char **nargv;                   /* arguments for execvp of passmgmt */
 153         int argindex;                   /* argument index into nargv */
 154         int zfs_flags = 0;                      /* create_home flags */
 155 
 156         cmdname = argv[0];
 157 
 158         if (geteuid() != 0) {
 159                 errmsg(M_PERM_DENIED);
 160                 exit(EX_NO_PERM);
 161         }
 162 
 163         opterr = 0;                     /* no print errors from getopt */
 164         usertype = getusertype(argv[0]);
 165 
 166         change_key(USERATTR_TYPE_KW, usertype);
 167 
 168         while ((ch = getopt(argc, argv,
 169                     "b:c:Dd:e:f:G:g:k:mzZop:s:u:A:P:R:K:")) != EOF)
 170                 switch (ch) {
 171                 case 'b':
 172                         base_dir = optarg;
 173                         break;
 174 
 175                 case 'c':
 176                         comment = optarg;
 177                         break;
 178 
 179                 case 'D':
 180                         Dflag++;
 181                         break;
 182 
 183                 case 'd':
 184                         dir = optarg;
 185                         break;
 186 
 187                 case 'e':
 188                         expirestr = optarg;
 189                         break;


 207                 case 'm':
 208                         mflag++;
 209                         break;
 210 
 211                 case 'o':
 212                         oflag++;
 213                         break;
 214 
 215                 case 'p':
 216                         projects = optarg;
 217                         break;
 218 
 219                 case 's':
 220                         shell = optarg;
 221                         break;
 222 
 223                 case 'u':
 224                         uidstr = optarg;
 225                         break;
 226 
 227                 case 'Z':
 228                         Zflag++;
 229                         break;
 230 
 231                 case 'z':
 232                         zflag++;
 233                         break;
 234 
 235                 case 'A':
 236                         change_key(USERATTR_AUTHS_KW, optarg);
 237                         break;
 238 
 239                 case 'P':
 240                         change_key(USERATTR_PROFILES_KW, optarg);
 241                         break;
 242 
 243                 case 'R':
 244                         if (is_role(usertype)) {
 245                                 errmsg(M_ARUSAGE);
 246                                 exit(EX_SYNTAX);
 247                         }
 248                         change_key(USERATTR_ROLES_KW, optarg);
 249                         break;
 250 
 251                 case 'K':
 252                         change_key(NULL, optarg);
 253                         break;
 254 
 255                 default:
 256                 case '?':
 257                         if (is_role(usertype))
 258                                 errmsg(M_ARUSAGE);
 259                         else
 260                                 errmsg(M_AUSAGE);
 261                         exit(EX_SYNTAX);
 262                 }
 263 
 264         if (((!mflag) && (zflag || Zflag)) || (zflag && Zflag) ||
 265             (mflag > 1 && (zflag || Zflag))) {
 266                 if (is_role(usertype))
 267                         errmsg(M_ARUSAGE);
 268                 else
 269                         errmsg(M_AUSAGE);
 270                 exit(EX_SYNTAX);
 271         }
 272 
 273 
 274         /* get defaults for adding new users */
 275         usrdefs = getusrdef(usertype);
 276 
 277         if (Dflag) {
 278                 /* DISPLAY mode */
 279 
 280                 /* check syntax */
 281                 if (optind != argc) {
 282                         if (is_role(usertype))
 283                                 errmsg(M_ARUSAGE);
 284                         else
 285                                 errmsg(M_AUSAGE);
 286                         exit(EX_SYNTAX);
 287                 }
 288 
 289                 if (uidstr != NULL || oflag || grps != NULL ||
 290                     dir != NULL || mflag || comment != NULL) {
 291                         if (is_role(usertype))
 292                                 errmsg(M_ARUSAGE);
 293                         else


 691                 errmsg(M_UPDATE, "created");
 692                 exit(ret);
 693         }
 694 
 695         /* add group entry */
 696         if ((grps != NULL) && edit_group(logname, (char *)0, gidlist, 0)) {
 697                 errmsg(M_UPDATE, "created");
 698                 cleanup(logname);
 699                 exit(EX_UPDATE);
 700         }
 701 
 702         /* update project database */
 703         if ((projects != NULL) &&
 704             edit_project(logname, (char *)NULL, projlist, 0)) {
 705                 errmsg(M_UPDATE, "created");
 706                 cleanup(logname);
 707                 exit(EX_UPDATE);
 708         }
 709 
 710         /* create home directory */
 711         if (mflag) {
 712                 zfs_flags = get_default_zfs_flags();
 713 
 714                 if (zflag || mflag > 1)
 715                         zfs_flags |= CHANGE_ZFS_FS;
 716                 else if (Zflag)
 717                         zfs_flags &= ~CHANGE_ZFS_FS;
 718                 ret = create_home(homedir, skel_dir, uid, gid, zfs_flags);
 719         }
 720         if (ret != EX_SUCCESS) {
 721                 (void) edit_project(logname, (char *)NULL, (projid_t **)NULL,
 722                     0);
 723                 (void) edit_group(logname, (char *)0, (int **)0, 1);
 724                 cleanup(logname);
 725                 exit(EX_HOMEDIR);
 726         }
 727 
 728         return (ret);
 729 }
 730 
 731 static void
 732 cleanup(logname)
 733 char *logname;
 734 {
 735         char *nargv[4];
 736 
 737         nargv[0] = PASSMGMT;
 738         nargv[1] = "-d";
 739         nargv[2] = logname;
 740         nargv[3] = NULL;
 741 
 742         switch (call_passmgmt(nargv)) {