bin/52601: [PATCH] rpc.yppasswdd fails if master.passwd is not in
/etc/
Dan Nelson
dnelson at allantgroup.com
Thu May 22 21:40:13 PDT 2003
>Number: 52601
>Category: bin
>Synopsis: [PATCH] rpc.yppasswdd fails if master.passwd is not in /etc/
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu May 22 21:40:11 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator: Dan Nelson
>Release: FreeBSD 5.1-BETA i386
>Organization:
The Allant Group
>Environment:
System: FreeBSD dan.emsphone.com 5.1-BETA FreeBSD 5.1-BETA #270: Thu May 22 09:18:13 CDT 2003 dan at dan.emsphone.com:/usr/src/sys/i386/compile/DANSMP i386
>Description:
rpc.yppasswd always calls yp_mkdb on master.passwd, which really should
only be done if you are exporting /etc/master.passwd.
>How-To-Repeat:
Set up an NIS server, and run passwd on a client. If it succeeds,
you'll see that passwd.db and spwd.db get created in /yar/yp. It also
ends up zeroing out the passwd field in the passwd map, which is not a
good idea if you're serving non-FreeBSD clients.
>Fix:
Only call pw_mkdb if passfile == _PATH_MASTERPASSWD. Otherwise, rename
master.passwd to a temp filename, rename the new passwd to
master.passwd, and let yppwupdate update passwd as it sees fit.
This also fixes PR bin/7968.
Index: yppasswdd_server.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/rpc.yppasswdd/yppasswdd_server.c,v
retrieving revision 1.27
diff -u -p -r1.27 yppasswdd_server.c
--- yppasswdd_server.c 3 May 2003 21:06:39 -0000 1.27
+++ yppasswdd_server.c 23 May 2003 04:06:29 -0000
@@ -448,6 +448,7 @@ yppasswdproc_update_1_svc(yppasswd *argp
char *oldgecos = NULL;
char *passfile_hold;
char passfile_buf[MAXPATHLEN + 2];
+ char passfile_hold_buf[MAXPATHLEN + 2];
char *domain = yppasswd_domain;
static struct sockaddr_in clntaddr;
static struct timeval t_saved, t_test;
@@ -572,6 +573,11 @@ yppasswdproc_update_1_svc(yppasswd *argp
passfile = (char *)&passfile_buf;
}
+ /* Create a filename to hold the original master.passwd so if our call
+ to yppwupdate fails we can roll back */
+ snprintf(passfile_hold_buf, sizeof(passfile_hold_buf), "%s.hold", passfile);
+ passfile_hold = (char *)&passfile_hold_buf;
+
/* Step 5: make a new password file with the updated info. */
if (pw_init(dirname(passfile), passfile)) {
@@ -593,11 +599,32 @@ yppasswdproc_update_1_svc(yppasswd *argp
yp_error("pw_copy() failed");
return &result;
}
- if (pw_mkdb(yp_password.pw_name) == -1) {
+ if (rename(passfile, passfile_hold) == -1) {
pw_fini();
- yp_error("pw_mkdb() failed");
+ yp_error("rename of %s to %s failed", passfile, passfile_hold);
return &result;
}
+ if (strcmp(passfile, _PATH_MASTERPASSWD) == 0) {
+ /* NIS server is exporting the system's master.passwd. */
+ /* Call pw_mkdb to rebuild passwd and the .db files */
+ if (pw_mkdb(yp_password.pw_name) == -1) {
+ pw_fini();
+ yp_error("pw_mkdb() failed");
+ rename(passfile_hold, passfile);
+ return &result;
+ }
+ } else
+ {
+ /* NIS server is exporting a private master.passwd. */
+ /* Rename tempfile into final location */
+ if (rename(pw_tempname(), passfile) == -1) {
+ pw_fini();
+ yp_error("rename of %s to %s failed", pw_tempname(), passfile);
+ rename(passfile_hold, passfile);
+ return &result;
+ }
+ }
+
pw_fini();
if (inplace) {
@@ -633,9 +660,10 @@ yppasswdproc_update_1_svc(yppasswd *argp
}
if (verbose) {
- yp_error("update completed for user %s (uid %d):",
+ yp_error("update completed for user %s (uid %d) in %s:",
argp->newpw.pw_name,
- argp->newpw.pw_uid);
+ argp->newpw.pw_uid,
+ passfile);
if (passwd_changed)
yp_error("password changed");
@@ -677,7 +705,7 @@ yppasswdproc_update_master_1_svc(master_
transp = rqstp->rq_xprt;
/*
- * NO AF_INET CONNETCIONS ALLOWED!
+ * NO AF_INET CONNECTIONS ALLOWED!
*/
rqhost = svc_getcaller(transp);
if (rqhost->sin_family != AF_UNIX) {
@@ -780,10 +808,12 @@ allow additions to be made to the passwo
yp_error("pw_copy() failed");
return &result;
}
- if (pw_mkdb(argp->newpw.pw_name) == -1) {
- pw_fini();
- yp_error("pw_mkdb() failed");
- return &result;
+ if (strcmp(passfile, _PATH_MASTERPASSWD) == 0) {
+ if (pw_mkdb(argp->newpw.pw_name) == -1) {
+ pw_fini();
+ yp_error("pw_mkdb() failed");
+ return &result;
+ }
}
pw_fini();
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list