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