xref: /titanic_52/usr/src/lib/libbc/libc/gen/common/getpwaent.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
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  * Copyright 1991 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"  /* c2 secure */
28 
29 
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <sys/label.h>
33 #include <sys/audit.h>
34 #include <pwdadj.h>
35 #include <pwd.h>
36 #include <rpcsvc/ypclnt.h>
37 
38 extern void rewind();
39 extern long strtol();
40 extern int strcmp();
41 extern int strlen();
42 extern int fclose();
43 extern char *strcpy();
44 extern char *strncpy();
45 extern char *calloc();
46 extern char *malloc();
47 
48 void setpwaent(), endpwaent();
49 
50 static struct _pwajunk {
51 	struct passwd _NULLPW;
52 	FILE *_pwfadj;
53 	char *_yp;
54 	int _yplen;
55 	char *_oldyp;
56 	int _oldyplen;
57 	struct list {
58 		char *name;
59 		struct list *nxt;
60 	} *_minuslist;
61 	struct passwd _interppasswd;
62 	struct passwd_adjunct _apwadj;
63 	char _interpline[BUFSIZ+1];
64 	char *_domain;
65 } *__pwajunk, *_pwajunk();
66 
67 #define	NULLPW (_pwa->_NULLPW)
68 #define pwfadj (_pwa->_pwfadj)
69 #define yp (_pwa->_yp)
70 #define yplen (_pwa->_yplen)
71 #define oldyp (_pwa->_oldyp)
72 #define oldyplen (_pwa->_oldyplen)
73 #define minuslist (_pwa->_minuslist)
74 #define interppasswd (_pwa->_interppasswd)
75 #define apwadj (_pwa->_apwadj)
76 #define interpline (_pwa->_interpline)
77 #define domain (_pwa->_domain)
78 
79 static char *PASSWDADJ	= "/etc/security/passwd.adjunct";
80 
81 static struct passwd_adjunct *interpret();
82 static struct passwd_adjunct *interpretwithsave();
83 static struct passwd_adjunct *save();
84 static struct passwd_adjunct *getnamefromyellow();
85 
86 static struct _pwajunk *
87 _pwajunk()
88 {
89 
90 	if (__pwajunk == 0)
91 		__pwajunk = (struct _pwajunk *)calloc(1, sizeof (*__pwajunk));
92 	return (__pwajunk);
93 }
94 
95 struct passwd_adjunct *
96 getpwanam(name)
97 	register char *name;
98 {
99 	register struct _pwajunk *_pwa = _pwajunk();
100 	struct passwd_adjunct *pwadj;
101 	char line[BUFSIZ+1];
102 
103 	if (_pwa == 0)
104 		return (0);
105 	setpwaent();
106 	if (!pwfadj)
107 		return NULL;
108 	while (fgets(line, BUFSIZ, pwfadj) != NULL) {
109 		if ((pwadj = interpret(line, strlen(line))) == NULL)
110 			continue;
111 		if (matchname(line, &pwadj, name)) {
112 			endpwaent();
113 			return pwadj;
114 		}
115 	}
116 	endpwaent();
117 	return NULL;
118 }
119 
120 #ifdef	NOT_INCLUDED
121 struct passwd_adjunct *
122 getpwauid(uid)
123 	register uid;
124 {
125 	register struct _pwajunk *_pwa = _pwajunk();
126 	/*
127 	 * provided for consistency even though there is no uid in
128 	 * the adjunct file.
129 	 */
130 	struct passwd *getpwuid();
131 	struct passwd *pw;
132 
133 	if (_pwa == 0)
134 		return (0);
135 	if ((pw = getpwuid(uid)) == NULL)
136 		return NULL;
137 	return (getpwanam(pw->pw_name));
138 }
139 #endif	NOT_INCLUDED
140 
141 
142 
143 
144 void
145 setpwaent()
146 {
147 	register struct _pwajunk *_pwa = _pwajunk();
148 
149 	if (_pwa == 0)
150 		return;
151 	if (domain == NULL) {
152 		(void) yp_get_default_domain(&domain );
153 	}
154 	if (pwfadj == NULL)
155 		pwfadj = fopen(PASSWDADJ, "r");
156 	else
157 		rewind(pwfadj);
158 	if (yp)
159 		free(yp);
160 	yp = NULL;
161 	freeminuslist();
162 }
163 
164 
165 
166 void
167 endpwaent()
168 {
169 	register struct _pwajunk *_pwa = _pwajunk();
170 
171 	if (_pwa == 0)
172 		return;
173 	if (pwfadj != NULL) {
174 		(void) fclose(pwfadj);
175 		pwfadj = NULL;
176 	}
177 	if (yp)
178 		free(yp);
179 	yp = NULL;
180 	freeminuslist();
181 	endnetgrent();
182 }
183 
184 
185 
186 struct passwd_adjunct *
187 getpwaent()
188 {
189 	register struct _pwajunk *_pwa = _pwajunk();
190 	char line[BUFSIZ+1];
191 	static struct passwd_adjunct *savepwadj;
192 	struct passwd_adjunct *pwadj;
193 	char *user;
194 	char *mach;
195 	char *dom;
196 
197 	if (_pwa == 0)
198 		return (0);
199 	if (domain == NULL) {
200 		(void) yp_get_default_domain(&domain );
201 	}
202 	if (pwfadj == NULL && (pwfadj = fopen(PASSWDADJ, "r")) == NULL) {
203 		return (NULL);
204 	}
205 
206 	for (;;) {
207 		if (yp) {
208 			pwadj = interpretwithsave(yp, yplen, savepwadj);
209 			free(yp);
210 			if (pwadj == NULL)
211 				return(NULL);
212 			getnextfromyellow();
213 			if (!onminuslist(pwadj)) {
214 				return(pwadj);
215 			}
216 		} else if (getnetgrent(&mach,&user,&dom)) {
217 			if (user) {
218 				pwadj = getnamefromyellow(user, savepwadj);
219 				if (pwadj != NULL && !onminuslist(pwadj)) {
220 					return(pwadj);
221 				}
222 			}
223 		} else {
224 			endnetgrent();
225 			if (fgets(line, BUFSIZ, pwfadj) == NULL)  {
226 				return(NULL);
227 			}
228 			if ((pwadj = interpret(line, strlen(line))) == NULL)
229 				return(NULL);
230 			switch(line[0]) {
231 			case '+':
232 				if (strcmp(pwadj->pwa_name, "+") == 0) {
233 					getfirstfromyellow();
234 					savepwadj = save(pwadj);
235 				} else if (line[1] == '@') {
236 					savepwadj = save(pwadj);
237 					if (innetgr(pwadj->pwa_name+2,(char *) NULL,"*",domain)) {
238 						/* include the whole NIS database */
239 						getfirstfromyellow();
240 					} else {
241 						setnetgrent(pwadj->pwa_name+2);
242 					}
243 				} else {
244 					/*
245 					 * else look up this entry in NIS
246 				 	 */
247 					savepwadj = save(pwadj);
248 					pwadj = getnamefromyellow(pwadj->pwa_name+1, savepwadj);
249 					if (pwadj != NULL && !onminuslist(pwadj)) {
250 						return(pwadj);
251 					}
252 				}
253 				break;
254 			case '-':
255 				if (line[1] == '@') {
256 					if (innetgr(pwadj->pwa_name+2,(char *) NULL,"*",domain)) {
257 						/* everybody was subtracted */
258 						return(NULL);
259 					}
260 					setnetgrent(pwadj->pwa_name+2);
261 					while (getnetgrent(&mach,&user,&dom)) {
262 						if (user) {
263 							addtominuslist(user);
264 						}
265 					}
266 					endnetgrent();
267 				} else {
268 					addtominuslist(pwadj->pwa_name+1);
269 				}
270 				break;
271 			default:
272 				if (!onminuslist(pwadj)) {
273 					return(pwadj);
274 				}
275 				break;
276 			}
277 		}
278 	}
279 }
280 
281 static
282 matchname(line1, pwadjp, name)
283 	char line1[];
284 	struct passwd_adjunct **pwadjp;
285 	char *name;
286 {
287 	register struct _pwajunk *_pwa = _pwajunk();
288 	struct passwd_adjunct *savepwadj;
289 	struct passwd_adjunct *pwadj = *pwadjp;
290 
291 	if (_pwa == 0)
292 		return (0);
293 	switch(line1[0]) {
294 		case '+':
295 			if (strcmp(pwadj->pwa_name, "+") == 0) {
296 				savepwadj = save(pwadj);
297 				pwadj = getnamefromyellow(name, savepwadj);
298 				if (pwadj) {
299 					*pwadjp = pwadj;
300 					return 1;
301 				}
302 				else
303 					return 0;
304 			}
305 			if (line1[1] == '@') {
306 				if (innetgr(pwadj->pwa_name+2,(char *) NULL,name,domain)) {
307 					savepwadj = save(pwadj);
308 					pwadj = getnamefromyellow(name,savepwadj);
309 					if (pwadj) {
310 						*pwadjp = pwadj;
311 						return 1;
312 					}
313 				}
314 				return 0;
315 			}
316 			if (strcmp(pwadj->pwa_name+1, name) == 0) {
317 				savepwadj = save(pwadj);
318 				pwadj = getnamefromyellow(pwadj->pwa_name+1, savepwadj);
319 				if (pwadj) {
320 					*pwadjp = pwadj;
321 					return 1;
322 				}
323 				else
324 					return 0;
325 			}
326 			break;
327 		case '-':
328 			if (line1[1] == '@') {
329 				if (innetgr(pwadj->pwa_name+2,(char *) NULL,name,domain)) {
330 					*pwadjp = NULL;
331 					return 1;
332 				}
333 			}
334 			else if (strcmp(pwadj->pwa_name+1, name) == 0) {
335 				*pwadjp = NULL;
336 				return 1;
337 			}
338 			break;
339 		default:
340 			if (strcmp(pwadj->pwa_name, name) == 0)
341 				return 1;
342 	}
343 	return 0;
344 }
345 
346 static
347 getnextfromyellow()
348 {
349 	register struct _pwajunk *_pwa = _pwajunk();
350 	int reason;
351 	char *key;
352 	int keylen;
353 
354 	if (_pwa == 0)
355 		return;
356 	reason = yp_next(domain, "passwd_adjunct",oldyp, oldyplen, &key
357 	    ,&keylen,&yp,&yplen);
358 	if (reason) {
359 #ifdef DEBUG
360 fprintf(stderr, "reason yp_next failed is %d\n", reason);
361 #endif
362 		yp = NULL;
363 	}
364 	if (oldyp)
365 		free(oldyp);
366 	oldyp = key;
367 	oldyplen = keylen;
368 }
369 
370 static
371 getfirstfromyellow()
372 {
373 	register struct _pwajunk *_pwa = _pwajunk();
374 	int reason;
375 	char *key;
376 	int keylen;
377 
378 	if (_pwa == 0)
379 		return;
380 	reason =  yp_first(domain, "passwd_adjunct", &key, &keylen, &yp, &yplen);
381 	if (reason) {
382 #ifdef DEBUG
383 fprintf(stderr, "reason yp_first failed is %d\n", reason);
384 #endif
385 		yp = NULL;
386 	}
387 	if (oldyp)
388 		free(oldyp);
389 	oldyp = key;
390 	oldyplen = keylen;
391 }
392 
393 static struct passwd_adjunct *
394 getnamefromyellow(name, savepwadj)
395 	char *name;
396 	struct passwd_adjunct *savepwadj;
397 {
398 	register struct _pwajunk *_pwa = _pwajunk();
399 	struct passwd_adjunct *pwadj;
400 	int reason;
401 	char *val;
402 	int vallen;
403 
404 	if (_pwa == 0)
405 		return (0);
406 	reason = yp_match(domain, "passwd.adjunct.byname", name, strlen(name)
407 		, &val, &vallen);
408 	if (reason) {
409 #ifdef DEBUG
410 fprintf(stderr, "reason yp_match failed is %d\n", reason);
411 #endif
412 		return NULL;
413 	} else {
414 		pwadj = interpret(val, vallen);
415 		free(val);
416 		if (pwadj == NULL)
417 			return NULL;
418 		if (savepwadj->pwa_passwd && *savepwadj->pwa_passwd)
419 			pwadj->pwa_passwd =  savepwadj->pwa_passwd;
420 		return pwadj;
421 	}
422 }
423 
424 static struct passwd_adjunct *
425 interpretwithsave(val, len, savepwadj)
426 	char *val;
427 	struct passwd_adjunct *savepwadj;
428 {
429 	register struct _pwajunk *_pwa = _pwajunk();
430 	struct passwd_adjunct *pwadj;
431 
432 	if (_pwa == 0)
433 		return (0);
434 	if ((pwadj = interpret(val, len)) == NULL)
435 		return NULL;
436 	if (savepwadj->pwa_passwd && *savepwadj->pwa_passwd)
437 		pwadj->pwa_passwd =  savepwadj->pwa_passwd;
438 	return pwadj;
439 }
440 
441 static char *
442 pwskip(p)
443 	register char *p;
444 {
445 	while(*p && *p != ':' && *p != '\n')
446 		++p;
447 	if (*p == '\n')
448 		*p = '\0';
449 	else if (*p != '\0')
450 		*p++ = '\0';
451 	return(p);
452 }
453 
454 static struct passwd_adjunct *
455 interpret(val, len)
456 	char *val;
457 {
458 	register struct _pwajunk *_pwa = _pwajunk();
459 	register char *p;
460 	char *field;
461 
462 	if (_pwa == 0)
463 		return (0);
464 	(void) strncpy(interpline, val, len);
465 	p = interpline;
466 	interpline[len] = '\n';
467 	interpline[len+1] = 0;
468 
469 	apwadj.pwa_name = p;
470 	p = pwskip(p);
471 	if (strcmp(apwadj.pwa_name, "+") == 0) {
472 		/* we are going to the NIS - fix the
473 		 * rest of the struct as much as is needed
474 		 */
475 		apwadj.pwa_passwd = "";
476 		return (&apwadj);
477 	}
478 	apwadj.pwa_passwd = p;
479 	p = pwskip(p);
480 	field = p;
481 	p = pwskip(p);
482 	labelfromstring(0, field, &apwadj.pwa_minimum);
483 	field = p;
484 	p = pwskip(p);
485 	labelfromstring(0, field, &apwadj.pwa_maximum);
486 	field = p;
487 	p = pwskip(p);
488 	labelfromstring(0, field, &apwadj.pwa_def);
489 	field = p;
490 	p = pwskip(p);
491 	apwadj.pwa_au_always.as_success = 0;
492 	apwadj.pwa_au_always.as_failure = 0;
493 	if (getauditflagsbin(field, &apwadj.pwa_au_always) != 0)
494 		return NULL;
495 	field = p;
496 	(void) pwskip(p);
497 	p = apwadj.pwa_passwd;
498 	while (*p && *p != ',')
499 		p++;
500 	if (*p)
501 		*p = '\0';
502 	apwadj.pwa_age = p;
503 	apwadj.pwa_au_never.as_success = 0;
504 	apwadj.pwa_au_never.as_failure = 0;
505 	if (getauditflagsbin(field, &apwadj.pwa_au_never) != 0)
506 		return NULL;
507 	return(&apwadj);
508 }
509 
510 static
511 freeminuslist() {
512 	register struct _pwajunk *_pwa = _pwajunk();
513 	struct list *ls;
514 
515 	if (_pwa == 0)
516 		return;
517 	for (ls = minuslist; ls != NULL; ls = ls->nxt) {
518 		free(ls->name);
519 		free((char *) ls);
520 	}
521 	minuslist = NULL;
522 }
523 
524 static
525 addtominuslist(name)
526 	char *name;
527 {
528 	register struct _pwajunk *_pwa = _pwajunk();
529 	struct list *ls;
530 	char *buf;
531 
532 	if (_pwa == 0)
533 		return;
534 	ls = (struct list *) malloc(sizeof(struct list));
535 	buf = malloc((unsigned) strlen(name) + 1);
536 	(void) strcpy(buf, name);
537 	ls->name = buf;
538 	ls->nxt = minuslist;
539 	minuslist = ls;
540 }
541 
542 /*
543  * save away the psswd field, which is the only one which can be
544  * specified in a local + entry to override the value in the NIS
545  * for passwd.adjunct
546  */
547 static struct passwd_adjunct *
548 save(pwadj)
549 	struct passwd_adjunct *pwadj;
550 {
551 	register struct _pwajunk *_pwa = _pwajunk();
552 	static struct passwd_adjunct *sv;
553 
554 	if (_pwa == 0)
555 		return (0);
556 	/* free up stuff from last call */
557 	if (sv) {
558 		free(sv->pwa_passwd);
559 		free((char *) sv);
560 	}
561 	sv = (struct passwd_adjunct *) malloc(sizeof(struct passwd_adjunct));
562 
563 	sv->pwa_passwd = malloc((unsigned) strlen(pwadj->pwa_passwd) + 1);
564 	(void) strcpy(sv->pwa_passwd, pwadj->pwa_passwd);
565 
566 	return sv;
567 }
568 
569 static
570 onminuslist(pwadj)
571 	struct passwd_adjunct *pwadj;
572 {
573 	register struct _pwajunk *_pwa = _pwajunk();
574 	struct list *ls;
575 	register char *nm;
576 
577 	if (_pwa == 0)
578 		return 0;
579 	nm = pwadj->pwa_name;
580 	for (ls = minuslist; ls != NULL; ls = ls->nxt) {
581 		if (strcmp(ls->name,nm) == 0) {
582 			return(1);
583 		}
584 	}
585 	return(0);
586 }
587