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[] = "@(#)innetgr.c 1.2 90/07/20 4.1NFSSRC; from 1.17 88/02/08 SMI Copyr 1985 Sun Micro"; 26#endif 27 28/* 29 * Copyright (c) 1990 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/* 39 * innetgr: test whether I'm in /etc/netgroup 40 * 41 */ 42 43 44struct innetgrdata { 45 char *name; 46 char *machine; 47 char *domain; 48 char **list; 49#define LISTSIZE 200 /* recursion limit */ 50 char **listp; /* pointer into list */ 51 char *thisdomain; 52}; 53 54static int lookup(char *, char *, char *, char *, char *, int *); 55static int doit(register struct innetgrdata *, char *); 56static void makekey(char *, char *, char *); 57 58int _old_innetgr(group, machine, name, domain) 59 char *group, *machine, *name, *domain; 60{ 61 int res; 62 register struct innetgrdata *d; 63 char *thisdomain; 64 65 (void) yp_get_default_domain(&thisdomain); 66 if (domain) { 67 if (name && !machine) { 68 if (lookup(thisdomain, 69 "netgroup.byuser",group,name,domain,&res)) { 70 return(res); 71 } 72 } else if (machine && !name) { 73 if (lookup(thisdomain, 74 "netgroup.byhost",group,machine,domain,&res)) { 75 return(res); 76 } 77 } 78 } 79 d = (struct innetgrdata *)malloc(sizeof (struct innetgrdata)); 80 if (d == 0) 81 return (0); 82 d->machine = machine; 83 d->name = name; 84 d->domain = domain; 85 d->thisdomain = thisdomain; 86 d->list = (char **)calloc(LISTSIZE, sizeof (char *)); 87 d->listp = d->list; 88 if (d->list == 0) { 89 free(d); 90 return (0); 91 } 92 res = doit(d, group); 93 free(d->list); 94 free(d); 95 return (res); 96} 97 98/* 99 * calls itself recursively 100 */ 101static int 102doit(d, group) 103 register struct innetgrdata *d; 104 char *group; 105{ 106 char *key, *val; 107 int vallen,keylen; 108 char *r; 109 int match; 110 register char *p, *q; 111 register char **lp; 112 int err; 113 114 *d->listp++ = group; 115 if (d->listp > d->list + LISTSIZE) { 116 (void) fprintf(stderr, "innetgr: recursive overflow\r\n"); 117 d->listp--; 118 return (0); 119 } 120 key = group; 121 keylen = strlen(group); 122 err = yp_match(d->thisdomain, "netgroup", key, keylen, &val, &vallen); 123 if (err) { 124#ifdef DEBUG 125 if (err == YPERR_KEY) 126 (void) fprintf(stderr, 127 "innetgr: no such netgroup as %s\n", group); 128 else 129 (void) fprintf(stderr, "innetgr: yp_match, %s\n",yperr_string(err)); 130#endif 131 d->listp--; 132 return(0); 133 } 134 /* 135 * check for recursive loops 136 */ 137 for (lp = d->list; lp < d->listp-1; lp++) 138 if (strcmp(*lp, group) == 0) { 139 (void) fprintf(stderr, 140 "innetgr: netgroup %s called recursively\r\n", 141 group); 142 d->listp--; 143 free(val); 144 return(0); 145 } 146 147 p = val; 148 p[vallen] = 0; 149 while (p != NULL) { 150 match = 0; 151 while (*p == ' ' || *p == '\t') 152 p++; 153 if (*p == 0 || *p == '#') 154 break; 155 if (*p == '(') { 156 p++; 157 while (*p == ' ' || *p == '\t') 158 p++; 159 r = q = index(p, ','); 160 if (q == NULL) { 161 (void) fprintf(stderr, 162 "innetgr: syntax error in /etc/netgroup\r\n"); 163 d->listp--; 164 free(val); 165 return(0); 166 } 167 if (p == q || d->machine == NULL) 168 match++; 169 else { 170 while (*(q-1) == ' ' || *(q-1) == '\t') 171 q--; 172 if (strncmp(d->machine, p, q-p) == 0) 173 match++; 174 } 175 p = r+1; 176 177 while (*p == ' ' || *p == '\t') 178 p++; 179 r = q = index(p, ','); 180 if (q == NULL) { 181 (void) fprintf(stderr, 182 "innetgr: syntax error in /etc/netgroup\r\n"); 183 d->listp--; 184 free(val); 185 return(0); 186 } 187 if (p == q || d->name == NULL) 188 match++; 189 else { 190 while (*(q-1) == ' ' || *(q-1) == '\t') 191 q--; 192 if (strncmp(d->name, p, q-p) == 0) 193 match++; 194 } 195 p = r+1; 196 197 while (*p == ' ' || *p == '\t') 198 p++; 199 r = q = index(p, ')'); 200 if (q == NULL) { 201 (void) fprintf(stderr, 202 "innetgr: syntax error in /etc/netgroup\r\n"); 203 d->listp--; 204 free(val); 205 return(0); 206 } 207 if (p == q || d->domain == NULL) 208 match++; 209 else { 210 while (*(q-1) == ' ' || *(q-1) == '\t') 211 q--; 212 if (strncmp(d->domain, p, q-p) == 0) 213 match++; 214 } 215 p = r+1; 216 if (match == 3) { 217 free(val); 218 d->listp--; 219 return 1; 220 } 221 } 222 else { 223 q = strpbrk(p, " \t\n#"); 224 if (q && *q == '#') 225 break; 226 if (q) 227 *q = 0; 228 if (doit(d, p)) { 229 free(val); 230 d->listp--; 231 return 1; 232 } 233 if (q) 234 *q = ' '; 235 } 236 p = strpbrk(p, " \t"); 237 } 238 free(val); 239 d->listp--; 240 return 0; 241} 242 243/* 244 * return 1 if "what" is in the comma-separated, newline-terminated "d->list" 245 */ 246static int 247inlist(what,list) 248 char *what; 249 char *list; 250{ 251# define TERMINATOR(c) (c == ',' || c == '\n') 252 253 register char *p; 254 int len; 255 256 len = strlen(what); 257 p = list; 258 do { 259 if (strncmp(what,p,len) == 0 && TERMINATOR(p[len])) { 260 return(1); 261 } 262 while (!TERMINATOR(*p)) { 263 p++; 264 } 265 p++; 266 } while (*p); 267 return(0); 268} 269 270 271 272 273/* 274 * Lookup a host or user name in a NIS map. Set result to 1 if group in the 275 * lookup list of groups. Return 1 if the map was found. 276 */ 277static int 278lookup(thisdomain,map,group,name,domain,res) 279 char *thisdomain; 280 char *map; 281 char *group; 282 char *name; 283 char *domain; 284 int *res; 285{ 286 int err; 287 char *val; 288 int vallen; 289 char key[256]; 290 char *wild = "*"; 291 int i; 292 293 for (i = 0; i < 4; i++) { 294 switch (i) { 295 case 0: makekey(key,name,domain); break; 296 case 1: makekey(key,wild,domain); break; 297 case 2: makekey(key,name,wild); break; 298 case 3: makekey(key,wild,wild); break; 299 } 300 err = yp_match(thisdomain,map,key,strlen(key),&val,&vallen); 301 if (!err) { 302 *res = inlist(group,val); 303 free(val); 304 if (*res) { 305 return(1); 306 } 307 } else { 308#ifdef DEBUG 309 (void) fprintf(stderr, 310 "yp_match(%s,%s) failed: %s.\n",map,key,yperr_string(err)); 311#endif 312 if (err != YPERR_KEY) { 313 return(0); 314 } 315 } 316 } 317 *res = 0; 318 return(1); 319} 320 321 322 323/* 324 * Generate a key for a netgroup.byXXXX NIS map 325 */ 326static void 327makekey(key,name,domain) 328 register char *key; 329 register char *name; 330 register char *domain; 331{ 332 while ((*key++ = *name++)) 333 ; 334 *(key-1) = '.'; 335 while ((*key++ = *domain++)) 336 ; 337} 338