* fix _compat_getpw so that it returns _local_getpw(...) if there

isn't a `+' token in the files database.
  (this bug probably crept in when a merge to current occurred)
* ensure that the _bad_getpw callbacks in __getpwcompat have an
  argument for error reporting.
This commit is contained in:
lukem 1999-01-18 00:59:10 +00:00
parent fb846bde24
commit a360857d48

View File

@ -1,4 +1,4 @@
/* $NetBSD: getpwent.c,v 1.33 1999/01/16 14:42:54 lukem Exp $ */ /* $NetBSD: getpwent.c,v 1.34 1999/01/18 00:59:10 lukem Exp $ */
/* /*
* Copyright (c) 1988, 1993 * Copyright (c) 1988, 1993
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95"; static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
#else #else
__RCSID("$NetBSD: getpwent.c,v 1.33 1999/01/16 14:42:54 lukem Exp $"); __RCSID("$NetBSD: getpwent.c,v 1.34 1999/01/18 00:59:10 lukem Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
@ -670,10 +670,10 @@ __getpwcompat(type, uid, name)
const char *name; const char *name;
{ {
static ns_dtab dtab[] = { static ns_dtab dtab[] = {
NS_FILES_CB(_bad_getpw, NULL), NS_FILES_CB(_bad_getpw, "files"),
NS_DNS_CB(_dns_getpw, NULL), NS_DNS_CB(_dns_getpw, NULL),
NS_NIS_CB(_nis_getpw, NULL), NS_NIS_CB(_nis_getpw, NULL),
NS_COMPAT_CB(_bad_getpw, NULL), NS_COMPAT_CB(_bad_getpw, "compat"),
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
@ -822,19 +822,24 @@ _compat_getpw(rv, cb_data, ap)
va_list ap; va_list ap;
{ {
DBT key; DBT key;
int len, search, rval; int search, rval, r, s;
uid_t uid; uid_t uid;
char bf[MAXLOGNAME + 1]; char bf[MAXLOGNAME + 1];
const char *name; const char *name, *host, *user, *dom;
if (!_pw_db && !__initdb())
return NS_UNAVAIL;
/*
* If there isn't a compat token in the database, use files.
*/
if (! __has_compatpw())
return (_local_getpw(rv, cb_data, ap));
search = va_arg(ap, int); search = va_arg(ap, int);
uid = 0; uid = 0;
name = NULL; name = NULL;
rval = NS_NOTFOUND; rval = NS_NOTFOUND;
if (!_pw_db && !__initdb())
return NS_UNAVAIL;
switch (search) { switch (search) {
case _PW_KEYBYNAME: case _PW_KEYBYNAME:
name = va_arg(ap, const char *); name = va_arg(ap, const char *);
@ -846,120 +851,99 @@ _compat_getpw(rv, cb_data, ap)
abort(); abort();
} }
/* for(s = -1, _pw_keynum=1; _pw_keynum; _pw_keynum++) {
* If YP is active, we must sequence through the passwd file bf[0] = _PW_KEYBYNUM;
* in sequence. memmove(bf + 1, (char *)&_pw_keynum, sizeof(_pw_keynum));
*/ key.data = (u_char *)bf;
if (__has_compatpw()) { key.size = sizeof(_pw_keynum) + 1;
int r; if(__hashpw(&key) != NS_SUCCESS)
int s = -1; break;
const char *host, *user, *dom; switch(_pw_passwd.pw_name[0]) {
case '+':
/* save the prototype */
__pwproto_set();
for(_pw_keynum=1; _pw_keynum; _pw_keynum++) { switch(_pw_passwd.pw_name[1]) {
bf[0] = _PW_KEYBYNUM; case '\0':
memmove(bf + 1, (char *)&_pw_keynum, r = __getpwcompat(search, uid, name);
sizeof(_pw_keynum)); if (r != NS_SUCCESS)
key.data = (u_char *)bf; continue;
key.size = sizeof(_pw_keynum) + 1;
if(__hashpw(&key) != NS_SUCCESS)
break; break;
switch(_pw_passwd.pw_name[0]) { case '@':
case '+':
/* save the prototype */
__pwproto_set();
switch(_pw_passwd.pw_name[1]) {
case '\0':
r = __getpwcompat(search, uid, name);
if (r != NS_SUCCESS)
continue;
break;
case '@':
pwnam_netgrp: pwnam_netgrp:
if(__ypcurrent) { if(__ypcurrent) {
free(__ypcurrent); free(__ypcurrent);
__ypcurrent = NULL; __ypcurrent = NULL;
}
if(s == -1) /* first time */
setnetgrent(_pw_passwd.pw_name + 2);
s = getnetgrent(&host, &user, &dom);
if(s == 0) { /* end of group */
endnetgrent();
s = -1;
continue;
}
if (!user || !*user)
goto pwnam_netgrp;
r = __getpwcompat(_PW_KEYBYNAME,
0, user);
if (r == NS_UNAVAIL)
return r;
if (r == NS_NOTFOUND) {
/*
* just because this user is bad
* it doesn't mean they all are.
*/
goto pwnam_netgrp;
}
break;
default:
user = _pw_passwd.pw_name + 1;
r = __getpwcompat(_PW_KEYBYNAME,
0, user);
if (r == NS_UNAVAIL)
return r;
if (r == NS_NOTFOUND)
continue;
break;
} }
if(__pwexclude_is(_pw_passwd.pw_name)) { if (s == -1) /* first time */
if(s == 1) /* inside netgrp */ setnetgrent(_pw_passwd.pw_name + 2);
goto pwnam_netgrp; s = getnetgrent(&host, &user, &dom);
if (s == 0) { /* end of group */
endnetgrent();
s = -1;
continue; continue;
} }
break; if (!user || !*user)
case '-': goto pwnam_netgrp;
/* attempted exclusion */
switch(_pw_passwd.pw_name[1]) { r = __getpwcompat(_PW_KEYBYNAME, 0, user);
case '\0':
break; if (r == NS_UNAVAIL)
case '@': return r;
setnetgrent(_pw_passwd.pw_name + 2); if (r == NS_NOTFOUND) {
while(getnetgrent(&host, &user, &dom)) { /*
if(user && *user) * just because this user is bad
__pwexclude_add(user); * it doesn't mean they all are.
} */
endnetgrent(); goto pwnam_netgrp;
break;
default:
__pwexclude_add(_pw_passwd.pw_name + 1);
break;
} }
break; break;
} default:
if ((search == _PW_KEYBYNAME && user = _pw_passwd.pw_name + 1;
strcmp(_pw_passwd.pw_name, name) == 0) r = __getpwcompat(_PW_KEYBYNAME, 0, user);
|| (search == _PW_KEYBYUID &&
_pw_passwd.pw_uid == uid)) { if (r == NS_UNAVAIL)
rval = NS_SUCCESS; return r;
if (r == NS_NOTFOUND)
continue;
break; break;
} }
if(s == 1) /* inside netgrp */ if(__pwexclude_is(_pw_passwd.pw_name)) {
goto pwnam_netgrp; if(s == 1) /* inside netgroup */
continue; goto pwnam_netgrp;
continue;
}
break;
case '-':
/* attempted exclusion */
switch(_pw_passwd.pw_name[1]) {
case '\0':
break;
case '@':
setnetgrent(_pw_passwd.pw_name + 2);
while(getnetgrent(&host, &user, &dom)) {
if(user && *user)
__pwexclude_add(user);
}
endnetgrent();
break;
default:
__pwexclude_add(_pw_passwd.pw_name + 1);
break;
}
break;
} }
__pwproto = (struct passwd *)NULL; if ((search == _PW_KEYBYNAME &&
} else { strcmp(_pw_passwd.pw_name, name) == 0)
bf[0] = _PW_KEYBYNAME; || (search == _PW_KEYBYUID && _pw_passwd.pw_uid == uid)) {
len = strlen(name); rval = NS_SUCCESS;
memmove(bf + 1, name, MIN(len, UT_NAMESIZE)); break;
key.data = (u_char *)bf; }
key.size = len + 1; if(s == 1) /* inside netgroup */
rval = __hashpw(&key); goto pwnam_netgrp;
continue;
} }
__pwproto = (struct passwd *)NULL;
if (!_pw_stayopen) { if (!_pw_stayopen) {
(void)(_pw_db->close)(_pw_db); (void)(_pw_db->close)(_pw_db);