xref: /onnv-gate/usr/src/lib/libbc/libc/gen/common/getpwaent.c (revision 722:636b850d4ee9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1991 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
27*722Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <sys/label.h>
330Sstevel@tonic-gate #include <sys/audit.h>
340Sstevel@tonic-gate #include <pwdadj.h>
350Sstevel@tonic-gate #include <pwd.h>
360Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
37*722Smuffin #include <string.h>
38*722Smuffin #include <malloc.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate extern void rewind();
410Sstevel@tonic-gate extern long strtol();
420Sstevel@tonic-gate extern int fclose();
430Sstevel@tonic-gate 
44*722Smuffin void	setpwaent(void);
45*722Smuffin void	endpwaent(void);
460Sstevel@tonic-gate 
470Sstevel@tonic-gate static struct _pwajunk {
480Sstevel@tonic-gate 	struct passwd _NULLPW;
490Sstevel@tonic-gate 	FILE *_pwfadj;
500Sstevel@tonic-gate 	char *_yp;
510Sstevel@tonic-gate 	int _yplen;
520Sstevel@tonic-gate 	char *_oldyp;
530Sstevel@tonic-gate 	int _oldyplen;
540Sstevel@tonic-gate 	struct list {
550Sstevel@tonic-gate 		char *name;
560Sstevel@tonic-gate 		struct list *nxt;
570Sstevel@tonic-gate 	} *_minuslist;
580Sstevel@tonic-gate 	struct passwd _interppasswd;
590Sstevel@tonic-gate 	struct passwd_adjunct _apwadj;
600Sstevel@tonic-gate 	char _interpline[BUFSIZ+1];
610Sstevel@tonic-gate 	char *_domain;
62*722Smuffin } *__pwajunk, *_pwajunk(void);
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #define	NULLPW (_pwa->_NULLPW)
650Sstevel@tonic-gate #define pwfadj (_pwa->_pwfadj)
660Sstevel@tonic-gate #define yp (_pwa->_yp)
670Sstevel@tonic-gate #define yplen (_pwa->_yplen)
680Sstevel@tonic-gate #define oldyp (_pwa->_oldyp)
690Sstevel@tonic-gate #define oldyplen (_pwa->_oldyplen)
700Sstevel@tonic-gate #define minuslist (_pwa->_minuslist)
710Sstevel@tonic-gate #define interppasswd (_pwa->_interppasswd)
720Sstevel@tonic-gate #define apwadj (_pwa->_apwadj)
730Sstevel@tonic-gate #define interpline (_pwa->_interpline)
740Sstevel@tonic-gate #define domain (_pwa->_domain)
750Sstevel@tonic-gate 
760Sstevel@tonic-gate static char *PASSWDADJ	= "/etc/security/passwd.adjunct";
770Sstevel@tonic-gate 
78*722Smuffin static struct passwd_adjunct	*interpret(char *, int);
79*722Smuffin static struct passwd_adjunct	*interpretwithsave(char *, int,
80*722Smuffin     struct passwd_adjunct *);
81*722Smuffin static struct passwd_adjunct	*save(struct passwd_adjunct *);
82*722Smuffin static struct passwd_adjunct	*getnamefromyellow(char *,
83*722Smuffin     struct passwd_adjunct *);
84*722Smuffin static int	matchname(char [], struct passwd_adjunct **, char *);
85*722Smuffin static int	onminuslist(struct passwd_adjunct *);
86*722Smuffin static void	getnextfromyellow(void);
87*722Smuffin static void	getfirstfromyellow(void);
88*722Smuffin static void	freeminuslist(void);
89*722Smuffin static void	addtominuslist(char *);
90*722Smuffin 
91*722Smuffin 
920Sstevel@tonic-gate 
930Sstevel@tonic-gate static struct _pwajunk *
_pwajunk(void)94*722Smuffin _pwajunk(void)
950Sstevel@tonic-gate {
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	if (__pwajunk == 0)
980Sstevel@tonic-gate 		__pwajunk = (struct _pwajunk *)calloc(1, sizeof (*__pwajunk));
990Sstevel@tonic-gate 	return (__pwajunk);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate struct passwd_adjunct *
getpwanam(char * name)103*722Smuffin getpwanam(char *name)
1040Sstevel@tonic-gate {
105*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
1060Sstevel@tonic-gate 	struct passwd_adjunct *pwadj;
1070Sstevel@tonic-gate 	char line[BUFSIZ+1];
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if (_pwa == 0)
110*722Smuffin 		return (NULL);
1110Sstevel@tonic-gate 	setpwaent();
1120Sstevel@tonic-gate 	if (!pwfadj)
113*722Smuffin 		return (NULL);
1140Sstevel@tonic-gate 	while (fgets(line, BUFSIZ, pwfadj) != NULL) {
1150Sstevel@tonic-gate 		if ((pwadj = interpret(line, strlen(line))) == NULL)
1160Sstevel@tonic-gate 			continue;
1170Sstevel@tonic-gate 		if (matchname(line, &pwadj, name)) {
1180Sstevel@tonic-gate 			endpwaent();
119*722Smuffin 			return (pwadj);
1200Sstevel@tonic-gate 		}
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate 	endpwaent();
123*722Smuffin 	return (NULL);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate void
setpwaent(void)128*722Smuffin setpwaent(void)
1290Sstevel@tonic-gate {
130*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	if (_pwa == 0)
1330Sstevel@tonic-gate 		return;
1340Sstevel@tonic-gate 	if (domain == NULL) {
1350Sstevel@tonic-gate 		(void) yp_get_default_domain(&domain );
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 	if (pwfadj == NULL)
1380Sstevel@tonic-gate 		pwfadj = fopen(PASSWDADJ, "r");
1390Sstevel@tonic-gate 	else
1400Sstevel@tonic-gate 		rewind(pwfadj);
1410Sstevel@tonic-gate 	if (yp)
1420Sstevel@tonic-gate 		free(yp);
1430Sstevel@tonic-gate 	yp = NULL;
1440Sstevel@tonic-gate 	freeminuslist();
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate void
endpwaent(void)150*722Smuffin endpwaent(void)
1510Sstevel@tonic-gate {
152*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (_pwa == 0)
1550Sstevel@tonic-gate 		return;
1560Sstevel@tonic-gate 	if (pwfadj != NULL) {
1570Sstevel@tonic-gate 		(void) fclose(pwfadj);
1580Sstevel@tonic-gate 		pwfadj = NULL;
1590Sstevel@tonic-gate 	}
1600Sstevel@tonic-gate 	if (yp)
1610Sstevel@tonic-gate 		free(yp);
1620Sstevel@tonic-gate 	yp = NULL;
1630Sstevel@tonic-gate 	freeminuslist();
1640Sstevel@tonic-gate 	endnetgrent();
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate struct passwd_adjunct *
getpwaent(void)170*722Smuffin getpwaent(void)
1710Sstevel@tonic-gate {
172*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
1730Sstevel@tonic-gate 	char line[BUFSIZ+1];
1740Sstevel@tonic-gate 	static struct passwd_adjunct *savepwadj;
1750Sstevel@tonic-gate 	struct passwd_adjunct *pwadj;
1760Sstevel@tonic-gate 	char *user;
1770Sstevel@tonic-gate 	char *mach;
1780Sstevel@tonic-gate 	char *dom;
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	if (_pwa == 0)
181*722Smuffin 		return (NULL);
1820Sstevel@tonic-gate 	if (domain == NULL) {
1830Sstevel@tonic-gate 		(void) yp_get_default_domain(&domain );
1840Sstevel@tonic-gate 	}
1850Sstevel@tonic-gate 	if (pwfadj == NULL && (pwfadj = fopen(PASSWDADJ, "r")) == NULL) {
1860Sstevel@tonic-gate 		return (NULL);
1870Sstevel@tonic-gate 	}
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	for (;;) {
1900Sstevel@tonic-gate 		if (yp) {
1910Sstevel@tonic-gate 			pwadj = interpretwithsave(yp, yplen, savepwadj);
1920Sstevel@tonic-gate 			free(yp);
1930Sstevel@tonic-gate 			if (pwadj == NULL)
194*722Smuffin 				return (NULL);
1950Sstevel@tonic-gate 			getnextfromyellow();
1960Sstevel@tonic-gate 			if (!onminuslist(pwadj)) {
197*722Smuffin 				return (pwadj);
1980Sstevel@tonic-gate 			}
1990Sstevel@tonic-gate 		} else if (getnetgrent(&mach,&user,&dom)) {
2000Sstevel@tonic-gate 			if (user) {
2010Sstevel@tonic-gate 				pwadj = getnamefromyellow(user, savepwadj);
2020Sstevel@tonic-gate 				if (pwadj != NULL && !onminuslist(pwadj)) {
203*722Smuffin 					return (pwadj);
2040Sstevel@tonic-gate 				}
2050Sstevel@tonic-gate 			}
2060Sstevel@tonic-gate 		} else {
2070Sstevel@tonic-gate 			endnetgrent();
2080Sstevel@tonic-gate 			if (fgets(line, BUFSIZ, pwfadj) == NULL)  {
209*722Smuffin 				return (NULL);
2100Sstevel@tonic-gate 			}
2110Sstevel@tonic-gate 			if ((pwadj = interpret(line, strlen(line))) == NULL)
212*722Smuffin 				return (NULL);
2130Sstevel@tonic-gate 			switch(line[0]) {
2140Sstevel@tonic-gate 			case '+':
2150Sstevel@tonic-gate 				if (strcmp(pwadj->pwa_name, "+") == 0) {
2160Sstevel@tonic-gate 					getfirstfromyellow();
2170Sstevel@tonic-gate 					savepwadj = save(pwadj);
2180Sstevel@tonic-gate 				} else if (line[1] == '@') {
2190Sstevel@tonic-gate 					savepwadj = save(pwadj);
2200Sstevel@tonic-gate 					if (innetgr(pwadj->pwa_name+2,(char *) NULL,"*",domain)) {
2210Sstevel@tonic-gate 						/* include the whole NIS database */
2220Sstevel@tonic-gate 						getfirstfromyellow();
2230Sstevel@tonic-gate 					} else {
2240Sstevel@tonic-gate 						setnetgrent(pwadj->pwa_name+2);
2250Sstevel@tonic-gate 					}
2260Sstevel@tonic-gate 				} else {
2270Sstevel@tonic-gate 					/*
2280Sstevel@tonic-gate 					 * else look up this entry in NIS
2290Sstevel@tonic-gate 				 	 */
2300Sstevel@tonic-gate 					savepwadj = save(pwadj);
2310Sstevel@tonic-gate 					pwadj = getnamefromyellow(pwadj->pwa_name+1, savepwadj);
2320Sstevel@tonic-gate 					if (pwadj != NULL && !onminuslist(pwadj)) {
233*722Smuffin 						return (pwadj);
2340Sstevel@tonic-gate 					}
2350Sstevel@tonic-gate 				}
2360Sstevel@tonic-gate 				break;
2370Sstevel@tonic-gate 			case '-':
2380Sstevel@tonic-gate 				if (line[1] == '@') {
2390Sstevel@tonic-gate 					if (innetgr(pwadj->pwa_name+2,(char *) NULL,"*",domain)) {
2400Sstevel@tonic-gate 						/* everybody was subtracted */
241*722Smuffin 						return (NULL);
2420Sstevel@tonic-gate 					}
2430Sstevel@tonic-gate 					setnetgrent(pwadj->pwa_name+2);
2440Sstevel@tonic-gate 					while (getnetgrent(&mach,&user,&dom)) {
2450Sstevel@tonic-gate 						if (user) {
2460Sstevel@tonic-gate 							addtominuslist(user);
2470Sstevel@tonic-gate 						}
2480Sstevel@tonic-gate 					}
2490Sstevel@tonic-gate 					endnetgrent();
2500Sstevel@tonic-gate 				} else {
2510Sstevel@tonic-gate 					addtominuslist(pwadj->pwa_name+1);
2520Sstevel@tonic-gate 				}
2530Sstevel@tonic-gate 				break;
2540Sstevel@tonic-gate 			default:
2550Sstevel@tonic-gate 				if (!onminuslist(pwadj)) {
256*722Smuffin 					return (pwadj);
2570Sstevel@tonic-gate 				}
2580Sstevel@tonic-gate 				break;
2590Sstevel@tonic-gate 			}
2600Sstevel@tonic-gate 		}
2610Sstevel@tonic-gate 	}
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate 
264*722Smuffin static int
matchname(char line1[],struct passwd_adjunct ** pwadjp,char * name)265*722Smuffin matchname(char line1[], struct passwd_adjunct **pwadjp, char *name)
2660Sstevel@tonic-gate {
267*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
2680Sstevel@tonic-gate 	struct passwd_adjunct *savepwadj;
2690Sstevel@tonic-gate 	struct passwd_adjunct *pwadj = *pwadjp;
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	if (_pwa == 0)
2720Sstevel@tonic-gate 		return (0);
2730Sstevel@tonic-gate 	switch(line1[0]) {
2740Sstevel@tonic-gate 		case '+':
2750Sstevel@tonic-gate 			if (strcmp(pwadj->pwa_name, "+") == 0) {
2760Sstevel@tonic-gate 				savepwadj = save(pwadj);
2770Sstevel@tonic-gate 				pwadj = getnamefromyellow(name, savepwadj);
2780Sstevel@tonic-gate 				if (pwadj) {
2790Sstevel@tonic-gate 					*pwadjp = pwadj;
280*722Smuffin 					return (1);
2810Sstevel@tonic-gate 				}
2820Sstevel@tonic-gate 				else
283*722Smuffin 					return (0);
2840Sstevel@tonic-gate 			}
2850Sstevel@tonic-gate 			if (line1[1] == '@') {
2860Sstevel@tonic-gate 				if (innetgr(pwadj->pwa_name+2,(char *) NULL,name,domain)) {
2870Sstevel@tonic-gate 					savepwadj = save(pwadj);
2880Sstevel@tonic-gate 					pwadj = getnamefromyellow(name,savepwadj);
2890Sstevel@tonic-gate 					if (pwadj) {
2900Sstevel@tonic-gate 						*pwadjp = pwadj;
291*722Smuffin 						return (1);
2920Sstevel@tonic-gate 					}
2930Sstevel@tonic-gate 				}
294*722Smuffin 				return (0);
2950Sstevel@tonic-gate 			}
2960Sstevel@tonic-gate 			if (strcmp(pwadj->pwa_name+1, name) == 0) {
2970Sstevel@tonic-gate 				savepwadj = save(pwadj);
2980Sstevel@tonic-gate 				pwadj = getnamefromyellow(pwadj->pwa_name+1, savepwadj);
2990Sstevel@tonic-gate 				if (pwadj) {
3000Sstevel@tonic-gate 					*pwadjp = pwadj;
301*722Smuffin 					return (1);
3020Sstevel@tonic-gate 				}
3030Sstevel@tonic-gate 				else
304*722Smuffin 					return (0);
3050Sstevel@tonic-gate 			}
3060Sstevel@tonic-gate 			break;
3070Sstevel@tonic-gate 		case '-':
3080Sstevel@tonic-gate 			if (line1[1] == '@') {
3090Sstevel@tonic-gate 				if (innetgr(pwadj->pwa_name+2,(char *) NULL,name,domain)) {
3100Sstevel@tonic-gate 					*pwadjp = NULL;
311*722Smuffin 					return (1);
3120Sstevel@tonic-gate 				}
3130Sstevel@tonic-gate 			}
3140Sstevel@tonic-gate 			else if (strcmp(pwadj->pwa_name+1, name) == 0) {
3150Sstevel@tonic-gate 				*pwadjp = NULL;
316*722Smuffin 				return (1);
3170Sstevel@tonic-gate 			}
3180Sstevel@tonic-gate 			break;
3190Sstevel@tonic-gate 		default:
3200Sstevel@tonic-gate 			if (strcmp(pwadj->pwa_name, name) == 0)
321*722Smuffin 				return (1);
3220Sstevel@tonic-gate 	}
323*722Smuffin 	return (0);
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate 
326*722Smuffin static void
getnextfromyellow(void)327*722Smuffin getnextfromyellow(void)
3280Sstevel@tonic-gate {
329*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
3300Sstevel@tonic-gate 	int reason;
3310Sstevel@tonic-gate 	char *key;
3320Sstevel@tonic-gate 	int keylen;
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 	if (_pwa == 0)
3350Sstevel@tonic-gate 		return;
3360Sstevel@tonic-gate 	reason = yp_next(domain, "passwd_adjunct",oldyp, oldyplen, &key
3370Sstevel@tonic-gate 	    ,&keylen,&yp,&yplen);
3380Sstevel@tonic-gate 	if (reason) {
3390Sstevel@tonic-gate #ifdef DEBUG
3400Sstevel@tonic-gate fprintf(stderr, "reason yp_next failed is %d\n", reason);
3410Sstevel@tonic-gate #endif
3420Sstevel@tonic-gate 		yp = NULL;
3430Sstevel@tonic-gate 	}
3440Sstevel@tonic-gate 	if (oldyp)
3450Sstevel@tonic-gate 		free(oldyp);
3460Sstevel@tonic-gate 	oldyp = key;
3470Sstevel@tonic-gate 	oldyplen = keylen;
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate 
350*722Smuffin static void
getfirstfromyellow(void)351*722Smuffin getfirstfromyellow(void)
3520Sstevel@tonic-gate {
353*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
3540Sstevel@tonic-gate 	int reason;
3550Sstevel@tonic-gate 	char *key;
3560Sstevel@tonic-gate 	int keylen;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	if (_pwa == 0)
3590Sstevel@tonic-gate 		return;
3600Sstevel@tonic-gate 	reason =  yp_first(domain, "passwd_adjunct", &key, &keylen, &yp, &yplen);
3610Sstevel@tonic-gate 	if (reason) {
3620Sstevel@tonic-gate #ifdef DEBUG
3630Sstevel@tonic-gate fprintf(stderr, "reason yp_first failed is %d\n", reason);
3640Sstevel@tonic-gate #endif
3650Sstevel@tonic-gate 		yp = NULL;
3660Sstevel@tonic-gate 	}
3670Sstevel@tonic-gate 	if (oldyp)
3680Sstevel@tonic-gate 		free(oldyp);
3690Sstevel@tonic-gate 	oldyp = key;
3700Sstevel@tonic-gate 	oldyplen = keylen;
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate static struct passwd_adjunct *
getnamefromyellow(char * name,struct passwd_adjunct * savepwadj)374*722Smuffin getnamefromyellow(char *name, struct passwd_adjunct *savepwadj)
3750Sstevel@tonic-gate {
376*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
3770Sstevel@tonic-gate 	struct passwd_adjunct *pwadj;
3780Sstevel@tonic-gate 	int reason;
3790Sstevel@tonic-gate 	char *val;
3800Sstevel@tonic-gate 	int vallen;
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	if (_pwa == 0)
383*722Smuffin 		return (NULL);
3840Sstevel@tonic-gate 	reason = yp_match(domain, "passwd.adjunct.byname", name, strlen(name)
3850Sstevel@tonic-gate 		, &val, &vallen);
3860Sstevel@tonic-gate 	if (reason) {
3870Sstevel@tonic-gate #ifdef DEBUG
3880Sstevel@tonic-gate fprintf(stderr, "reason yp_match failed is %d\n", reason);
3890Sstevel@tonic-gate #endif
390*722Smuffin 		return (NULL);
3910Sstevel@tonic-gate 	} else {
3920Sstevel@tonic-gate 		pwadj = interpret(val, vallen);
3930Sstevel@tonic-gate 		free(val);
3940Sstevel@tonic-gate 		if (pwadj == NULL)
395*722Smuffin 			return (NULL);
3960Sstevel@tonic-gate 		if (savepwadj->pwa_passwd && *savepwadj->pwa_passwd)
3970Sstevel@tonic-gate 			pwadj->pwa_passwd =  savepwadj->pwa_passwd;
398*722Smuffin 		return (pwadj);
3990Sstevel@tonic-gate 	}
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate static struct passwd_adjunct *
interpretwithsave(char * val,int len,struct passwd_adjunct * savepwadj)403*722Smuffin interpretwithsave(char *val, int len, struct passwd_adjunct *savepwadj)
4040Sstevel@tonic-gate {
405*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
4060Sstevel@tonic-gate 	struct passwd_adjunct *pwadj;
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	if (_pwa == 0)
409*722Smuffin 		return (NULL);
4100Sstevel@tonic-gate 	if ((pwadj = interpret(val, len)) == NULL)
411*722Smuffin 		return (NULL);
4120Sstevel@tonic-gate 	if (savepwadj->pwa_passwd && *savepwadj->pwa_passwd)
4130Sstevel@tonic-gate 		pwadj->pwa_passwd =  savepwadj->pwa_passwd;
414*722Smuffin 	return (pwadj);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate static char *
pwskip(char * p)418*722Smuffin pwskip(char *p)
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate 	while(*p && *p != ':' && *p != '\n')
4210Sstevel@tonic-gate 		++p;
4220Sstevel@tonic-gate 	if (*p == '\n')
4230Sstevel@tonic-gate 		*p = '\0';
4240Sstevel@tonic-gate 	else if (*p != '\0')
4250Sstevel@tonic-gate 		*p++ = '\0';
426*722Smuffin 	return (p);
4270Sstevel@tonic-gate }
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate static struct passwd_adjunct *
interpret(char * val,int len)430*722Smuffin interpret(char *val, int len)
4310Sstevel@tonic-gate {
432*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
433*722Smuffin 	char *p;
4340Sstevel@tonic-gate 	char *field;
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate 	if (_pwa == 0)
437*722Smuffin 		return (NULL);
4380Sstevel@tonic-gate 	(void) strncpy(interpline, val, len);
4390Sstevel@tonic-gate 	p = interpline;
4400Sstevel@tonic-gate 	interpline[len] = '\n';
4410Sstevel@tonic-gate 	interpline[len+1] = 0;
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	apwadj.pwa_name = p;
4440Sstevel@tonic-gate 	p = pwskip(p);
4450Sstevel@tonic-gate 	if (strcmp(apwadj.pwa_name, "+") == 0) {
4460Sstevel@tonic-gate 		/* we are going to the NIS - fix the
4470Sstevel@tonic-gate 		 * rest of the struct as much as is needed
4480Sstevel@tonic-gate 		 */
4490Sstevel@tonic-gate 		apwadj.pwa_passwd = "";
4500Sstevel@tonic-gate 		return (&apwadj);
4510Sstevel@tonic-gate 	}
4520Sstevel@tonic-gate 	apwadj.pwa_passwd = p;
4530Sstevel@tonic-gate 	p = pwskip(p);
4540Sstevel@tonic-gate 	field = p;
4550Sstevel@tonic-gate 	p = pwskip(p);
4560Sstevel@tonic-gate 	labelfromstring(0, field, &apwadj.pwa_minimum);
4570Sstevel@tonic-gate 	field = p;
4580Sstevel@tonic-gate 	p = pwskip(p);
4590Sstevel@tonic-gate 	labelfromstring(0, field, &apwadj.pwa_maximum);
4600Sstevel@tonic-gate 	field = p;
4610Sstevel@tonic-gate 	p = pwskip(p);
4620Sstevel@tonic-gate 	labelfromstring(0, field, &apwadj.pwa_def);
4630Sstevel@tonic-gate 	field = p;
4640Sstevel@tonic-gate 	p = pwskip(p);
4650Sstevel@tonic-gate 	apwadj.pwa_au_always.as_success = 0;
4660Sstevel@tonic-gate 	apwadj.pwa_au_always.as_failure = 0;
4670Sstevel@tonic-gate 	if (getauditflagsbin(field, &apwadj.pwa_au_always) != 0)
468*722Smuffin 		return (NULL);
4690Sstevel@tonic-gate 	field = p;
4700Sstevel@tonic-gate 	(void) pwskip(p);
4710Sstevel@tonic-gate 	p = apwadj.pwa_passwd;
4720Sstevel@tonic-gate 	while (*p && *p != ',')
4730Sstevel@tonic-gate 		p++;
4740Sstevel@tonic-gate 	if (*p)
4750Sstevel@tonic-gate 		*p = '\0';
4760Sstevel@tonic-gate 	apwadj.pwa_age = p;
4770Sstevel@tonic-gate 	apwadj.pwa_au_never.as_success = 0;
4780Sstevel@tonic-gate 	apwadj.pwa_au_never.as_failure = 0;
4790Sstevel@tonic-gate 	if (getauditflagsbin(field, &apwadj.pwa_au_never) != 0)
480*722Smuffin 		return (NULL);
481*722Smuffin 	return (&apwadj);
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate 
484*722Smuffin static void
freeminuslist(void)485*722Smuffin freeminuslist(void) {
486*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
4870Sstevel@tonic-gate 	struct list *ls;
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 	if (_pwa == 0)
4900Sstevel@tonic-gate 		return;
4910Sstevel@tonic-gate 	for (ls = minuslist; ls != NULL; ls = ls->nxt) {
4920Sstevel@tonic-gate 		free(ls->name);
4930Sstevel@tonic-gate 		free((char *) ls);
4940Sstevel@tonic-gate 	}
4950Sstevel@tonic-gate 	minuslist = NULL;
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate 
498*722Smuffin static void
addtominuslist(char * name)499*722Smuffin addtominuslist(char *name)
5000Sstevel@tonic-gate {
501*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
5020Sstevel@tonic-gate 	struct list *ls;
5030Sstevel@tonic-gate 	char *buf;
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	if (_pwa == 0)
5060Sstevel@tonic-gate 		return;
5070Sstevel@tonic-gate 	ls = (struct list *) malloc(sizeof(struct list));
5080Sstevel@tonic-gate 	buf = malloc((unsigned) strlen(name) + 1);
5090Sstevel@tonic-gate 	(void) strcpy(buf, name);
5100Sstevel@tonic-gate 	ls->name = buf;
5110Sstevel@tonic-gate 	ls->nxt = minuslist;
5120Sstevel@tonic-gate 	minuslist = ls;
5130Sstevel@tonic-gate }
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate /*
5160Sstevel@tonic-gate  * save away the psswd field, which is the only one which can be
5170Sstevel@tonic-gate  * specified in a local + entry to override the value in the NIS
5180Sstevel@tonic-gate  * for passwd.adjunct
5190Sstevel@tonic-gate  */
5200Sstevel@tonic-gate static struct passwd_adjunct *
save(struct passwd_adjunct * pwadj)521*722Smuffin save(struct passwd_adjunct *pwadj)
5220Sstevel@tonic-gate {
523*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
5240Sstevel@tonic-gate 	static struct passwd_adjunct *sv;
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate 	if (_pwa == 0)
527*722Smuffin 		return (NULL);
5280Sstevel@tonic-gate 	/* free up stuff from last call */
5290Sstevel@tonic-gate 	if (sv) {
5300Sstevel@tonic-gate 		free(sv->pwa_passwd);
5310Sstevel@tonic-gate 		free((char *) sv);
5320Sstevel@tonic-gate 	}
5330Sstevel@tonic-gate 	sv = (struct passwd_adjunct *) malloc(sizeof(struct passwd_adjunct));
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 	sv->pwa_passwd = malloc((unsigned) strlen(pwadj->pwa_passwd) + 1);
5360Sstevel@tonic-gate 	(void) strcpy(sv->pwa_passwd, pwadj->pwa_passwd);
5370Sstevel@tonic-gate 
538*722Smuffin 	return (sv);
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate 
541*722Smuffin static int
onminuslist(struct passwd_adjunct * pwadj)542*722Smuffin onminuslist(struct passwd_adjunct *pwadj)
5430Sstevel@tonic-gate {
544*722Smuffin 	struct _pwajunk *_pwa = _pwajunk();
5450Sstevel@tonic-gate 	struct list *ls;
546*722Smuffin 	char *nm;
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 	if (_pwa == 0)
549*722Smuffin 		return (0);
5500Sstevel@tonic-gate 	nm = pwadj->pwa_name;
5510Sstevel@tonic-gate 	for (ls = minuslist; ls != NULL; ls = ls->nxt) {
5520Sstevel@tonic-gate 		if (strcmp(ls->name,nm) == 0) {
553*722Smuffin 			return (1);
5540Sstevel@tonic-gate 		}
5550Sstevel@tonic-gate 	}
556*722Smuffin 	return (0);
5570Sstevel@tonic-gate }
558