From owner-freebsd-bugs@FreeBSD.ORG Thu May 22 21:40:12 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CBE7D37B404 for ; Thu, 22 May 2003 21:40:12 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 84E4043FAF for ; Thu, 22 May 2003 21:40:11 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h4N4eBUp051417 for ; Thu, 22 May 2003 21:40:11 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h4N4eBIc051416; Thu, 22 May 2003 21:40:11 -0700 (PDT) Resent-Date: Thu, 22 May 2003 21:40:11 -0700 (PDT) Resent-Message-Id: <200305230440.h4N4eBIc051416@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Dan Nelson Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5CB5637B401 for ; Thu, 22 May 2003 21:33:10 -0700 (PDT) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by mx1.FreeBSD.org (Postfix) with ESMTP id B0F9843F3F for ; Thu, 22 May 2003 21:33:09 -0700 (PDT) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.12.9/8.12.9) id h4N4X99D064233; Thu, 22 May 2003 23:33:09 -0500 (CDT) (envelope-from dan) Message-Id: <200305230433.h4N4X99D064233@dan.emsphone.com> Date: Thu, 22 May 2003 23:33:09 -0500 (CDT) From: Dan Nelson To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/52601: [PATCH] rpc.yppasswdd fails if master.passwd is not in /etc/ X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 May 2003 04:40:13 -0000 >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@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: