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.
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.
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]
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
27 * For SUNWnskit - version 1.1
36 #include <rpcsvc/ypclnt.h>
41 #define MAXDOMAINLEN 256
42 #define MAXGROUPLEN 1024
45 * Reverse the netgroup file. A flag of "-u" means reverse by username,
46 * one of "-h" means reverse by hostname. Each line in the output file
47 * will begin with a key formed by concatenating the host or user name
48 * with the domain name. The key will be followed by a tab, then the
49 * comma-separated, newline-terminated list of groups to which the
50 * user or host belongs.
52 * Exception: Groups to which everyone belongs (universal groups) will
53 * not be included in the list. The universal groups will be listed under
54 * the special name "*".
56 * Thus to find out all the groups that user "foo" of domain "bar" is in,
57 * lookup the groups under foo.bar, foo.*, *.bar and *.*.
63 /* Stores a list of strings */
64 typedef struct stringnode
*stringlist
;
69 typedef struct stringnode stringnode
;
73 /* Stores a list of (name,list-of-groups) */
74 typedef struct groupentrynode
*groupentrylist
;
75 struct groupentrynode
{
80 typedef struct groupentrynode groupentrynode
;
84 static groupentrylist grouptable
[TABLESIZE
];
86 static char *nextgroup(void);
87 static void storegroup(char *group
, struct grouplist
*glist
, int byuser
);
88 static void enter(char *name
, char *group
);
89 static void appendgroup(groupentrylist grlist
, char *group
);
90 static groupentrylist
newentry(char *name
, char *group
);
91 static void loadtable(FILE *nf
);
92 static void dumptable(void);
100 struct grouplist
*glist
;
104 if (argc
== 2 && argv
[1][0] == '-' &&
105 (argv
[1][1] == 'u' || argv
[1][1] == 'h')) {
106 byuser
= (argv
[1][1] == 'u');
108 (void) fprintf(stderr
,
109 "usage: %s -h (by host), %s -u (by user)\n",
114 while (group
= nextgroup()) {
115 glist
= my_getgroup(group
);
116 storegroup(group
, glist
, byuser
);
124 * Get the next netgroup from /etc/netgroup
129 static int index
= -1;
130 static tablelist cur
= NULL
;
133 while (cur
== NULL
) {
134 if (++index
== TABLESIZE
) {
137 cur
= ngtable
[index
];
147 * Dump out all of the stored info into a file
153 groupentrylist entry
;
156 for (i
= 0; i
< TABLESIZE
; i
++) {
157 if (entry
= grouptable
[i
]) {
159 fputs(entry
->name
, stdout
);
161 for (groups
= entry
->groups
; groups
;
162 groups
= groups
->next
) {
163 fputs(groups
->str
, stdout
);
179 * Add a netgroup to a user's list of netgroups
182 storegroup(char *group
, struct grouplist
*glist
, int byuser
)
184 char *name
; /* username or hostname */
187 static char *universal
= "*";
189 for (; glist
; glist
= glist
->gl_nxt
) {
190 name
= byuser
? glist
->gl_name
: glist
->gl_machine
;
193 } else if (!isalnum(*name
) && *name
!= '_') {
196 domain
= glist
->gl_domain
;
200 key
= malloc((unsigned) (strlen(name
)+strlen(domain
)+2));
201 (void) sprintf(key
, "%s.%s", name
, domain
);
208 static groupentrylist
209 newentry(char *name
, char *group
)
213 new = MALLOC(groupentrynode
);
215 STRCPY(new->name
, name
);
217 new->groups
= MALLOC(stringnode
);
218 new->groups
->str
= group
;
219 new->groups
->next
= NULL
;
226 appendgroup(groupentrylist grlist
, char *group
)
228 stringlist cur
, prev
;
230 for (cur
= grlist
->groups
; cur
; prev
= cur
, cur
= cur
->next
) {
231 if (strcmp(group
, cur
->str
) == 0) {
235 prev
->next
= MALLOC(stringnode
);
242 enter(char *name
, char *group
)
246 groupentrylist gelprev
;
248 key
= tablekey(name
);
249 if (grouptable
[key
] == NULL
) {
250 grouptable
[key
] = newentry(name
, group
);
252 gel
= grouptable
[key
];
253 while (gel
&& strcmp(gel
->name
, name
)) {
258 appendgroup(gel
, group
);
260 gelprev
->next
= newentry(name
, group
);
266 * Load up a hash table with the info in /etc/netgroup
271 char buf
[MAXGROUPLEN
];
276 while (getaline(buf
, MAXGROUPLEN
, nf
)) {
277 for (p
= buf
; *p
&& isspace((int)*p
); p
++)
278 ; /* skip leading blanks */
279 for (; *p
&& *p
!= '#' && *p
!= ' ' && *p
!= '\t'; p
++)
281 if (*p
== EOS
|| *p
== '#')
285 while (*p
== ' ' || *p
== '\t') {
288 if (*p
== EOS
|| *p
== '#')
293 store(ngtable
, group
, line
);