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 #pragma ident   "%Z%%M% %I%     %E% SMI"
  32 
  33 #include        <sys/types.h>
  34 #include        <stdio.h>
  35 #include        <stdlib.h>
  36 #include        <ctype.h>
  37 #include        <limits.h>
  38 #include        <userdefs.h>
  39 #include        <users.h>
  40 #include        <errno.h>
  41 #include        "messages.h"
  42 
  43 extern int errmsg();
  44 extern gid_t findnextgid();
  45 extern int valid_gid(), add_group();
  46 
  47 /*
  48  *  groupadd [-g gid [-o]] group
  49  *
  50  *      This command adds new groups to the system.  Arguments are:
  51  *
  52  *      gid - a gid_t less than MAXUID
  53  *      group - a string of printable characters excluding colon(:) and less
  54  *              than MAXGLEN characters long.
  55  */
  56 
  57 char *cmdname = "groupadd";
  58 
  59 int
  60 main(int argc, char *argv[])
  61 {
  62         int ch;                         /* return from getopt */
  63         gid_t gid;                      /* group id */
  64         int oflag = 0;  /* flags */
  65         int rc;
  66         char *gidstr = NULL;    /* gid from command line */
  67         char *grpname;                  /* group name from command line */
  68         int warning;
  69 
  70         while ((ch = getopt(argc, argv, "g:o")) != EOF)
  71                 switch (ch) {
  72                         case 'g':
  73                                 gidstr = optarg;
  74                                 break;
  75                         case 'o':
  76                                 oflag++;
  77                                 break;
  78                         case '?':
  79                                 errmsg(M_AUSAGE);
  80                                 exit(EX_SYNTAX);
  81                 }
  82 
  83         if ((oflag && !gidstr) || optind != argc - 1) {
  84                 errmsg(M_AUSAGE);
  85                 exit(EX_SYNTAX);
  86         }
  87 
  88         grpname = argv[optind];
  89 
  90         switch (valid_gname(grpname, NULL, &warning)) {
  91         case INVALID:
  92                 errmsg(M_GRP_INVALID, grpname);
  93                 exit(EX_BADARG);
  94                 /*NOTREACHED*/
  95         case NOTUNIQUE:
  96                 errmsg(M_GRP_USED, grpname);
  97                 exit(EX_NAME_EXISTS);
  98                 /*NOTREACHED*/
  99         }
 100         if (warning)
 101                 warningmsg(warning, grpname);
 102 
 103         if (gidstr) {
 104                 /* Given a gid string - validate it */
 105                 char *ptr;
 106 
 107                 errno = 0;
 108                 gid = (gid_t)strtol(gidstr, &ptr, 10);
 109 
 110                 if (*ptr || errno == ERANGE) {
 111                         errmsg(M_GID_INVALID, gidstr);
 112                         exit(EX_BADARG);
 113                 }
 114 
 115                 switch (valid_gid(gid, NULL)) {
 116                 case RESERVED:
 117                         errmsg(M_RESERVED, gid);
 118                         break;
 119 
 120                 case NOTUNIQUE:
 121                         if (!oflag) {
 122                                 errmsg(M_GRP_USED, gidstr);
 123                                 exit(EX_ID_EXISTS);
 124                         }
 125                         break;
 126 
 127                 case INVALID:
 128                         errmsg(M_GID_INVALID, gidstr);
 129                         exit(EX_BADARG);
 130 
 131                 case TOOBIG:
 132                         errmsg(M_TOOBIG, gid);
 133                         exit(EX_BADARG);
 134 
 135                 }
 136 
 137         } else {
 138 
 139                 if ((gid = findnextgid()) < 0) {
 140                         errmsg(M_GID_INVALID, "default id");
 141                         exit(EX_ID_EXISTS);
 142                 }
 143 
 144         }
 145 
 146         if ((rc = add_group(grpname, gid)) != EX_SUCCESS)
 147                 errmsg(M_UPDATE, "created");
 148 
 149         return (rc);
 150 }