1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright (c) 1996, by Sun Microsystems, Inc. 25 * All rights reserved. 26 * 27 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <ctype.h> 33 #include <string.h> 34 #include "table.h" 35 #include "util.h" 36 #include "getgroup.h" 37 38 /* 39 * Stolen mostly, from getnetgrent.c 40 * 41 * my_getgroup() performs the same function as _getgroup(), but operates 42 * on /etc/netgroup directly, rather than doing yp lookups. 43 * 44 * /etc/netgroup must first loaded into a hash table so the matching 45 * function can look up lines quickly. 46 */ 47 48 49 /* To check for cycles in netgroups */ 50 struct list { 51 char *name; 52 struct list *nxt; 53 }; 54 55 static char *any(); 56 static char *match(); 57 static char *fill(); 58 59 60 void 61 freegrouplist(revhandle_t *hdl) 62 { 63 struct grouplist *gl, *next; 64 65 for (gl = hdl->grouplist; gl != NULL; gl = next) { 66 next = gl->gl_nxt; 67 68 FREE(gl->gl_name); 69 FREE(gl->gl_domain); 70 FREE(gl->gl_machine); 71 FREE(gl); 72 } 73 hdl->grouplist = NULL; 74 } 75 76 77 78 /* 79 * recursive function to find the members of netgroup "group". "list" is 80 * the path followed through the netgroups so far, to check for cycles. 81 */ 82 void 83 doit(char *group, struct list *list, revhandle_t *hdl) 84 { 85 register char *p, *q; 86 register struct list *ls; 87 struct list tmplist; 88 char *val; 89 struct grouplist *gpls; 90 91 92 /* 93 * check for non-existing groups 94 */ 95 if ((val = match(group, hdl)) == NULL) { 96 return; 97 } 98 99 100 /* 101 * check for cycles 102 */ 103 for (ls = list; ls != NULL; ls = ls->nxt) { 104 if (strcmp(ls->name, group) == 0) { 105 (void) fprintf(stderr, 106 "Cycle detected in /etc/netgroup: %s.\n", 107 group); 108 return; 109 } 110 } 111 112 113 ls = &tmplist; 114 ls->name = group; 115 ls->nxt = list; 116 list = ls; 117 118 p = val; 119 while (p != NULL) { 120 while (*p == ' ' || *p == '\t') 121 p++; 122 if (*p == EOS || *p == '#') 123 break; 124 if (*p == '(') { 125 gpls = MALLOC(struct grouplist); 126 p++; 127 128 if (!(p = fill(p, &gpls->gl_machine, ','))) { 129 goto syntax_error; 130 } 131 if (!(p = fill(p, &gpls->gl_name, ','))) { 132 goto syntax_error; 133 } 134 if (!(p = fill(p, &gpls->gl_domain, ')'))) { 135 goto syntax_error; 136 } 137 gpls->gl_nxt = hdl->grouplist; 138 hdl->grouplist = gpls; 139 } else { 140 q = any(p, " \t\n#"); 141 if (q && *q == '#') 142 break; 143 *q = EOS; 144 doit(p, list, hdl); 145 *q = ' '; 146 } 147 p = any(p, " \t"); 148 } 149 return; 150 151 syntax_error: 152 (void) fprintf(stderr, "syntax error in /etc/netgroup\n"); 153 (void) fprintf(stderr, "--- %s %s\n", group, val); 154 } 155 156 157 158 159 /* 160 * Fill a buffer "target" selectively from buffer "start". 161 * "termchar" terminates the information in start, and preceding 162 * or trailing white space is ignored. If the buffer "start" is 163 * empty, "target" is filled with "*". The location just after the 164 * terminating character is returned. 165 */ 166 static char * 167 fill(start, target, termchar) 168 char *start; 169 char **target; 170 char termchar; 171 { 172 register char *p; 173 register char *q; 174 register char *r; 175 int size; 176 177 for (p = start; *p == ' ' || *p == '\t'; p++) 178 ; 179 r = strchr(p, termchar); 180 if (r == (char *)NULL) { 181 return ((char *)NULL); 182 } 183 if (p == r) { 184 *target = NULL; 185 } else { 186 for (q = r-1; *q == ' ' || *q == '\t'; q--) 187 ; 188 size = q-p+1; 189 STRNCPY(*target, p, size); 190 } 191 return (r+1); 192 } 193 194 195 /* 196 * scans cp, looking for a match with any character 197 * in match. Returns pointer to place in cp that matched 198 * (or NULL if no match) 199 */ 200 static char * 201 any(cp, match) 202 register char *cp; 203 char *match; 204 { 205 register char *mp, c; 206 207 while (c = *cp) { 208 for (mp = match; *mp; mp++) 209 if (*mp == c) 210 return (cp); 211 cp++; 212 } 213 return (NULL); 214 } 215 216 217 218 /* 219 * The equivalent of yp_match. Returns the match, or NULL if there is none. 220 */ 221 static char * 222 match(char *group, revhandle_t *hdl) 223 { 224 return (lookup(hdl->ngtable, group)); 225 }