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