1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * Copyright (c) 2013 RackTop Systems.
  32  */
  33 
  34 #include        <sys/types.h>
  35 #include        <sys/param.h>
  36 #include        <stdio.h>
  37 #include        <stdlib.h>
  38 #include        <ctype.h>
  39 #include        <limits.h>
  40 #include        <userdefs.h>
  41 #include        <users.h>
  42 #include        <errno.h>
  43 #include        <libcmdutils.h>
  44 #include        "messages.h"
  45 
  46 extern int errmsg();
  47 extern int valid_gid(), add_group();
  48 
  49 /*
  50  *  groupadd [-g gid [-o]] group
  51  *
  52  *      This command adds new groups to the system.  Arguments are:
  53  *
  54  *      gid - a gid_t less than MAXUID
  55  *      group - a string of printable characters excluding colon(:) and less
  56  *              than MAXGLEN characters long.
  57  */
  58 
  59 char *cmdname = "groupadd";
  60 
  61 int
  62 main(int argc, char *argv[])
  63 {
  64         int ch;                         /* return from getopt */
  65         gid_t gid;                      /* group id */
  66         int oflag = 0;  /* flags */
  67         int rc;
  68         char *gidstr = NULL;    /* gid from command line */
  69         char *grpname;                  /* group name from command line */
  70         int warning;
  71 
  72         while ((ch = getopt(argc, argv, "g:o")) != EOF)
  73                 switch (ch) {
  74                         case 'g':
  75                                 gidstr = optarg;
  76                                 break;
  77                         case 'o':
  78                                 oflag++;
  79                                 break;
  80                         case '?':
  81                                 errmsg(M_AUSAGE);
  82                                 exit(EX_SYNTAX);
  83                 }
  84 
  85         if ((oflag && !gidstr) || optind != argc - 1) {
  86                 errmsg(M_AUSAGE);
  87                 exit(EX_SYNTAX);
  88         }
  89 
  90         grpname = argv[optind];
  91 
  92         switch (valid_gname(grpname, NULL, &warning)) {
  93         case INVALID:
  94                 errmsg(M_GRP_INVALID, grpname);
  95                 exit(EX_BADARG);
  96                 /*NOTREACHED*/
  97         case NOTUNIQUE:
  98                 errmsg(M_GRP_USED, grpname);
  99                 exit(EX_NAME_EXISTS);
 100                 /*NOTREACHED*/
 101         }
 102         if (warning)
 103                 warningmsg(warning, grpname);
 104 
 105         if (gidstr) {
 106                 /* Given a gid string - validate it */
 107                 char *ptr;
 108 
 109                 errno = 0;
 110                 gid = (gid_t)strtol(gidstr, &ptr, 10);
 111 
 112                 if (*ptr || errno == ERANGE) {
 113                         errmsg(M_GID_INVALID, gidstr);
 114                         exit(EX_BADARG);
 115                 }
 116 
 117                 switch (valid_gid(gid, NULL)) {
 118                 case RESERVED:
 119                         errmsg(M_RESERVED, gid);
 120                         break;
 121 
 122                 case NOTUNIQUE:
 123                         if (!oflag) {
 124                                 errmsg(M_GRP_USED, gidstr);
 125                                 exit(EX_ID_EXISTS);
 126                         }
 127                         break;
 128 
 129                 case INVALID:
 130                         errmsg(M_GID_INVALID, gidstr);
 131                         exit(EX_BADARG);
 132 
 133                 case TOOBIG:
 134                         errmsg(M_TOOBIG, gid);
 135                         exit(EX_BADARG);
 136 
 137                 }
 138 
 139         } else {
 140 
 141                 if (findnextgid(DEFRID+1, MAXUID, &gid) != 0) {
 142                         errmsg(M_GID_INVALID, "default id");
 143                         exit(EX_ID_EXISTS);
 144                 }
 145 
 146         }
 147 
 148         if ((rc = add_group(grpname, gid)) != EX_SUCCESS)
 149                 errmsg(M_UPDATE, "created");
 150 
 151         return (rc);
 152 }