4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996-1999 by Internet Software Consortium.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #if !defined(LINT) && !defined(CODECENTER)
21 static const char rcsid
[] = "Id: lcl_ng.c,v 1.3 2005/04/27 04:56:31 sra Exp";
26 #include "port_before.h"
28 #include <sys/types.h>
29 #include <netinet/in.h>
30 #include <arpa/nameser.h>
39 #include <isc/memcluster.h>
41 #include "port_after.h"
48 #define NG_HOST 0 /*%< Host name */
49 #define NG_USER 1 /*%< User name */
50 #define NG_DOM 2 /*%< and Domain name */
51 #define LINSIZ 1024 /*%< Length of netgroup file line */
54 * This code is a hack-and-slash special. It realy needs to be
55 * rewritten with things like strdup, and realloc in mind.
56 * More reasonable data structures would not be a bad thing.
60 * Static Variables and functions used by setnetgrent(), getnetgrent() and
63 * There are two linked lists:
64 * \li linelist is just used by setnetgrent() to parse the net group file via.
66 * \li netgrp is the list of entries for the current netgroup
69 struct linelist
*l_next
; /*%< Chain ptr. */
70 int l_parsed
; /*%< Flag for cycles */
71 char * l_groupname
; /*%< Name of netgroup */
72 char * l_line
; /*%< Netgroup entrie(s) to be parsed */
75 struct ng_old_struct
{
76 struct ng_old_struct
*ng_next
; /*%< Chain ptr */
77 char * ng_str
[3]; /*%< Field pointers, see below */
82 struct linelist
*linehead
;
83 struct ng_old_struct
*nextgrp
;
85 struct ng_old_struct
*gr
;
92 static void ng_rewind(struct irs_ng
*, const char*);
93 static void ng_close(struct irs_ng
*);
94 static int ng_next(struct irs_ng
*, const char **,
95 const char **, const char **);
96 static int ng_test(struct irs_ng
*, const char *,
97 const char *, const char *,
99 static void ng_minimize(struct irs_ng
*);
101 static int parse_netgrp(struct irs_ng
*, const char*);
102 static struct linelist
*read_for_group(struct irs_ng
*, const char *);
103 static void freelists(struct irs_ng
*);
108 irs_lcl_ng(struct irs_acc
*this) {
114 if (!(ng
= memget(sizeof *ng
))) {
118 memset(ng
, 0x5e, sizeof *ng
);
119 if (!(pvt
= memget(sizeof *pvt
))) {
120 memput(ng
, sizeof *ng
);
124 memset(pvt
, 0, sizeof *pvt
);
126 ng
->close
= ng_close
;
129 ng
->rewind
= ng_rewind
;
130 ng
->minimize
= ng_minimize
;
137 ng_close(struct irs_ng
*this) {
138 struct pvt
*pvt
= (struct pvt
*)this->private;
143 memput(pvt
, sizeof *pvt
);
144 memput(this, sizeof *this);
148 * Parse the netgroup file looking for the netgroup and build the list
149 * of netgrp structures. Let parse_netgrp() and read_for_group() do
153 ng_rewind(struct irs_ng
*this, const char *group
) {
154 struct pvt
*pvt
= (struct pvt
*)this->private;
156 if (pvt
->fp
!= NULL
&& fseek(pvt
->fp
, SEEK_CUR
, 0L) == -1) {
161 if (pvt
->fp
== NULL
|| pvt
->grouphead
.gr
== NULL
||
162 strcmp(group
, pvt
->grouphead
.grname
)) {
166 pvt
->fp
= fopen(_PATH_NETGROUP
, "r");
167 if (pvt
->fp
!= NULL
) {
168 if (parse_netgrp(this, group
))
170 if (!(pvt
->grouphead
.grname
= strdup(group
)))
176 pvt
->nextgrp
= pvt
->grouphead
.gr
;
180 * Get the next netgroup off the list.
183 ng_next(struct irs_ng
*this, const char **host
, const char **user
,
186 struct pvt
*pvt
= (struct pvt
*)this->private;
189 *host
= pvt
->nextgrp
->ng_str
[NG_HOST
];
190 *user
= pvt
->nextgrp
->ng_str
[NG_USER
];
191 *domain
= pvt
->nextgrp
->ng_str
[NG_DOM
];
192 pvt
->nextgrp
= pvt
->nextgrp
->ng_next
;
199 * Search for a match in a netgroup.
202 ng_test(struct irs_ng
*this, const char *name
,
203 const char *host
, const char *user
, const char *domain
)
205 const char *ng_host
, *ng_user
, *ng_domain
;
207 ng_rewind(this, name
);
208 while (ng_next(this, &ng_host
, &ng_user
, &ng_domain
))
209 if ((host
== NULL
|| ng_host
== NULL
||
210 !strcmp(host
, ng_host
)) &&
211 (user
== NULL
|| ng_user
== NULL
||
212 !strcmp(user
, ng_user
)) &&
213 (domain
== NULL
|| ng_domain
== NULL
||
214 !strcmp(domain
, ng_domain
))) {
223 ng_minimize(struct irs_ng
*this) {
224 struct pvt
*pvt
= (struct pvt
*)this->private;
226 if (pvt
->fp
!= NULL
) {
227 (void)fclose(pvt
->fp
);
235 * endnetgrent() - cleanup
238 freelists(struct irs_ng
*this) {
239 struct pvt
*pvt
= (struct pvt
*)this->private;
240 struct linelist
*lp
, *olp
;
241 struct ng_old_struct
*gp
, *ogp
;
247 free(olp
->l_groupname
);
251 pvt
->linehead
= NULL
;
252 if (pvt
->grouphead
.grname
) {
253 free(pvt
->grouphead
.grname
);
254 pvt
->grouphead
.grname
= NULL
;
256 gp
= pvt
->grouphead
.gr
;
260 if (ogp
->ng_str
[NG_HOST
])
261 free(ogp
->ng_str
[NG_HOST
]);
262 if (ogp
->ng_str
[NG_USER
])
263 free(ogp
->ng_str
[NG_USER
]);
264 if (ogp
->ng_str
[NG_DOM
])
265 free(ogp
->ng_str
[NG_DOM
]);
268 pvt
->grouphead
.gr
= NULL
;
272 * Parse the netgroup file setting up the linked lists.
275 parse_netgrp(struct irs_ng
*this, const char *group
) {
276 struct pvt
*pvt
= (struct pvt
*)this->private;
280 struct ng_old_struct
*grp
;
281 struct linelist
*lp
= pvt
->linehead
;
284 * First, see if the line has already been read in.
287 if (!strcmp(group
, lp
->l_groupname
))
292 (lp
= read_for_group(this, group
)) == NULL
)
295 /*fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);*/
300 while (*pos
!= '\0') {
302 if (!(grp
= malloc(sizeof (struct ng_old_struct
)))) {
307 memset(grp
, 0, sizeof (struct ng_old_struct
));
308 grp
->ng_next
= pvt
->grouphead
.gr
;
309 pvt
->grouphead
.gr
= grp
;
311 gpos
= strsep(&pos
, ")");
312 for (strpos
= 0; strpos
< 3; strpos
++) {
313 if ((spos
= strsep(&gpos
, ","))) {
314 while (*spos
== ' ' || *spos
== '\t')
316 if ((epos
= strpbrk(spos
, " \t"))) {
322 if(!(grp
->ng_str
[strpos
]
328 memcpy(grp
->ng_str
[strpos
],
336 spos
= strsep(&pos
, ", \t");
337 if (spos
!= NULL
&& parse_netgrp(this, spos
)) {
344 while (*pos
== ' ' || *pos
== ',' || *pos
== '\t')
349 /*fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname,
355 * Read the netgroup file and save lines until the line for the netgroup
356 * is found. Return 1 if eof is encountered.
358 static struct linelist
*
359 read_for_group(struct irs_ng
*this, const char *group
) {
360 struct pvt
*pvt
= (struct pvt
*)this->private;
361 char *pos
, *spos
, *linep
= NULL
, *olinep
;
364 char line
[LINSIZ
+ 1];
366 while (fgets(line
, LINSIZ
, pvt
->fp
) != NULL
) {
370 while (*pos
== ' ' || *pos
== '\t')
373 while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\n' &&
377 while (*pos
== ' ' || *pos
== '\t')
379 if (*pos
!= '\n' && *pos
!= '\0') {
380 if (!(lp
= malloc(sizeof (*lp
)))) {
385 if (!(lp
->l_groupname
= malloc(len
+ 1))) {
390 memcpy(lp
->l_groupname
, spos
, len
);
391 *(lp
->l_groupname
+ len
) = '\0';
397 * Loop around handling line continuations.
400 if (*(pos
+ len
- 1) == '\n')
402 if (*(pos
+ len
- 1) == '\\') {
408 if (!(linep
= malloc(olen
+ len
+ 1))){
411 free(lp
->l_groupname
);
418 memcpy(linep
, olinep
, olen
);
421 memcpy(linep
+ olen
, pos
, len
);
423 *(linep
+ olen
) = '\0';
427 if (fgets(line
, LINSIZ
, pvt
->fp
)) {
435 lp
->l_next
= pvt
->linehead
;
439 * If this is the one we wanted, we are done.
441 if (!strcmp(lp
->l_groupname
, group
))