1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 33*7c478bd9Sstevel@tonic-gate #include <unistd.h> 34*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 35*7c478bd9Sstevel@tonic-gate #include <stdio.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <ctype.h> 38*7c478bd9Sstevel@tonic-gate #include <pwd.h> 39*7c478bd9Sstevel@tonic-gate #include <errno.h> 40*7c478bd9Sstevel@tonic-gate #include <locale.h> 41*7c478bd9Sstevel@tonic-gate #include <limits.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #define BADLINE "Too many/few fields" 44*7c478bd9Sstevel@tonic-gate #define TOOLONG "Line too long" 45*7c478bd9Sstevel@tonic-gate #define NONAME "No group name" 46*7c478bd9Sstevel@tonic-gate #define BADNAME "Bad character(s) in group name" 47*7c478bd9Sstevel@tonic-gate #define BADGID "Invalid GID" 48*7c478bd9Sstevel@tonic-gate #define NULLNAME "Null login name" 49*7c478bd9Sstevel@tonic-gate #define NOTFOUND "Logname not found in password file" 50*7c478bd9Sstevel@tonic-gate #define DUPNAME "Duplicate logname entry" 51*7c478bd9Sstevel@tonic-gate #define DUPNAME2 "Duplicate logname entry (gid first occurs in passwd entry)" 52*7c478bd9Sstevel@tonic-gate #define NOMEM "Out of memory" 53*7c478bd9Sstevel@tonic-gate #define NGROUPS "Maximum groups exceeded for logname " 54*7c478bd9Sstevel@tonic-gate #define BLANKLINE "Blank line detected. Please remove line" 55*7c478bd9Sstevel@tonic-gate #define LONGNAME "Group name too long" 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate int eflag, badchar, baddigit, badlognam, colons, len; 58*7c478bd9Sstevel@tonic-gate static int longnam = 0; 59*7c478bd9Sstevel@tonic-gate int code; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate #define MYBUFSIZE (LINE_MAX) /* max line length including newline and null */ 62*7c478bd9Sstevel@tonic-gate #define NUM_COLONS 3 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate char *buf; 65*7c478bd9Sstevel@tonic-gate char *nptr; 66*7c478bd9Sstevel@tonic-gate char *cptr; 67*7c478bd9Sstevel@tonic-gate FILE *fptr; 68*7c478bd9Sstevel@tonic-gate gid_t gid; 69*7c478bd9Sstevel@tonic-gate int error(); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate struct group { 72*7c478bd9Sstevel@tonic-gate struct group *nxt; 73*7c478bd9Sstevel@tonic-gate int cnt; 74*7c478bd9Sstevel@tonic-gate gid_t grp; 75*7c478bd9Sstevel@tonic-gate }; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate struct node { 78*7c478bd9Sstevel@tonic-gate struct node *next; 79*7c478bd9Sstevel@tonic-gate int ngroups; 80*7c478bd9Sstevel@tonic-gate struct group *groups; 81*7c478bd9Sstevel@tonic-gate char user[1]; 82*7c478bd9Sstevel@tonic-gate }; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate void * 85*7c478bd9Sstevel@tonic-gate emalloc(size) 86*7c478bd9Sstevel@tonic-gate { 87*7c478bd9Sstevel@tonic-gate void *vp; 88*7c478bd9Sstevel@tonic-gate vp = malloc(size); 89*7c478bd9Sstevel@tonic-gate if (vp == NULL) { 90*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s\n", gettext(NOMEM)); 91*7c478bd9Sstevel@tonic-gate exit(1); 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate return (vp); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate main(argc, argv) 97*7c478bd9Sstevel@tonic-gate int argc; 98*7c478bd9Sstevel@tonic-gate char *argv[]; 99*7c478bd9Sstevel@tonic-gate { 100*7c478bd9Sstevel@tonic-gate struct passwd *pwp; 101*7c478bd9Sstevel@tonic-gate struct node *root = NULL; 102*7c478bd9Sstevel@tonic-gate struct node *t; 103*7c478bd9Sstevel@tonic-gate struct group *gp; 104*7c478bd9Sstevel@tonic-gate int ngroups_max; 105*7c478bd9Sstevel@tonic-gate int ngroups = 0; 106*7c478bd9Sstevel@tonic-gate int listlen; 107*7c478bd9Sstevel@tonic-gate int i; 108*7c478bd9Sstevel@tonic-gate int lineno = 0; 109*7c478bd9Sstevel@tonic-gate char *buf_off, *tmpbuf; 110*7c478bd9Sstevel@tonic-gate int delim[NUM_COLONS + 1], buf_len, bufsize; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 115*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 116*7c478bd9Sstevel@tonic-gate #endif 117*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate code = 0; 120*7c478bd9Sstevel@tonic-gate ngroups_max = sysconf(_SC_NGROUPS_MAX); 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate if (argc == 1) 123*7c478bd9Sstevel@tonic-gate argv[1] = "/etc/group"; 124*7c478bd9Sstevel@tonic-gate else if (argc != 2) { 125*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("usage: %s filename\n"), *argv); 126*7c478bd9Sstevel@tonic-gate exit(1); 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate if ((fptr = fopen(argv[1], "r")) == NULL) { 130*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("cannot open file %s: %s\n"), argv[1], 131*7c478bd9Sstevel@tonic-gate strerror(errno)); 132*7c478bd9Sstevel@tonic-gate exit(1); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate #ifdef ORIG_SVR4 136*7c478bd9Sstevel@tonic-gate while ((pwp = getpwent()) != NULL) { 137*7c478bd9Sstevel@tonic-gate t = (struct node *)emalloc(sizeof (*t) + strlen(pwp->pw_name)); 138*7c478bd9Sstevel@tonic-gate t->next = root; 139*7c478bd9Sstevel@tonic-gate root = t; 140*7c478bd9Sstevel@tonic-gate strcpy(t->user, pwp->pw_name); 141*7c478bd9Sstevel@tonic-gate t->ngroups = 1; 142*7c478bd9Sstevel@tonic-gate if (!ngroups_max) 143*7c478bd9Sstevel@tonic-gate t->groups = NULL; 144*7c478bd9Sstevel@tonic-gate else { 145*7c478bd9Sstevel@tonic-gate t->groups = (struct group *) 146*7c478bd9Sstevel@tonic-gate emalloc(sizeof (struct group)); 147*7c478bd9Sstevel@tonic-gate t->groups->grp = pwp->pw_gid; 148*7c478bd9Sstevel@tonic-gate t->groups->cnt = 1; 149*7c478bd9Sstevel@tonic-gate t->groups->nxt = NULL; 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate #endif 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate bufsize = MYBUFSIZE; 155*7c478bd9Sstevel@tonic-gate if ((buf = malloc(bufsize)) == NULL) { 156*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(NOMEM)); 157*7c478bd9Sstevel@tonic-gate exit(1); 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate while (!feof(fptr) && !ferror(fptr)) { 160*7c478bd9Sstevel@tonic-gate buf_len = 0; 161*7c478bd9Sstevel@tonic-gate buf_off = buf; 162*7c478bd9Sstevel@tonic-gate while (fgets(buf_off, (bufsize - buf_len), fptr) != NULL) { 163*7c478bd9Sstevel@tonic-gate buf_len += strlen(buf_off); 164*7c478bd9Sstevel@tonic-gate if (buf[buf_len - 1] == '\n' || feof(fptr)) 165*7c478bd9Sstevel@tonic-gate break; 166*7c478bd9Sstevel@tonic-gate tmpbuf = realloc(buf, (bufsize + MYBUFSIZE)); 167*7c478bd9Sstevel@tonic-gate if (tmpbuf == NULL) { 168*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(NOMEM)); 169*7c478bd9Sstevel@tonic-gate exit(1); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate bufsize += MYBUFSIZE; 172*7c478bd9Sstevel@tonic-gate buf = tmpbuf; 173*7c478bd9Sstevel@tonic-gate buf_off = buf + buf_len; 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate if (buf_len == 0) 176*7c478bd9Sstevel@tonic-gate continue; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* Report error to be consistent with libc */ 179*7c478bd9Sstevel@tonic-gate if ((buf_len + 1) > LINE_MAX) 180*7c478bd9Sstevel@tonic-gate error(TOOLONG); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate lineno++; 183*7c478bd9Sstevel@tonic-gate if (buf[0] == '\n') /* blank lines are ignored */ 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate code = 1; /* exit with error code = 1 */ 186*7c478bd9Sstevel@tonic-gate eflag = 0; /* force print of "blank" line */ 187*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\n%s %d\n", gettext(BLANKLINE), 188*7c478bd9Sstevel@tonic-gate lineno); 189*7c478bd9Sstevel@tonic-gate continue; 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate if (buf[buf_len - 1] == '\n') { 193*7c478bd9Sstevel@tonic-gate if ((tmpbuf = strdup(buf)) == NULL) { 194*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(NOMEM)); 195*7c478bd9Sstevel@tonic-gate exit(1); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate tmpbuf[buf_len - 1] = ','; 198*7c478bd9Sstevel@tonic-gate } else { 199*7c478bd9Sstevel@tonic-gate if ((tmpbuf = malloc(buf_len + 2)) == NULL) { 200*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(NOMEM)); 201*7c478bd9Sstevel@tonic-gate exit(1); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate (void) strcpy(tmpbuf, buf); 204*7c478bd9Sstevel@tonic-gate tmpbuf[buf_len++] = ','; 205*7c478bd9Sstevel@tonic-gate tmpbuf[buf_len] = '\0'; 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate colons = 0; 209*7c478bd9Sstevel@tonic-gate eflag = 0; 210*7c478bd9Sstevel@tonic-gate badchar = 0; 211*7c478bd9Sstevel@tonic-gate baddigit = 0; 212*7c478bd9Sstevel@tonic-gate badlognam = 0; 213*7c478bd9Sstevel@tonic-gate gid = (gid_t)0; 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate ngroups++; /* Increment number of groups found */ 216*7c478bd9Sstevel@tonic-gate /* Check that entry is not a nameservice redirection */ 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate if (buf[0] == '+' || buf[0] == '-') { 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * Should set flag here to allow special case checking 221*7c478bd9Sstevel@tonic-gate * in the rest of the code, 222*7c478bd9Sstevel@tonic-gate * but for now, we'll just ignore this entry. 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate free(tmpbuf); 225*7c478bd9Sstevel@tonic-gate continue; 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* Check number of fields */ 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate for (i = 0; buf[i] != NULL; i++) 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate if (buf[i] == ':') 233*7c478bd9Sstevel@tonic-gate { 234*7c478bd9Sstevel@tonic-gate delim[colons] = i; 235*7c478bd9Sstevel@tonic-gate if (++colons > NUM_COLONS) 236*7c478bd9Sstevel@tonic-gate break; 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate if (colons != NUM_COLONS) 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate error(BADLINE); 242*7c478bd9Sstevel@tonic-gate free(tmpbuf); 243*7c478bd9Sstevel@tonic-gate continue; 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* check to see that group name is at least 1 character */ 247*7c478bd9Sstevel@tonic-gate /* and that all characters are lowrcase or digits. */ 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate if (buf[0] == ':') 250*7c478bd9Sstevel@tonic-gate error(NONAME); 251*7c478bd9Sstevel@tonic-gate else 252*7c478bd9Sstevel@tonic-gate { 253*7c478bd9Sstevel@tonic-gate for (i = 0; buf[i] != ':'; i++) 254*7c478bd9Sstevel@tonic-gate { 255*7c478bd9Sstevel@tonic-gate if (i >= LOGNAME_MAX) 256*7c478bd9Sstevel@tonic-gate longnam++; 257*7c478bd9Sstevel@tonic-gate if (!(islower(buf[i]) || isdigit(buf[i]))) 258*7c478bd9Sstevel@tonic-gate badchar++; 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate if (longnam > 0) 261*7c478bd9Sstevel@tonic-gate error(LONGNAME); 262*7c478bd9Sstevel@tonic-gate if (badchar > 0) 263*7c478bd9Sstevel@tonic-gate error(BADNAME); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* check that GID is numeric and <= 31 bits */ 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate len = (delim[2] - delim[1]) - 1; 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate if (len > 10 || len < 1) 271*7c478bd9Sstevel@tonic-gate error(BADGID); 272*7c478bd9Sstevel@tonic-gate else { 273*7c478bd9Sstevel@tonic-gate for (i = (delim[1]+1); i < delim[2]; i++) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate if (! (isdigit(buf[i]))) 276*7c478bd9Sstevel@tonic-gate baddigit++; 277*7c478bd9Sstevel@tonic-gate else if (baddigit == 0) 278*7c478bd9Sstevel@tonic-gate gid = gid * 10 + (gid_t)(buf[i] - '0'); 279*7c478bd9Sstevel@tonic-gate /* converts ascii GID to decimal */ 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate if (baddigit > 0) 282*7c478bd9Sstevel@tonic-gate error(BADGID); 283*7c478bd9Sstevel@tonic-gate else if (gid < (gid_t)0) 284*7c478bd9Sstevel@tonic-gate error(BADGID); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* check that logname appears in the passwd file */ 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate nptr = &tmpbuf[delim[2]]; 290*7c478bd9Sstevel@tonic-gate nptr++; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate listlen = strlen(nptr) - 1; 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate while ((cptr = strchr(nptr, ',')) != NULL) 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate *cptr = NULL; 297*7c478bd9Sstevel@tonic-gate if (*nptr == NULL) 298*7c478bd9Sstevel@tonic-gate { 299*7c478bd9Sstevel@tonic-gate if (listlen) 300*7c478bd9Sstevel@tonic-gate error(NULLNAME); 301*7c478bd9Sstevel@tonic-gate nptr++; 302*7c478bd9Sstevel@tonic-gate continue; 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate for (t = root; t != NULL; t = t->next) { 306*7c478bd9Sstevel@tonic-gate if (strcmp(t->user, nptr) == 0) 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate if (t == NULL) { 310*7c478bd9Sstevel@tonic-gate #ifndef ORIG_SVR4 311*7c478bd9Sstevel@tonic-gate /* 312*7c478bd9Sstevel@tonic-gate * User entry not found, so check if in 313*7c478bd9Sstevel@tonic-gate * password file 314*7c478bd9Sstevel@tonic-gate */ 315*7c478bd9Sstevel@tonic-gate struct passwd *pwp; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate if ((pwp = getpwnam(nptr)) == NULL) { 318*7c478bd9Sstevel@tonic-gate #endif 319*7c478bd9Sstevel@tonic-gate badlognam++; 320*7c478bd9Sstevel@tonic-gate error(NOTFOUND); 321*7c478bd9Sstevel@tonic-gate goto getnext; 322*7c478bd9Sstevel@tonic-gate #ifndef ORIG_SVR4 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* Usrname found, so add entry to user-list */ 326*7c478bd9Sstevel@tonic-gate t = (struct node *) 327*7c478bd9Sstevel@tonic-gate emalloc(sizeof (*t) + strlen(nptr)); 328*7c478bd9Sstevel@tonic-gate t->next = root; 329*7c478bd9Sstevel@tonic-gate root = t; 330*7c478bd9Sstevel@tonic-gate strcpy(t->user, nptr); 331*7c478bd9Sstevel@tonic-gate t->ngroups = 1; 332*7c478bd9Sstevel@tonic-gate if (!ngroups_max) 333*7c478bd9Sstevel@tonic-gate t->groups = NULL; 334*7c478bd9Sstevel@tonic-gate else { 335*7c478bd9Sstevel@tonic-gate t->groups = (struct group *) 336*7c478bd9Sstevel@tonic-gate emalloc(sizeof (struct group)); 337*7c478bd9Sstevel@tonic-gate t->groups->grp = pwp->pw_gid; 338*7c478bd9Sstevel@tonic-gate t->groups->cnt = 1; 339*7c478bd9Sstevel@tonic-gate t->groups->nxt = NULL; 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate #endif 343*7c478bd9Sstevel@tonic-gate if (!ngroups_max) 344*7c478bd9Sstevel@tonic-gate goto getnext; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate t->ngroups++; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* 349*7c478bd9Sstevel@tonic-gate * check for duplicate logname in group 350*7c478bd9Sstevel@tonic-gate */ 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate for (gp = t->groups; gp != NULL; gp = gp->nxt) { 353*7c478bd9Sstevel@tonic-gate if (gid == gp->grp) { 354*7c478bd9Sstevel@tonic-gate if (gp->cnt++ == 1) { 355*7c478bd9Sstevel@tonic-gate badlognam++; 356*7c478bd9Sstevel@tonic-gate if (gp->nxt == NULL) 357*7c478bd9Sstevel@tonic-gate error(DUPNAME2); 358*7c478bd9Sstevel@tonic-gate else 359*7c478bd9Sstevel@tonic-gate error(DUPNAME); 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate goto getnext; 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate gp = (struct group *)emalloc(sizeof (struct group)); 366*7c478bd9Sstevel@tonic-gate gp->grp = gid; 367*7c478bd9Sstevel@tonic-gate gp->cnt = 1; 368*7c478bd9Sstevel@tonic-gate gp->nxt = t->groups; 369*7c478bd9Sstevel@tonic-gate t->groups = gp; 370*7c478bd9Sstevel@tonic-gate getnext: 371*7c478bd9Sstevel@tonic-gate nptr = ++cptr; 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate free(tmpbuf); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate if (ngroups == 0) { 377*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Group file '%s' is empty\n"), argv[1]); 378*7c478bd9Sstevel@tonic-gate code = 1; 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate if (ngroups_max) { 382*7c478bd9Sstevel@tonic-gate for (t = root; t != NULL; t = t->next) { 383*7c478bd9Sstevel@tonic-gate if (t->ngroups > ngroups_max) { 384*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\n\n%s%s (%d)\n", 385*7c478bd9Sstevel@tonic-gate NGROUPS, t->user, t->ngroups); 386*7c478bd9Sstevel@tonic-gate code = 1; 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate exit(code); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* Error printing routine */ 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate error(msg) 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate char *msg; 398*7c478bd9Sstevel@tonic-gate { 399*7c478bd9Sstevel@tonic-gate code = 1; 400*7c478bd9Sstevel@tonic-gate if (eflag == 0) 401*7c478bd9Sstevel@tonic-gate { 402*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\n\n%s", buf); 403*7c478bd9Sstevel@tonic-gate eflag = 1; 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate if (longnam != 0) 406*7c478bd9Sstevel@tonic-gate { 407*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t%s\n", gettext(msg)); 408*7c478bd9Sstevel@tonic-gate longnam = 0; 409*7c478bd9Sstevel@tonic-gate return; 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate if (badchar != 0) 412*7c478bd9Sstevel@tonic-gate { 413*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t%d %s\n", badchar, gettext(msg)); 414*7c478bd9Sstevel@tonic-gate badchar = 0; 415*7c478bd9Sstevel@tonic-gate return; 416*7c478bd9Sstevel@tonic-gate } else if (baddigit != 0) 417*7c478bd9Sstevel@tonic-gate { 418*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t%s\n", gettext(msg)); 419*7c478bd9Sstevel@tonic-gate baddigit = 0; 420*7c478bd9Sstevel@tonic-gate return; 421*7c478bd9Sstevel@tonic-gate } else if (badlognam != 0) 422*7c478bd9Sstevel@tonic-gate { 423*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t%s - %s\n", nptr, gettext(msg)); 424*7c478bd9Sstevel@tonic-gate badlognam = 0; 425*7c478bd9Sstevel@tonic-gate return; 426*7c478bd9Sstevel@tonic-gate } else 427*7c478bd9Sstevel@tonic-gate { 428*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t%s\n", gettext(msg)); 429*7c478bd9Sstevel@tonic-gate return; 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate } 432