From 5126bebe35d659ea3599c987e6350ee5f3b6d2b7 Mon Sep 17 00:00:00 2001 From: deraadt Date: Tue, 2 Aug 2022 17:00:15 +0000 Subject: [PATCH] 1) The yp_bind/yp_unbind and internal _yp_dobind/_yp_unbind sequences shared dom_binding structs between threads, which is unsafe -- example, dom_vers signalled retry events, and structs+socket would get deallocated in _yp_unbind. Change all yp_first (and similar) functions to understand that _yp_dobind now provides a private dom_binding and socket, which must be released using _yp_unbind. Use similar methods in the one-step yp_all function. 2) domainname caching in get* is not neccessary now that the domainname cannot change relative to ypconnect(2)'s decisions. Many fields in dom_binding struct become unused, so delete them. ok jmatthew, also tested by miod --- lib/libc/gen/getgrent.c | 16 +++------------- lib/libc/gen/getgrouplist.c | 7 +++---- lib/libc/gen/getnetgrent.c | 29 +++++++++++++++++------------ lib/libc/gen/getpwent.c | 26 +++++++------------------- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index 3b7c65bfdeb..106f6c3f9dd 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getgrent.c,v 1.49 2022/07/17 03:10:47 deraadt Exp $ */ +/* $OpenBSD: getgrent.c,v 1.50 2022/08/02 17:00:15 deraadt Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -341,18 +341,8 @@ grscan(int search, gid_t gid, const char *name, struct group *p_gr, } #ifdef YP if (line[0] == '+' || line[0] == '-') { - if (__ypdomain == NULL && - yp_get_default_domain(&__ypdomain)) - goto parse; - switch (yp_bind(__ypdomain)) { - case 0: - break; - case YPERR_BADARGS: - case YPERR_YPBIND: - goto parse; - default: - return 0; - } + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); } if (line[0] == '+') { switch (line[1]) { diff --git a/lib/libc/gen/getgrouplist.c b/lib/libc/gen/getgrouplist.c index b390449eef2..b23b937faf0 100644 --- a/lib/libc/gen/getgrouplist.c +++ b/lib/libc/gen/getgrouplist.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getgrouplist.c,v 1.29 2022/07/17 03:10:47 deraadt Exp $ */ +/* $OpenBSD: getgrouplist.c,v 1.30 2022/08/02 17:00:15 deraadt Exp $ */ /* * Copyright (c) 2008 Ingo Schwarze * Copyright (c) 1991, 1993 @@ -223,9 +223,8 @@ getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) } /* Only access YP when there is no static entry. */ - if (!yp_bind(__ypdomain) && - !yp_match(__ypdomain, "netid.byname", key, - (int)strlen(key), &ypdata, &ypdatalen)) + if (!yp_match(__ypdomain, "netid.byname", key, + (int)strlen(key), &ypdata, &ypdatalen)) if (_parse_netid(ypdata, pwstore.pw_uid, groups, &ngroups, maxgroups) == -1) ret = -1; diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c index bd02e09bdfe..26761bde493 100644 --- a/lib/libc/gen/getnetgrent.c +++ b/lib/libc/gen/getnetgrent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getnetgrent.c,v 1.28 2016/09/24 12:43:37 millert Exp $ */ +/* $OpenBSD: getnetgrent.c,v 1.29 2022/08/02 17:00:15 deraadt Exp $ */ /* * Copyright (c) 1994 Christos Zoulas @@ -619,7 +619,8 @@ setnetgrent(const char *ng) { struct stringlist *sl; #ifdef YP - char *line; + static char *__ypdomain; + char *line = NULL; #endif char *ng_copy, *ypdom = NULL; @@ -639,10 +640,12 @@ setnetgrent(const char *ng) * We use yp if there is a "+" in the netgroup file, or if there is * no netgroup file at all */ - if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) - yp_get_default_domain(&ypdom); - else - free(line); + if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) { + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); + ypdom = __ypdomain; + } + free(line); #endif ng_copy = strdup(ng); if (ng_copy != NULL) @@ -673,9 +676,10 @@ DEF_WEAK(getnetgrent); int innetgr(const char *grp, const char *host, const char *user, const char *domain) { - char *ypdom = NULL, *grpdup; + char *ypdom = NULL, *grpdup; #ifdef YP - char *line = NULL; + static char *__ypdomain; + char *line = NULL; #endif int found; struct stringlist *sl; @@ -688,10 +692,11 @@ innetgr(const char *grp, const char *host, const char *user, const char *domain) * We use yp if there is a "+" in the netgroup file, or if there is * no netgroup file at all */ - if (_ng_db == NULL) - yp_get_default_domain(&ypdom); - else if (lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) - yp_get_default_domain(&ypdom); + if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) { + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); + ypdom = __ypdomain; + } free(line); #endif diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 7ddbe332e4c..24ac8f96c3a 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getpwent.c,v 1.65 2022/07/17 03:10:47 deraadt Exp $ */ +/* $OpenBSD: getpwent.c,v 1.66 2022/08/02 17:00:15 deraadt Exp $ */ /* * Copyright (c) 2008 Theo de Raadt * Copyright (c) 1988, 1993 @@ -332,12 +332,8 @@ again: int keylen, datalen, r, s; char *key, *data = NULL; - if (!__ypdomain) { - if (_yp_check(&__ypdomain) == 0) { - __ypmode = YPMODE_NONE; - goto again; - } - } + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); switch (__ypmode) { case YPMODE_FULL: if (__ypcurrent) { @@ -538,14 +534,8 @@ __has_ypmaster(void) return (checked); } - if (!__ypdomain) { - if (_yp_check(&__ypdomain) == 0) { - saved_uid = uid; - saved_euid = euid; - checked = 0; - return (checked); /* No domain. */ - } - } + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); if (yp_first(__ypdomain, "master.passwd.byname", &key, &keylen, &result, &resultlen)) { @@ -583,10 +573,8 @@ __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw, break; switch (pw->pw_name[0]) { case '+': - if (!__ypdomain) { - if (_yp_check(&__ypdomain) == 0) - continue; - } + if (!__ypdomain) + yp_get_default_domain(&__ypdomain); __ypproto_set(pw, &__yppbuf, *flagsp, &yp_pw_flags); if (!map) { if (lookup == LOOKUP_BYNAME) { -- 2.20.1