xref: /onnv-gate/usr/src/cmd/oamuser/group/gid.c (revision 4321:a8930ec16e52)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
26 /*	  All Rights Reserved  	*/
27 
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.5 */
30 
31 #include <sys/types.h>
32 #include <stdio.h>
33 #include <userdefs.h>
34 
35 #include <sys/param.h>
36 #ifndef	MAXUID
37 #include <limits.h>
38 #ifdef UID_MAX
39 #define	MAXUID	UID_MAX
40 #else
41 #define	MAXUID	60000
42 #endif
43 #endif
44 
45 /*
46  * Check to see that the gid is not a reserved gid
47  * -- nobody, noaccess or nogroup
48  */
49 static int
isvalidgid(gid_t gid)50 isvalidgid(gid_t gid)
51 {
52 	return (gid != 60001 && gid != 60002 && gid != 65534);
53 }
54 
55 gid_t
findnextgid()56 findnextgid()
57 {
58 	FILE *fptr;
59 	gid_t last, next;
60 	gid_t gid;
61 
62 	/*
63 	 * Sort the used GIDs in decreasing order to return MAXUSED + 1
64 	 */
65 	if ((fptr = popen("exec sh -c "
66 	    "\"getent group|cut -f3 -d:|sort -nr|uniq \" 2>/dev/null",
67 	    "r")) == NULL)
68 		return (-1);
69 
70 	if (fscanf(fptr, "%u\n", &next) == EOF) {
71 		(void) pclose(fptr);
72 		return (DEFRID + 1);
73 	}
74 
75 	/*
76 	 * 'next' is now the highest allocated gid.
77 	 *
78 	 * The simplest allocation is where we just add one, and obtain
79 	 * a valid gid.  If this fails look for a hole in the gid range ..
80 	 */
81 
82 	last = MAXUID;		/* upper limit */
83 	gid = -1;		/* start invalid */
84 	do {
85 		if (!isvalidgid(next))
86 			continue;
87 
88 		if (next <= DEFRID) {
89 			if (last != DEFRID + 1)
90 				gid = DEFRID + 1;
91 			break;
92 		}
93 
94 		if ((gid = next + 1) != last) {
95 			while (!isvalidgid(gid))
96 				gid++;
97 			if (gid > 0 && gid < last)
98 				break;
99 		}
100 
101 		gid = -1;
102 		last = next;
103 
104 	} while (fscanf(fptr, "%u\n", &next) != EOF);
105 
106 	(void) pclose(fptr);
107 
108 	return (gid);
109 }
110