1 /* $NetBSD: parse_netgroup.c,v 1.5 2003/07/14 05:55:39 itojun Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/cdefs.h>
38 __RCSID("$NetBSD: parse_netgroup.c,v 1.5 2003/07/14 05:55:39 itojun Exp $");
42 * This is a specially hacked-up version of getnetgrent.c used to parse
43 * data from the stored hash table of netgroup info rather than from a
44 * file. It's used mainly for the parse_netgroup() function. All the YP
45 * stuff and file support has been stripped out since it isn't needed.
56 * Static Variables and functions used by rng_setnetgrent(), rng_getnetgrent()
57 * and rng_endnetgrent().
59 * There are two linked lists:
60 * - linelist is just used by setnetgrent() to parse the net group file via.
62 * - netgrp is the list of entries for the current netgroup
65 struct linelist
*l_next
; /* Chain ptr. */
66 int l_parsed
; /* Flag for cycles */
67 char *l_groupname
; /* Name of netgroup */
68 char *l_line
; /* Netgroup entrie(s) to be parsed */
72 struct netgrp
*ng_next
; /* Chain ptr */
73 char *ng_str
[3]; /* Field pointers, see below */
75 #define NG_HOST 0 /* Host name */
76 #define NG_USER 1 /* User name */
77 #define NG_DOM 2 /* and Domain name */
79 static struct linelist
*linehead
= (struct linelist
*)0;
80 static struct netgrp
*nextgrp
= (struct netgrp
*)0;
89 extern struct group_entry
*gtable
[];
91 static int parse_netgrp(const char *);
92 static struct linelist
*read_for_group(const char *);
97 * Parse the netgroup file looking for the netgroup and build the list
98 * of netgrp structures. Let parse_netgrp() and read_for_group() do
102 rng_setnetgrent(const char *group
)
106 if (group
== NULL
|| !strlen(group
))
109 if (grouphead
.gr
== (struct netgrp
*)0 ||
110 strcmp(group
, grouphead
.grname
)) {
112 if (parse_netgrp(group
))
115 grouphead
.grname
= strdup(group
);
117 nextgrp
= grouphead
.gr
;
121 * Get the next netgroup off the list.
124 rng_getnetgrent(char **hostp
, char **userp
, char **domp
)
127 *hostp
= nextgrp
->ng_str
[NG_HOST
];
128 *userp
= nextgrp
->ng_str
[NG_USER
];
129 *domp
= nextgrp
->ng_str
[NG_DOM
];
130 nextgrp
= nextgrp
->ng_next
;
137 * rng_endnetgrent() - cleanup
140 rng_endnetgrent(void)
142 struct linelist
*lp
, *olp
;
143 struct netgrp
*gp
, *ogp
;
149 free(olp
->l_groupname
);
153 linehead
= (struct linelist
*)0;
154 if (grouphead
.grname
) {
155 free(grouphead
.grname
);
156 grouphead
.grname
= (char *)0;
162 if (ogp
->ng_str
[NG_HOST
])
163 free(ogp
->ng_str
[NG_HOST
]);
164 if (ogp
->ng_str
[NG_USER
])
165 free(ogp
->ng_str
[NG_USER
]);
166 if (ogp
->ng_str
[NG_DOM
])
167 free(ogp
->ng_str
[NG_DOM
]);
170 grouphead
.gr
= (struct netgrp
*)0;
174 * Parse the netgroup file setting up the linked lists.
177 parse_netgrp(const char *group
)
186 struct linelist
*lp
= linehead
;
189 * First, see if the line has already been read in.
192 if (!strcmp(group
, lp
->l_groupname
))
196 if (lp
== (struct linelist
*)0 &&
197 (lp
= read_for_group(group
)) == (struct linelist
*)0)
202 * This error message is largely superflous since the
203 * code handles the error condition successfully, and
204 * spewing it out from inside libc can actually hose
207 warnx("Cycle in netgroup %s", lp
->l_groupname
);
213 /* Watch for null pointer dereferences, dammit! */
214 while (pos
!= NULL
&& *pos
!= '\0') {
216 grp
= (struct netgrp
*)malloc(sizeof (struct netgrp
));
217 memset((char *)grp
, 0, sizeof (struct netgrp
));
218 grp
->ng_next
= grouphead
.gr
;
221 gpos
= strsep(&pos
, ")");
225 for (strpos
= 0; strpos
< 3; strpos
++) {
226 if ((spos
= strsep(&gpos
, ","))) {
230 while (*spos
== ' ' || *spos
== '\t')
232 if ((epos
= strpbrk(spos
, " \t"))) {
238 grp
->ng_str
[strpos
] = (char *)
240 memmove(grp
->ng_str
[strpos
],
245 * All other systems I've tested
246 * return NULL for empty netgroup
247 * fields. It's up to user programs
248 * to handle the NULLs appropriately.
250 grp
->ng_str
[strpos
] = NULL
;
255 * Note: on other platforms, malformed netgroup
256 * entries are not normally flagged. While we
257 * can catch bad entries and report them, we should
258 * stay silent by default for compatibility's sake.
262 "Bad entry (%s%s%s%s%s) in netgroup \"%s\"",
263 grp
->ng_str
[NG_HOST
] == NULL
? "" :
264 grp
->ng_str
[NG_HOST
],
265 grp
->ng_str
[NG_USER
] == NULL
? "" : ",",
266 grp
->ng_str
[NG_USER
] == NULL
? "" :
267 grp
->ng_str
[NG_USER
],
268 grp
->ng_str
[NG_DOM
] == NULL
? "" : ",",
269 grp
->ng_str
[NG_DOM
] == NULL
? "" :
274 spos
= strsep(&pos
, ", \t");
275 if (parse_netgrp(spos
))
278 /* Watch for null pointer dereferences, dammit! */
280 while (*pos
== ' ' || *pos
== ',' || *pos
== '\t')
287 * Read the netgroup file and save lines until the line for the netgroup
288 * is found. Return 1 if eof is encountered.
290 static struct linelist
*
291 read_for_group(const char *group
)
293 char *pos
, *spos
, *linep
= NULL
, *olinep
= NULL
;
297 char line
[LINSIZ
+ 1];
300 data
= lookup (gtable
, group
);
301 snprintf(line
, sizeof(line
), "%s %s", group
, data
);
307 while (*pos
== ' ' || *pos
== '\t')
310 while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\n' &&
314 while (*pos
== ' ' || *pos
== '\t')
316 if (*pos
!= '\n' && *pos
!= '\0') {
317 lp
= (struct linelist
*)malloc(sizeof (*lp
));
319 lp
->l_groupname
= (char *)malloc(len
+ 1);
320 memmove(lp
->l_groupname
, spos
, len
);
321 *(lp
->l_groupname
+ len
) = '\0';
325 * Loop around handling line continuations.
328 if (*(pos
+ len
- 1) == '\n')
330 if (*(pos
+ len
- 1) == '\\') {
336 linep
= (char *)malloc(olen
+ len
+ 1);
338 memmove(linep
, olinep
, olen
);
341 memmove(linep
+ olen
, pos
, len
);
343 *(linep
+ olen
) = '\0';
348 if (fgets(line
, LINSIZ
, netf
)) {
357 lp
->l_next
= linehead
;
361 * If this is the one we wanted, we are done.
363 if (!strcmp(lp
->l_groupname
, group
))
367 return ((struct linelist
*)0);