xref: /illumos-gate/usr/src/cmd/oamuser/user/val_lgrp.c (revision 3fe80ca4a1f8a033d672a9a2e6e4babac651205a)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 /*
30  * Copyright (c) 2013 RackTop Systems.
31  */
32 
33 
34 #include	<sys/types.h>
35 #include	<stdio.h>
36 #include	<stdlib.h>
37 #include	<sys/param.h>
38 #include	<unistd.h>
39 #include	<users.h>
40 #include	<userdefs.h>
41 #include	"messages.h"
42 
43 extern void exit();
44 extern char *strtok();
45 
46 static gid_t *grplist;
47 static int ngroups_max = 0;
48 
49 /* Validate a list of groups */
50 int	**
51 valid_lgroup(char *list, gid_t gid)
52 {
53 	int n_invalid = 0, i = 0, j;
54 	char *ptr;
55 	struct group *g_ptr;
56 	int warning;
57 	int dup_prim = 0; /* we don't duplicate our primary as a supplemental */
58 
59 	if( !list || !*list )
60 		return( (int **) NULL );
61 
62 	if (ngroups_max == 0) {
63 		ngroups_max = sysconf(_SC_NGROUPS_MAX);
64 		grplist = malloc((ngroups_max + 1) * sizeof (gid_t));
65 	}
66 
67 	while ((ptr = strtok((i || n_invalid || dup_prim)? NULL: list, ","))) {
68 
69 		switch (valid_group(ptr, &g_ptr, &warning)) {
70 		case INVALID:
71 			errmsg( M_INVALID, ptr, "group id" );
72 			n_invalid++;
73 			break;
74 		case TOOBIG:
75 			errmsg( M_TOOBIG, "gid", ptr );
76 			n_invalid++;
77 			break;
78 		case UNIQUE:
79 			errmsg( M_GRP_NOTUSED, ptr );
80 			n_invalid++;
81 			break;
82 		case NOTUNIQUE:
83 			/* ignore duplicated primary */
84 			if (g_ptr->gr_gid == gid) {
85 				if (!dup_prim)
86 					dup_prim++;
87 				continue;
88 			}
89 
90 			if( !i )
91 				grplist[ i++ ] = g_ptr->gr_gid;
92 			else {
93 				/* Keep out duplicates */
94 				for( j = 0; j < i; j++ )
95 					if( g_ptr->gr_gid == grplist[j] )
96 						break;
97 
98 				if( j == i )
99 					/* Not a duplicate */
100 					grplist[i++] = g_ptr->gr_gid;
101 			}
102 			break;
103 
104 		}
105 		if (warning)
106 			warningmsg(warning, ptr);
107 
108 		if( i >= ngroups_max ) {
109 			errmsg( M_MAXGROUPS, ngroups_max );
110 			break;
111 		}
112 	}
113 
114 	/* Terminate the list */
115 	grplist[ i ] = -1;
116 
117 	if( n_invalid )
118 		exit( EX_BADARG );
119 
120 	return( (int **)grplist );
121 }
122