1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.1 (the "License"). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24#if !defined(lint) && defined(SCCSIDS) 25static char sccsid[] = "@(#)getnetgrent.c 1.2 90/07/20 4.1NFSSRC; from 1.22 88/02/08 Copyr 1985 Sun Micro"; 26#endif 27 28/* 29 * Copyright (c) 1985 by Sun Microsystems, Inc. 30 */ 31 32#include <stdio.h> 33#include <ctype.h> 34#include <stdlib.h> 35#include <string.h> 36#include <rpcsvc/ypclnt.h> 37 38#define MAXGROUPLEN 1024 39 40/* 41 * access members of a netgroup 42 */ 43 44static struct grouplist { /* also used by pwlib */ 45 char *gl_machine; 46 char *gl_name; 47 char *gl_domain; 48 struct grouplist *gl_nxt; 49} *grouplist, *grlist; 50 51 52struct list { /* list of names to check for loops */ 53 char *name; 54 struct list *nxt; 55}; 56 57static void doit(); 58static char *fill(); 59static char *match(); 60 61static char *domain; 62static char *oldgrp; 63 64char *NETGROUP = "netgroup"; 65 66void _old_endnetgrent(void); 67void _old_setnetgrent(char *); 68 69void _old_setnetgrent(grp) 70 char *grp; 71{ 72 73 if (oldgrp == NULL) 74 oldgrp = (char *)calloc(1,256); 75 if (strcmp(oldgrp, grp) == 0) 76 grlist = grouplist; 77 else { 78 if (grouplist != NULL) 79 _old_endnetgrent(); 80 doit(grp, (struct list *) NULL); 81 grlist = grouplist; 82 (void) strcpy(oldgrp, grp); 83 } 84} 85 86void _old_endnetgrent() 87{ 88 register struct grouplist *gl; 89 90 for (gl = grouplist; gl != NULL; gl = gl->gl_nxt) { 91 if (gl->gl_name) 92 free(gl->gl_name); 93 if (gl->gl_domain) 94 free(gl->gl_domain); 95 if (gl->gl_machine) 96 free(gl->gl_machine); 97 free((char *) gl); 98 } 99 grouplist = NULL; 100 grlist = NULL; 101 if (oldgrp) { 102 free(oldgrp); 103 oldgrp = 0; 104 } 105} 106 107int _old_getnetgrent(machinep, namep, domainp) 108 char **machinep, **namep, **domainp; 109{ 110 111 if (grlist == 0) 112 return (0); 113 *machinep = grlist->gl_machine; 114 *namep = grlist->gl_name; 115 *domainp = grlist->gl_domain; 116 grlist = grlist->gl_nxt; 117 return (1); 118} 119 120/* 121 * recursive function to find the members of netgroup "group". "list" is 122 * the path followed through the netgroups so far, to check for cycles. 123 */ 124static void 125doit(group,list) 126 char *group; 127 struct list *list; 128{ 129 register char *p, *q; 130 register struct list *ls; 131 struct list this_group; 132 char *val; 133 struct grouplist *gpls; 134 135 /* 136 * check for non-existing groups 137 */ 138 if ((val = match(group)) == NULL) 139 return; 140 141 /* 142 * check for cycles 143 */ 144 for (ls = list; ls != NULL; ls = ls->nxt) 145 if (strcmp(ls->name, group) == 0) { 146 (void) fprintf(stderr, 147 "Cycle detected in /etc/netgroup: %s.\n", group); 148 return; 149 } 150 151 ls = &this_group; 152 ls->name = group; 153 ls->nxt = list; 154 list = ls; 155 156 p = val; 157 while (p != NULL) { 158 while (*p == ' ' || *p == '\t') 159 p++; 160 if (*p == 0 || *p =='#') 161 break; 162 if (*p == '(') { 163 gpls = (struct grouplist *) 164 malloc(sizeof(struct grouplist)); 165 p++; 166 if (!(p = fill(p,&gpls->gl_machine,','))) 167 goto syntax_error; 168 if (!(p = fill(p,&gpls->gl_name,','))) 169 goto syntax_error; 170 if (!(p = fill(p,&gpls->gl_domain,')'))) 171 goto syntax_error; 172 gpls->gl_nxt = grouplist; 173 grouplist = gpls; 174 } else { 175 q = strpbrk(p, " \t\n#"); 176 if (q && *q == '#') 177 break; 178 *q = 0; 179 doit(p,list); 180 *q = ' '; 181 } 182 p = strpbrk(p, " \t"); 183 } 184 return; 185 186syntax_error: 187 (void) fprintf(stderr,"syntax error in /etc/netgroup\n"); 188 (void) fprintf(stderr,"--- %s\n",val); 189 return; 190} 191 192/* 193 * Fill a buffer "target" selectively from buffer "start". 194 * "termchar" terminates the information in start, and preceding 195 * or trailing white space is ignored. The location just after the 196 * terminating character is returned. 197 */ 198static char * 199fill(start,target,termchar) 200 char *start, **target, termchar; 201{ 202 register char *p, *q; 203 char *r; 204 unsigned size; 205 206 for (p = start; *p == ' ' || *p == '\t'; p++) 207 ; 208 r = index(p, termchar); 209 if (r == NULL) 210 return (NULL); 211 if (p == r) 212 *target = NULL; 213 else { 214 for (q = r-1; *q == ' ' || *q == '\t'; q--) 215 ; 216 size = q - p + 1; 217 *target = malloc(size+1); 218 (void) strncpy(*target,p,(int) size); 219 (*target)[size] = 0; 220 } 221 return (r+1); 222} 223 224static char * 225match(group) 226 char *group; 227{ 228 char *val; 229 int vallen; 230 231 if (domain == NULL) 232 (void) yp_get_default_domain(&domain ); 233 if (yp_match(domain, NETGROUP, group, strlen(group), &val, &vallen)) 234 return (NULL); 235 return (val); 236} 237