Print this page
4078 groupadd execs getent unnecessarily
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: Gary Mills <gary_mills@fastmail.fm>
Reviewed by: Milan Jurik <milan.jurik@xylab.cz>
Reviewed by: Gordon Ross <Gordon.W.Ross@gmail.com>


   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 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 



  29 
  30 #include        <sys/types.h>
  31 #include        <sys/stat.h>
  32 #include        <sys/param.h>
  33 #include        <stdio.h>
  34 #include        <stdlib.h>
  35 #include        <ctype.h>
  36 #include        <limits.h>
  37 #include        <string.h>
  38 #include        <userdefs.h>
  39 #include        <errno.h>
  40 #include        <project.h>
  41 #include        <unistd.h>
  42 #include        <user_attr.h>

  43 #include        "users.h"
  44 #include        "messages.h"
  45 #include        "userdisp.h"
  46 #include        "funcs.h"
  47 
  48 /*
  49  *  useradd [-u uid [-o] | -g group | -G group [[, group]...] | -d dir [-m]
  50  *              | -s shell | -c comment | -k skel_dir | -b base_dir] ]
  51  *              [ -A authorization [, authorization ...]]
  52  *              [ -P profile [, profile ...]]
  53  *              [ -K key=value ]
  54  *              [ -R role [, role ...]] [-p project [, project ...]] login
  55  *  useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
  56  *              -s shell | -k skel_dir ]
  57  *              [ -A authorization [, authorization ...]]
  58  *              [ -P profile [, profile ...]] [ -K key=value ]
  59  *              [ -R role [, role ...]] [-p project [, project ...]] login
  60  *
  61  *      This command adds new user logins to the system.  Arguments are:
  62  *


  65  *      dir - home directory
  66  *      shell - a program to be used as a shell
  67  *      comment - any text string
  68  *      skel_dir - a skeleton directory
  69  *      base_dir - a directory
  70  *      login - a string of printable chars except colon(:)
  71  *      authorization - One or more comma separated authorizations defined
  72  *                      in auth_attr(4).
  73  *      profile - One or more comma separated execution profiles defined
  74  *                in prof_attr(4)
  75  *      role - One or more comma-separated role names defined in user_attr(4)
  76  *      project - One or more comma-separated project names or numbers
  77  *
  78  */
  79 
  80 extern struct userdefs *getusrdef();
  81 extern void dispusrdef();
  82 
  83 static void cleanup();
  84 
  85 extern uid_t findnextuid(void);
  86 extern int check_perm(), valid_expire();
  87 extern int putusrdef(), valid_uid();
  88 extern int call_passmgmt(), edit_group(), create_home();
  89 extern int edit_project();
  90 extern int **valid_lgroup();
  91 extern projid_t **valid_lproject();
  92 extern void update_def(struct userdefs *);
  93 extern void import_def(struct userdefs *);
  94 
  95 static uid_t uid;                       /* new uid */
  96 static char *logname;                   /* login name to add */
  97 static struct userdefs *usrdefs;        /* defaults for useradd */
  98 
  99 char *cmdname;
 100 
 101 static char homedir[ PATH_MAX + 1 ];    /* home directory */
 102 static char gidstring[32];              /* group id string representation */
 103 static gid_t gid;                       /* gid of new login */
 104 static char uidstring[32];              /* user id string representation */
 105 static char *uidstr = NULL;             /* uid from command line */


 115 static char inactstring[10];            /* inactivity string representation */
 116 static char *expirestr = NULL;          /* expiration date from command line */
 117 static char *projects = NULL;           /* project id's from command line */
 118 
 119 static char *usertype = NULL;   /* type of user, either role or normal */
 120 
 121 typedef enum {
 122         BASEDIR = 0,
 123         SKELDIR,
 124         SHELL
 125 } path_opt_t;
 126 
 127 
 128 static void valid_input(path_opt_t, const char *);
 129 
 130 int
 131 main(argc, argv)
 132 int argc;
 133 char *argv[];
 134 {
 135         int ch, ret, mflag = 0, oflag = 0, Dflag = 0, **gidlist;
 136         projid_t **projlist;
 137         char *ptr;                      /* loc in a str, may be set by strtol */
 138         struct group *g_ptr;
 139         struct project p_ptr;
 140         char mybuf[PROJECT_BUFSZ];
 141         struct stat statbuf;            /* status buffer for stat */
 142         int warning;
 143         int busy = 0;
 144         char **nargv;                   /* arguments for execvp of passmgmt */
 145         int argindex;                   /* argument index into nargv */
 146 
 147         cmdname = argv[0];
 148 
 149         if (geteuid() != 0) {
 150                 errmsg(M_PERM_DENIED);
 151                 exit(EX_NO_PERM);
 152         }
 153 
 154         opterr = 0;                     /* no print errors from getopt */
 155         usertype = getusertype(argv[0]);
 156 


 408 
 409                 switch (valid_uid(uid, NULL)) {
 410                 case NOTUNIQUE:
 411                         if (!oflag) {
 412                                 /* override not specified */
 413                                 errmsg(M_UID_USED, uid);
 414                                 exit(EX_ID_EXISTS);
 415                         }
 416                         break;
 417                 case RESERVED:
 418                         errmsg(M_RESERVED, uid);
 419                         break;
 420                 case TOOBIG:
 421                         errmsg(M_TOOBIG, "uid", uid);
 422                         exit(EX_BADARG);
 423                         break;
 424                 }
 425 
 426         } else {
 427 
 428                 if ((uid = findnextuid()) < 0) {
 429                         errmsg(M_INVALID, "default id", "user id");
 430                         exit(EX_ID_EXISTS);
 431                 }
 432         }
 433 
 434         if (group != NULL) {
 435                 switch (valid_group(group, &g_ptr, &warning)) {
 436                 case INVALID:
 437                         errmsg(M_INVALID, group, "group id");
 438                         exit(EX_BADARG);
 439                         /*NOTREACHED*/
 440                 case TOOBIG:
 441                         errmsg(M_TOOBIG, "gid", group);
 442                         exit(EX_BADARG);
 443                         /*NOTREACHED*/
 444                 case RESERVED:
 445                 case UNIQUE:
 446                         errmsg(M_GRP_NOTUSED, group);
 447                         exit(EX_NAME_NOT_EXIST);
 448                         /*NOTREACHED*/


 617                 case PEX_SYNTAX:
 618                 case PEX_BADARG:
 619                         /* should NEVER occur that passmgmt usage is wrong */
 620                         if (is_role(usertype))
 621                                 errmsg(M_ARUSAGE);
 622                         else
 623                                 errmsg(M_AUSAGE);
 624                         exit(EX_SYNTAX);
 625                         break;
 626 
 627                 case PEX_BADUID:
 628                         /*
 629                          * The uid has been taken. If it was specified by a
 630                          * user, then we must fail. Otherwise, keep trying
 631                          * to get a good uid until we run out of IDs.
 632                          */
 633                         if (uidstr != NULL) {
 634                                 errmsg(M_UID_USED, uid);
 635                                 exit(EX_ID_EXISTS);
 636                         } else {
 637                                 if ((uid = findnextuid()) < 0) {
 638                                         errmsg(M_INVALID, "default id",
 639                                             "user id");
 640                                         exit(EX_ID_EXISTS);
 641                                 }
 642                                 (void) sprintf(uidstring, "%u", uid);
 643                         }
 644                         break;
 645 
 646                 case PEX_BADNAME:
 647                         /* invalid loname */
 648                         errmsg(M_USED, logname);
 649                         exit(EX_NAME_EXISTS);
 650                         break;
 651 
 652                 default:
 653                         errmsg(M_UPDATE, "created");
 654                         exit(ret);
 655                         break;
 656                 }
 657         }




   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 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * Copyright (c) 2013 RackTop Systems.
  31  */
  32 
  33 #include        <sys/types.h>
  34 #include        <sys/stat.h>
  35 #include        <sys/param.h>
  36 #include        <stdio.h>
  37 #include        <stdlib.h>
  38 #include        <ctype.h>
  39 #include        <limits.h>
  40 #include        <string.h>
  41 #include        <userdefs.h>
  42 #include        <errno.h>
  43 #include        <project.h>
  44 #include        <unistd.h>
  45 #include        <user_attr.h>
  46 #include        <libcmdutils.h>
  47 #include        "users.h"
  48 #include        "messages.h"
  49 #include        "userdisp.h"
  50 #include        "funcs.h"
  51 
  52 /*
  53  *  useradd [-u uid [-o] | -g group | -G group [[, group]...] | -d dir [-m]
  54  *              | -s shell | -c comment | -k skel_dir | -b base_dir] ]
  55  *              [ -A authorization [, authorization ...]]
  56  *              [ -P profile [, profile ...]]
  57  *              [ -K key=value ]
  58  *              [ -R role [, role ...]] [-p project [, project ...]] login
  59  *  useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
  60  *              -s shell | -k skel_dir ]
  61  *              [ -A authorization [, authorization ...]]
  62  *              [ -P profile [, profile ...]] [ -K key=value ]
  63  *              [ -R role [, role ...]] [-p project [, project ...]] login
  64  *
  65  *      This command adds new user logins to the system.  Arguments are:
  66  *


  69  *      dir - home directory
  70  *      shell - a program to be used as a shell
  71  *      comment - any text string
  72  *      skel_dir - a skeleton directory
  73  *      base_dir - a directory
  74  *      login - a string of printable chars except colon(:)
  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  *      project - One or more comma-separated project names or numbers
  81  *
  82  */
  83 
  84 extern struct userdefs *getusrdef();
  85 extern void dispusrdef();
  86 
  87 static void cleanup();
  88 

  89 extern int check_perm(), valid_expire();
  90 extern int putusrdef(), valid_uid();
  91 extern int call_passmgmt(), edit_group(), create_home();
  92 extern int edit_project();
  93 extern int **valid_lgroup();
  94 extern projid_t **valid_lproject();
  95 extern void update_def(struct userdefs *);
  96 extern void import_def(struct userdefs *);
  97 
  98 static uid_t uid;                       /* new uid */
  99 static char *logname;                   /* login name to add */
 100 static struct userdefs *usrdefs;        /* defaults for useradd */
 101 
 102 char *cmdname;
 103 
 104 static char homedir[ PATH_MAX + 1 ];    /* home directory */
 105 static char gidstring[32];              /* group id string representation */
 106 static gid_t gid;                       /* gid of new login */
 107 static char uidstring[32];              /* user id string representation */
 108 static char *uidstr = NULL;             /* uid from command line */


 118 static char inactstring[10];            /* inactivity string representation */
 119 static char *expirestr = NULL;          /* expiration date from command line */
 120 static char *projects = NULL;           /* project id's from command line */
 121 
 122 static char *usertype = NULL;   /* type of user, either role or normal */
 123 
 124 typedef enum {
 125         BASEDIR = 0,
 126         SKELDIR,
 127         SHELL
 128 } path_opt_t;
 129 
 130 
 131 static void valid_input(path_opt_t, const char *);
 132 
 133 int
 134 main(argc, argv)
 135 int argc;
 136 char *argv[];
 137 {
 138         int ch, ret, mflag = 0, oflag = 0, Dflag = 0, **gidlist = NULL;
 139         projid_t **projlist = NULL;
 140         char *ptr;                      /* loc in a str, may be set by strtol */
 141         struct group *g_ptr;
 142         struct project p_ptr;
 143         char mybuf[PROJECT_BUFSZ];
 144         struct stat statbuf;            /* status buffer for stat */
 145         int warning;
 146         int busy = 0;
 147         char **nargv;                   /* arguments for execvp of passmgmt */
 148         int argindex;                   /* argument index into nargv */
 149 
 150         cmdname = argv[0];
 151 
 152         if (geteuid() != 0) {
 153                 errmsg(M_PERM_DENIED);
 154                 exit(EX_NO_PERM);
 155         }
 156 
 157         opterr = 0;                     /* no print errors from getopt */
 158         usertype = getusertype(argv[0]);
 159 


 411 
 412                 switch (valid_uid(uid, NULL)) {
 413                 case NOTUNIQUE:
 414                         if (!oflag) {
 415                                 /* override not specified */
 416                                 errmsg(M_UID_USED, uid);
 417                                 exit(EX_ID_EXISTS);
 418                         }
 419                         break;
 420                 case RESERVED:
 421                         errmsg(M_RESERVED, uid);
 422                         break;
 423                 case TOOBIG:
 424                         errmsg(M_TOOBIG, "uid", uid);
 425                         exit(EX_BADARG);
 426                         break;
 427                 }
 428 
 429         } else {
 430 
 431                 if (findnextuid(DEFRID+1, MAXUID, &uid) != 0) {
 432                         errmsg(M_INVALID, "default id", "user id");
 433                         exit(EX_ID_EXISTS);
 434                 }
 435         }
 436 
 437         if (group != NULL) {
 438                 switch (valid_group(group, &g_ptr, &warning)) {
 439                 case INVALID:
 440                         errmsg(M_INVALID, group, "group id");
 441                         exit(EX_BADARG);
 442                         /*NOTREACHED*/
 443                 case TOOBIG:
 444                         errmsg(M_TOOBIG, "gid", group);
 445                         exit(EX_BADARG);
 446                         /*NOTREACHED*/
 447                 case RESERVED:
 448                 case UNIQUE:
 449                         errmsg(M_GRP_NOTUSED, group);
 450                         exit(EX_NAME_NOT_EXIST);
 451                         /*NOTREACHED*/


 620                 case PEX_SYNTAX:
 621                 case PEX_BADARG:
 622                         /* should NEVER occur that passmgmt usage is wrong */
 623                         if (is_role(usertype))
 624                                 errmsg(M_ARUSAGE);
 625                         else
 626                                 errmsg(M_AUSAGE);
 627                         exit(EX_SYNTAX);
 628                         break;
 629 
 630                 case PEX_BADUID:
 631                         /*
 632                          * The uid has been taken. If it was specified by a
 633                          * user, then we must fail. Otherwise, keep trying
 634                          * to get a good uid until we run out of IDs.
 635                          */
 636                         if (uidstr != NULL) {
 637                                 errmsg(M_UID_USED, uid);
 638                                 exit(EX_ID_EXISTS);
 639                         } else {
 640                                 if (findnextuid(DEFRID+1, MAXUID, &uid) != 0) {
 641                                         errmsg(M_INVALID, "default id",
 642                                             "user id");
 643                                         exit(EX_ID_EXISTS);
 644                                 }
 645                                 (void) sprintf(uidstring, "%u", uid);
 646                         }
 647                         break;
 648 
 649                 case PEX_BADNAME:
 650                         /* invalid loname */
 651                         errmsg(M_USED, logname);
 652                         exit(EX_NAME_EXISTS);
 653                         break;
 654 
 655                 default:
 656                         errmsg(M_UPDATE, "created");
 657                         exit(ret);
 658                         break;
 659                 }
 660         }