NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/43852: yp_passwd command may destroy NIS database entries when used on a server that includes users via netgroups
>Number: 43852
>Category: bin
>Synopsis: yp_passwd command may destroy NIS database entries when used
>on a server that includes users via netgroups
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Sep 08 12:25:00 +0000 2010
>Originator: Dr. Wolfgang Stukenbrock
>Release: NetBSD 5.0.2
>Organization:
Sr. Nagler & Company GmbH
>Environment:
System: NetBSD s051 5.0.2 NetBSD 5.0.2 (NSW-S051) #2: Thu Aug 12 18:30:48 CEST
2010 wgstuken@s051:/usr/src/sys/arch/amd64/compile/NSW-S051 amd64
Architecture: x86_64
Machine: amd64
>Description:
There has been a problem (in 4.x) with the same topic that "has" been
fixed by PR 37863.
I've send a patch for that, but accedently this patch has been modified
prio applying it in a way,
that the misbehaviour is not fixed.
The password structure obtained from YP gets overwritten by the data
from the local system
(by calling getpwnam_r() with the same structure) again, so that the
same bug is in there as before!
I've checked the top-level version in CVS, the bug is still in there.
I'm not shure why the usage of getpwnam_r() has been choosen at all.
Prio PR37863 getpwnam() is used and my original patch also used
getpwnam().
There may be reasons why this is the better way of dooing it this way
that I cannot see.
There is a static buffer of 1024 bytes now, that would be obsolete if
getpwnam() is used. And the
current code assumes, that the dynamic parts like passwd, path to
home, gecos and shell will fit into
theese 1024 bytes.
Neverless I've created a fix for the still existing problem based on
the current source of 5.0.2 and let
the getpwnam_r() in it.
>How-To-Repeat:
same as in PR 37863 before ....
>Fix:
apply the following patch to /usr/src/usr.bin/passwd/yp_passwd.c
--- yp_passwd.c 2010/09/08 11:55:11 1.1
+++ yp_passwd.c 2010/09/08 11:59:42
@@ -212,7 +212,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;
@@ -284,16 +284,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)
@@ -374,7 +374,7 @@
char *master;
int r, rpcport, status;
struct yppasswd ypp;
- struct passwd *pw, pwb;
+ struct passwd *pw, pwb, pwb2;
char pwbuf[1024];
struct timeval tv;
CLIENT *client;
@@ -418,19 +418,19 @@
/* 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) {
warnx("NIS unknown user %s", username);
/* continuation */
return(-1);
}
- 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) {
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index