1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 1997-2002 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* 7*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996-1999 by Internet Software Consortium. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 10*7c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 11*7c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14*7c478bd9Sstevel@tonic-gate * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15*7c478bd9Sstevel@tonic-gate * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16*7c478bd9Sstevel@tonic-gate * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17*7c478bd9Sstevel@tonic-gate * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18*7c478bd9Sstevel@tonic-gate * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19*7c478bd9Sstevel@tonic-gate * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20*7c478bd9Sstevel@tonic-gate * SOFTWARE. 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate 23*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 26*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "$Id: lcl_ng.c,v 1.17 2001/05/29 05:49:05 marka Exp $"; 27*7c478bd9Sstevel@tonic-gate #endif 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* Imports */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include "port_before.h" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 35*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 36*7c478bd9Sstevel@tonic-gate #include <resolv.h> 37*7c478bd9Sstevel@tonic-gate #include <errno.h> 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 40*7c478bd9Sstevel@tonic-gate #include <string.h> 41*7c478bd9Sstevel@tonic-gate #include <unistd.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #include <irs.h> 44*7c478bd9Sstevel@tonic-gate #include <isc/memcluster.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #include "port_after.h" 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #include "irs_p.h" 49*7c478bd9Sstevel@tonic-gate #include "lcl_p.h" 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate /* Definitions */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define NG_HOST 0 /* Host name */ 54*7c478bd9Sstevel@tonic-gate #define NG_USER 1 /* User name */ 55*7c478bd9Sstevel@tonic-gate #define NG_DOM 2 /* and Domain name */ 56*7c478bd9Sstevel@tonic-gate #define LINSIZ 1024 /* Length of netgroup file line */ 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate * XXX Warning XXX 60*7c478bd9Sstevel@tonic-gate * This code is a hack-and-slash special. It realy needs to be 61*7c478bd9Sstevel@tonic-gate * rewritten with things like strdup, and realloc in mind. 62*7c478bd9Sstevel@tonic-gate * More reasonable data structures would not be a bad thing. 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * Static Variables and functions used by setnetgrent(), getnetgrent() and 67*7c478bd9Sstevel@tonic-gate * endnetgrent(). 68*7c478bd9Sstevel@tonic-gate * There are two linked lists: 69*7c478bd9Sstevel@tonic-gate * - linelist is just used by setnetgrent() to parse the net group file via. 70*7c478bd9Sstevel@tonic-gate * parse_netgrp() 71*7c478bd9Sstevel@tonic-gate * - netgrp is the list of entries for the current netgroup 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate struct linelist { 74*7c478bd9Sstevel@tonic-gate struct linelist *l_next; /* Chain ptr. */ 75*7c478bd9Sstevel@tonic-gate int l_parsed; /* Flag for cycles */ 76*7c478bd9Sstevel@tonic-gate char * l_groupname; /* Name of netgroup */ 77*7c478bd9Sstevel@tonic-gate char * l_line; /* Netgroup entrie(s) to be parsed */ 78*7c478bd9Sstevel@tonic-gate }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate struct ng_old_struct { 81*7c478bd9Sstevel@tonic-gate struct ng_old_struct *ng_next; /* Chain ptr */ 82*7c478bd9Sstevel@tonic-gate char * ng_str[3]; /* Field pointers, see below */ 83*7c478bd9Sstevel@tonic-gate }; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate struct pvt { 86*7c478bd9Sstevel@tonic-gate FILE *fp; 87*7c478bd9Sstevel@tonic-gate struct linelist *linehead; 88*7c478bd9Sstevel@tonic-gate struct ng_old_struct *nextgrp; 89*7c478bd9Sstevel@tonic-gate struct { 90*7c478bd9Sstevel@tonic-gate struct ng_old_struct *gr; 91*7c478bd9Sstevel@tonic-gate char *grname; 92*7c478bd9Sstevel@tonic-gate } grouphead; 93*7c478bd9Sstevel@tonic-gate }; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* Forward */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static void ng_rewind(struct irs_ng *, const char*); 98*7c478bd9Sstevel@tonic-gate static void ng_close(struct irs_ng *); 99*7c478bd9Sstevel@tonic-gate static int ng_next(struct irs_ng *, const char **, 100*7c478bd9Sstevel@tonic-gate const char **, const char **); 101*7c478bd9Sstevel@tonic-gate static int ng_test(struct irs_ng *, const char *, 102*7c478bd9Sstevel@tonic-gate const char *, const char *, 103*7c478bd9Sstevel@tonic-gate const char *); 104*7c478bd9Sstevel@tonic-gate static void ng_minimize(struct irs_ng *); 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate static int parse_netgrp(struct irs_ng *, const char*); 107*7c478bd9Sstevel@tonic-gate static struct linelist *read_for_group(struct irs_ng *, const char *); 108*7c478bd9Sstevel@tonic-gate static void freelists(struct irs_ng *); 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* Public */ 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate struct irs_ng * 113*7c478bd9Sstevel@tonic-gate irs_lcl_ng(struct irs_acc *this) { 114*7c478bd9Sstevel@tonic-gate struct irs_ng *ng; 115*7c478bd9Sstevel@tonic-gate struct pvt *pvt; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate UNUSED(this); 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate if (!(ng = memget(sizeof *ng))) { 120*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 121*7c478bd9Sstevel@tonic-gate return (NULL); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate memset(ng, 0x5e, sizeof *ng); 124*7c478bd9Sstevel@tonic-gate if (!(pvt = memget(sizeof *pvt))) { 125*7c478bd9Sstevel@tonic-gate memput(ng, sizeof *ng); 126*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 127*7c478bd9Sstevel@tonic-gate return (NULL); 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate memset(pvt, 0, sizeof *pvt); 130*7c478bd9Sstevel@tonic-gate ng->private = pvt; 131*7c478bd9Sstevel@tonic-gate ng->close = ng_close; 132*7c478bd9Sstevel@tonic-gate ng->next = ng_next; 133*7c478bd9Sstevel@tonic-gate ng->test = ng_test; 134*7c478bd9Sstevel@tonic-gate ng->rewind = ng_rewind; 135*7c478bd9Sstevel@tonic-gate ng->minimize = ng_minimize; 136*7c478bd9Sstevel@tonic-gate return (ng); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate /* Methods */ 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate static void 142*7c478bd9Sstevel@tonic-gate ng_close(struct irs_ng *this) { 143*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if (pvt->fp != NULL) 146*7c478bd9Sstevel@tonic-gate fclose(pvt->fp); 147*7c478bd9Sstevel@tonic-gate freelists(this); 148*7c478bd9Sstevel@tonic-gate memput(pvt, sizeof *pvt); 149*7c478bd9Sstevel@tonic-gate memput(this, sizeof *this); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * Parse the netgroup file looking for the netgroup and build the list 154*7c478bd9Sstevel@tonic-gate * of netgrp structures. Let parse_netgrp() and read_for_group() do 155*7c478bd9Sstevel@tonic-gate * most of the work. 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate static void 158*7c478bd9Sstevel@tonic-gate ng_rewind(struct irs_ng *this, const char *group) { 159*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if (pvt->fp != NULL && fseek(pvt->fp, SEEK_CUR, 0L) == -1) { 162*7c478bd9Sstevel@tonic-gate fclose(pvt->fp); 163*7c478bd9Sstevel@tonic-gate pvt->fp = NULL; 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (pvt->fp == NULL || pvt->grouphead.gr == NULL || 167*7c478bd9Sstevel@tonic-gate strcmp(group, pvt->grouphead.grname)) { 168*7c478bd9Sstevel@tonic-gate freelists(this); 169*7c478bd9Sstevel@tonic-gate if (pvt->fp != NULL) 170*7c478bd9Sstevel@tonic-gate fclose(pvt->fp); 171*7c478bd9Sstevel@tonic-gate pvt->fp = fopen(_PATH_NETGROUP, "r"); 172*7c478bd9Sstevel@tonic-gate if (pvt->fp != NULL) { 173*7c478bd9Sstevel@tonic-gate if (parse_netgrp(this, group)) 174*7c478bd9Sstevel@tonic-gate freelists(this); 175*7c478bd9Sstevel@tonic-gate if (!(pvt->grouphead.grname = strdup(group))) 176*7c478bd9Sstevel@tonic-gate freelists(this); 177*7c478bd9Sstevel@tonic-gate fclose(pvt->fp); 178*7c478bd9Sstevel@tonic-gate pvt->fp = NULL; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate pvt->nextgrp = pvt->grouphead.gr; 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* 185*7c478bd9Sstevel@tonic-gate * Get the next netgroup off the list. 186*7c478bd9Sstevel@tonic-gate */ 187*7c478bd9Sstevel@tonic-gate static int 188*7c478bd9Sstevel@tonic-gate ng_next(struct irs_ng *this, const char **host, const char **user, 189*7c478bd9Sstevel@tonic-gate const char **domain) 190*7c478bd9Sstevel@tonic-gate { 191*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (pvt->nextgrp) { 194*7c478bd9Sstevel@tonic-gate *host = pvt->nextgrp->ng_str[NG_HOST]; 195*7c478bd9Sstevel@tonic-gate *user = pvt->nextgrp->ng_str[NG_USER]; 196*7c478bd9Sstevel@tonic-gate *domain = pvt->nextgrp->ng_str[NG_DOM]; 197*7c478bd9Sstevel@tonic-gate pvt->nextgrp = pvt->nextgrp->ng_next; 198*7c478bd9Sstevel@tonic-gate return (1); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate return (0); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate /* 204*7c478bd9Sstevel@tonic-gate * Search for a match in a netgroup. 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate static int 207*7c478bd9Sstevel@tonic-gate ng_test(struct irs_ng *this, const char *name, 208*7c478bd9Sstevel@tonic-gate const char *host, const char *user, const char *domain) 209*7c478bd9Sstevel@tonic-gate { 210*7c478bd9Sstevel@tonic-gate const char *ng_host, *ng_user, *ng_domain; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate ng_rewind(this, name); 213*7c478bd9Sstevel@tonic-gate while (ng_next(this, &ng_host, &ng_user, &ng_domain)) 214*7c478bd9Sstevel@tonic-gate if ((host == NULL || ng_host == NULL || 215*7c478bd9Sstevel@tonic-gate !strcmp(host, ng_host)) && 216*7c478bd9Sstevel@tonic-gate (user == NULL || ng_user == NULL || 217*7c478bd9Sstevel@tonic-gate !strcmp(user, ng_user)) && 218*7c478bd9Sstevel@tonic-gate (domain == NULL || ng_domain == NULL || 219*7c478bd9Sstevel@tonic-gate !strcmp(domain, ng_domain))) { 220*7c478bd9Sstevel@tonic-gate freelists(this); 221*7c478bd9Sstevel@tonic-gate return (1); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate freelists(this); 224*7c478bd9Sstevel@tonic-gate return (0); 225*7c478bd9Sstevel@tonic-gate } 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate static void 228*7c478bd9Sstevel@tonic-gate ng_minimize(struct irs_ng *this) { 229*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate if (pvt->fp != NULL) { 232*7c478bd9Sstevel@tonic-gate (void)fclose(pvt->fp); 233*7c478bd9Sstevel@tonic-gate pvt->fp = NULL; 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate /* Private */ 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * endnetgrent() - cleanup 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate static void 243*7c478bd9Sstevel@tonic-gate freelists(struct irs_ng *this) { 244*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 245*7c478bd9Sstevel@tonic-gate struct linelist *lp, *olp; 246*7c478bd9Sstevel@tonic-gate struct ng_old_struct *gp, *ogp; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate lp = pvt->linehead; 249*7c478bd9Sstevel@tonic-gate while (lp) { 250*7c478bd9Sstevel@tonic-gate olp = lp; 251*7c478bd9Sstevel@tonic-gate lp = lp->l_next; 252*7c478bd9Sstevel@tonic-gate free(olp->l_groupname); 253*7c478bd9Sstevel@tonic-gate free(olp->l_line); 254*7c478bd9Sstevel@tonic-gate free((char *)olp); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate pvt->linehead = NULL; 257*7c478bd9Sstevel@tonic-gate if (pvt->grouphead.grname) { 258*7c478bd9Sstevel@tonic-gate free(pvt->grouphead.grname); 259*7c478bd9Sstevel@tonic-gate pvt->grouphead.grname = NULL; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate gp = pvt->grouphead.gr; 262*7c478bd9Sstevel@tonic-gate while (gp) { 263*7c478bd9Sstevel@tonic-gate ogp = gp; 264*7c478bd9Sstevel@tonic-gate gp = gp->ng_next; 265*7c478bd9Sstevel@tonic-gate if (ogp->ng_str[NG_HOST]) 266*7c478bd9Sstevel@tonic-gate free(ogp->ng_str[NG_HOST]); 267*7c478bd9Sstevel@tonic-gate if (ogp->ng_str[NG_USER]) 268*7c478bd9Sstevel@tonic-gate free(ogp->ng_str[NG_USER]); 269*7c478bd9Sstevel@tonic-gate if (ogp->ng_str[NG_DOM]) 270*7c478bd9Sstevel@tonic-gate free(ogp->ng_str[NG_DOM]); 271*7c478bd9Sstevel@tonic-gate free((char *)ogp); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate pvt->grouphead.gr = NULL; 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * Parse the netgroup file setting up the linked lists. 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate static int 280*7c478bd9Sstevel@tonic-gate parse_netgrp(struct irs_ng *this, const char *group) { 281*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 282*7c478bd9Sstevel@tonic-gate char *spos, *epos; 283*7c478bd9Sstevel@tonic-gate int len, strpos; 284*7c478bd9Sstevel@tonic-gate char *pos, *gpos; 285*7c478bd9Sstevel@tonic-gate struct ng_old_struct *grp; 286*7c478bd9Sstevel@tonic-gate struct linelist *lp = pvt->linehead; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /* 289*7c478bd9Sstevel@tonic-gate * First, see if the line has already been read in. 290*7c478bd9Sstevel@tonic-gate */ 291*7c478bd9Sstevel@tonic-gate while (lp) { 292*7c478bd9Sstevel@tonic-gate if (!strcmp(group, lp->l_groupname)) 293*7c478bd9Sstevel@tonic-gate break; 294*7c478bd9Sstevel@tonic-gate lp = lp->l_next; 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate if (lp == NULL && 297*7c478bd9Sstevel@tonic-gate (lp = read_for_group(this, group)) == NULL) 298*7c478bd9Sstevel@tonic-gate return (1); 299*7c478bd9Sstevel@tonic-gate if (lp->l_parsed) { 300*7c478bd9Sstevel@tonic-gate /*fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);*/ 301*7c478bd9Sstevel@tonic-gate return (1); 302*7c478bd9Sstevel@tonic-gate } else 303*7c478bd9Sstevel@tonic-gate lp->l_parsed = 1; 304*7c478bd9Sstevel@tonic-gate pos = lp->l_line; 305*7c478bd9Sstevel@tonic-gate while (*pos != '\0') { 306*7c478bd9Sstevel@tonic-gate if (*pos == '(') { 307*7c478bd9Sstevel@tonic-gate if (!(grp = malloc(sizeof (struct ng_old_struct)))) { 308*7c478bd9Sstevel@tonic-gate freelists(this); 309*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 310*7c478bd9Sstevel@tonic-gate return (1); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate memset(grp, 0, sizeof (struct ng_old_struct)); 313*7c478bd9Sstevel@tonic-gate grp->ng_next = pvt->grouphead.gr; 314*7c478bd9Sstevel@tonic-gate pvt->grouphead.gr = grp; 315*7c478bd9Sstevel@tonic-gate pos++; 316*7c478bd9Sstevel@tonic-gate gpos = strsep(&pos, ")"); 317*7c478bd9Sstevel@tonic-gate for (strpos = 0; strpos < 3; strpos++) { 318*7c478bd9Sstevel@tonic-gate if ((spos = strsep(&gpos, ","))) { 319*7c478bd9Sstevel@tonic-gate while (*spos == ' ' || *spos == '\t') 320*7c478bd9Sstevel@tonic-gate spos++; 321*7c478bd9Sstevel@tonic-gate if ((epos = strpbrk(spos, " \t"))) { 322*7c478bd9Sstevel@tonic-gate *epos = '\0'; 323*7c478bd9Sstevel@tonic-gate len = epos - spos; 324*7c478bd9Sstevel@tonic-gate } else 325*7c478bd9Sstevel@tonic-gate len = strlen(spos); 326*7c478bd9Sstevel@tonic-gate if (len > 0) { 327*7c478bd9Sstevel@tonic-gate if(!(grp->ng_str[strpos] 328*7c478bd9Sstevel@tonic-gate = (char *) 329*7c478bd9Sstevel@tonic-gate malloc(len + 1))) { 330*7c478bd9Sstevel@tonic-gate freelists(this); 331*7c478bd9Sstevel@tonic-gate return (1); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate memcpy(grp->ng_str[strpos], 334*7c478bd9Sstevel@tonic-gate spos, 335*7c478bd9Sstevel@tonic-gate len + 1); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate } else 338*7c478bd9Sstevel@tonic-gate goto errout; 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate } else { 341*7c478bd9Sstevel@tonic-gate spos = strsep(&pos, ", \t"); 342*7c478bd9Sstevel@tonic-gate if (spos != NULL && parse_netgrp(this, spos)) { 343*7c478bd9Sstevel@tonic-gate freelists(this); 344*7c478bd9Sstevel@tonic-gate return (1); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate if (pos == NULL) 348*7c478bd9Sstevel@tonic-gate break; 349*7c478bd9Sstevel@tonic-gate while (*pos == ' ' || *pos == ',' || *pos == '\t') 350*7c478bd9Sstevel@tonic-gate pos++; 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate return (0); 353*7c478bd9Sstevel@tonic-gate errout: 354*7c478bd9Sstevel@tonic-gate /*fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname, 355*7c478bd9Sstevel@tonic-gate spos);*/ 356*7c478bd9Sstevel@tonic-gate return (1); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate /* 360*7c478bd9Sstevel@tonic-gate * Read the netgroup file and save lines until the line for the netgroup 361*7c478bd9Sstevel@tonic-gate * is found. Return 1 if eof is encountered. 362*7c478bd9Sstevel@tonic-gate */ 363*7c478bd9Sstevel@tonic-gate static struct linelist * 364*7c478bd9Sstevel@tonic-gate read_for_group(struct irs_ng *this, const char *group) { 365*7c478bd9Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 366*7c478bd9Sstevel@tonic-gate char *pos, *spos, *linep = NULL, *olinep; 367*7c478bd9Sstevel@tonic-gate int len, olen, cont; 368*7c478bd9Sstevel@tonic-gate struct linelist *lp; 369*7c478bd9Sstevel@tonic-gate char line[LINSIZ + 1]; 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate while (fgets(line, LINSIZ, pvt->fp) != NULL) { 372*7c478bd9Sstevel@tonic-gate pos = line; 373*7c478bd9Sstevel@tonic-gate if (*pos == '#') 374*7c478bd9Sstevel@tonic-gate continue; 375*7c478bd9Sstevel@tonic-gate while (*pos == ' ' || *pos == '\t') 376*7c478bd9Sstevel@tonic-gate pos++; 377*7c478bd9Sstevel@tonic-gate spos = pos; 378*7c478bd9Sstevel@tonic-gate while (*pos != ' ' && *pos != '\t' && *pos != '\n' && 379*7c478bd9Sstevel@tonic-gate *pos != '\0') 380*7c478bd9Sstevel@tonic-gate pos++; 381*7c478bd9Sstevel@tonic-gate len = pos - spos; 382*7c478bd9Sstevel@tonic-gate while (*pos == ' ' || *pos == '\t') 383*7c478bd9Sstevel@tonic-gate pos++; 384*7c478bd9Sstevel@tonic-gate if (*pos != '\n' && *pos != '\0') { 385*7c478bd9Sstevel@tonic-gate if (!(lp = malloc(sizeof (*lp)))) { 386*7c478bd9Sstevel@tonic-gate freelists(this); 387*7c478bd9Sstevel@tonic-gate return (NULL); 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate lp->l_parsed = 0; 390*7c478bd9Sstevel@tonic-gate if (!(lp->l_groupname = malloc(len + 1))) { 391*7c478bd9Sstevel@tonic-gate free(lp); 392*7c478bd9Sstevel@tonic-gate freelists(this); 393*7c478bd9Sstevel@tonic-gate return (NULL); 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate memcpy(lp->l_groupname, spos, len); 396*7c478bd9Sstevel@tonic-gate *(lp->l_groupname + len) = '\0'; 397*7c478bd9Sstevel@tonic-gate len = strlen(pos); 398*7c478bd9Sstevel@tonic-gate olen = 0; 399*7c478bd9Sstevel@tonic-gate olinep = NULL; 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate /* 402*7c478bd9Sstevel@tonic-gate * Loop around handling line continuations. 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate do { 405*7c478bd9Sstevel@tonic-gate if (*(pos + len - 1) == '\n') 406*7c478bd9Sstevel@tonic-gate len--; 407*7c478bd9Sstevel@tonic-gate if (*(pos + len - 1) == '\\') { 408*7c478bd9Sstevel@tonic-gate len--; 409*7c478bd9Sstevel@tonic-gate cont = 1; 410*7c478bd9Sstevel@tonic-gate } else 411*7c478bd9Sstevel@tonic-gate cont = 0; 412*7c478bd9Sstevel@tonic-gate if (len > 0) { 413*7c478bd9Sstevel@tonic-gate if (!(linep = malloc(olen + len + 1))){ 414*7c478bd9Sstevel@tonic-gate if (olen > 0) 415*7c478bd9Sstevel@tonic-gate free(olinep); 416*7c478bd9Sstevel@tonic-gate free(lp->l_groupname); 417*7c478bd9Sstevel@tonic-gate free(lp); 418*7c478bd9Sstevel@tonic-gate freelists(this); 419*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 420*7c478bd9Sstevel@tonic-gate return (NULL); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate if (olen > 0) { 423*7c478bd9Sstevel@tonic-gate memcpy(linep, olinep, olen); 424*7c478bd9Sstevel@tonic-gate free(olinep); 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate memcpy(linep + olen, pos, len); 427*7c478bd9Sstevel@tonic-gate olen += len; 428*7c478bd9Sstevel@tonic-gate *(linep + olen) = '\0'; 429*7c478bd9Sstevel@tonic-gate olinep = linep; 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate if (cont) { 432*7c478bd9Sstevel@tonic-gate if (fgets(line, LINSIZ, pvt->fp)) { 433*7c478bd9Sstevel@tonic-gate pos = line; 434*7c478bd9Sstevel@tonic-gate len = strlen(pos); 435*7c478bd9Sstevel@tonic-gate } else 436*7c478bd9Sstevel@tonic-gate cont = 0; 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate } while (cont); 439*7c478bd9Sstevel@tonic-gate lp->l_line = linep; 440*7c478bd9Sstevel@tonic-gate lp->l_next = pvt->linehead; 441*7c478bd9Sstevel@tonic-gate pvt->linehead = lp; 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate /* 444*7c478bd9Sstevel@tonic-gate * If this is the one we wanted, we are done. 445*7c478bd9Sstevel@tonic-gate */ 446*7c478bd9Sstevel@tonic-gate if (!strcmp(lp->l_groupname, group)) 447*7c478bd9Sstevel@tonic-gate return (lp); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate } 450*7c478bd9Sstevel@tonic-gate return (NULL); 451*7c478bd9Sstevel@tonic-gate } 452