Module Name: src Committed By: christos Date: Wed Sep 8 13:44:44 UTC 2010
Modified Files: src/usr.bin/passwd: yp_passwd.c Log Message: PR/43852: Wolfgang Stukenbrock: yp_passwd command may destroy NIS database entries when used on a server that includes users via netgroups. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/usr.bin/passwd/yp_passwd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/passwd/yp_passwd.c diff -u src/usr.bin/passwd/yp_passwd.c:1.33 src/usr.bin/passwd/yp_passwd.c:1.34 --- src/usr.bin/passwd/yp_passwd.c:1.33 Sun Apr 12 19:59:37 2009 +++ src/usr.bin/passwd/yp_passwd.c Wed Sep 8 09:44:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: yp_passwd.c,v 1.33 2009/04/12 23:59:37 lukem Exp $ */ +/* $NetBSD: yp_passwd.c,v 1.34 2010/09/08 13:44:44 christos Exp $ */ /* * Copyright (c) 1988, 1990, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)local_passwd.c 8.3 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: yp_passwd.c,v 1.33 2009/04/12 23:59:37 lukem Exp $"); +__RCSID("$NetBSD: yp_passwd.c,v 1.34 2010/09/08 13:44:44 christos Exp $"); #endif #endif /* not lint */ @@ -168,21 +168,26 @@ ypgetpwnam(const char *nam, struct passwd *pwd) { char *val; - int reason, vallen; - int flags; + int reason, vallen, namlen = (int)strlen(nam); + int flags = 0; int ok = 0; val = NULL; - reason = yp_match(domain, "passwd.byname", nam, (int)strlen(nam), - &val, &vallen); + reason = yp_match(domain, "master.passwd.byname", nam, namlen, + &val, &vallen); + if (reason == YPERR_MAP) { + reason = yp_match(domain, "passwd.byname", nam, namlen, + &val, &vallen); + flags = _PASSWORD_OLDFMT; + } if (reason != 0) goto out; - flags = _PASSWORD_OLDFMT; if (pw_scan(val, pwd, &flags) == 0) goto out; ok = 1; + val = NULL; /* Don't free the memory, it is still in use */ out: if (val) free(val); @@ -213,7 +218,7 @@ char *master; int ch, r, rpcport, status; struct yppasswd ypp; - struct passwd pwb, *pw; + struct passwd pwb, pwb2, *pw; char pwbuf[1024]; struct timeval tv; CLIENT *client; @@ -266,7 +271,7 @@ * the daemon. */ if ((r = yp_master(domain, "passwd.byname", &master)) != 0) - errx(1, "can't find the master NIS server. Reason: %s", + errx(1, "can't find the master NIS server. Reason: %s", yperr_string(r)); /* @@ -285,16 +290,16 @@ /* Bail out if this is a local (non-yp) user, */ /* then get user's login identity */ - if (!ypgetpwnam(username, pw = &pwb) || - getpwnam_r(username, &pwb, pwbuf, sizeof(pwbuf), &pw) || + if (!ypgetpwnam(username, &pwb) || + getpwnam_r(username, &pwb2, pwbuf, sizeof(pwbuf), &pw) || pw == NULL) errx(1, "NIS unknown user %s", username); - if (uid && uid != pw->pw_uid) + if (uid && uid != pwb.pw_uid) errx(1, "you may only change your own password: %s", strerror(EACCES)); - makeypp(&ypp, pw); + makeypp(&ypp, &pwb); client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); if (client == NULL)