Subject: bin/3806: passwd program can leave ptmp around if killed
To: None <gnats-bugs@gnats.netbsd.org>
From: Data In~rte~vgri}ity EnginNO CARRIER <greywolf@starwolf.com>
List: netbsd-bugs
Date: 06/28/1997 14:18:13
>Number:         3806
>Category:       bin
>Synopsis:       /usr/bin/passwd can leave /etc/ptmp around if killed (-KILL)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 28 14:50:01 1997
>Last-Modified:
>Originator:     Grey Wolf
>Organization:
Star Wolf Innovations
>Release:        1.2
>Environment:
	SPARCstation IPX, NetBSD 1.2E-current-970604, sun4c, ...
	
System: NetBSD starwolf.starwolf.com 1.2E NetBSD 1.2E (STARWOLF) #8: Wed Jun 4 01:11:20 PDT 1997 root@starwolf.starwolf.com:/usr/src/sys/arch/sparc/compile/STARWOLF sparc


>Description:
	/usr/bin/passwd can leave /etc/ptmp around if the process is sent
	a SIGKILL, causing a Denial-Of-Service for anyone wishing to modify
	the passwd file.
>How-To-Repeat:
	[in one window]
	% passwd
	Changing password for luser
	Old password:

	[in other window]
	% ps ax | grep passwd
	...
	% kill -9 {passwd-pid}
>Fix:
	The fix is not to try to create the lock file until all the
	information is obtained; don't do anything with ptmp until we
	verify the user's passwd and get the confirmed new password.
	
*** local_passwd.c	Sat Jun 28 01:16:12 1997
--- local_passwd.c.orig	Wed Jun 25 00:16:58 1997
***************
*** 143,165 ****
  		return (1);
  	}
  
- 
- 	/*
- 	 * Get the new password.  Reset passwd change time to zero; when
- 	 * classes are implemented, go and get the "offset" value for this
- 	 * class and reset the timer.
- 	 */
- 	pw->pw_passwd = getnewpasswd(pw);
- 
- 	/*
- 	 * This used to be before pw_init() above;
- 	 * it was moved because there existed a condition in which the
- 	 * passwd file could end up locked if the user killed the
- 	 * program somehow.
- 	 *
- 	 * The password file should NEVER be locked for longer than
- 	 * absolutely necessary.
- 	 */
  	pw_init();
  	tfd = pw_lock(0);
  	if (tfd < 0)
--- 143,148 ----
***************
*** 167,172 ****
--- 150,162 ----
  	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
  	if (pfd < 0)
  		pw_error(_PATH_MASTERPASSWD, 1, 1);
+ 
+ 	/*
+	 * Get the new password.  Reset passwd change time to zero; when
+ 	 * classes are implemented, go and get the "offset" value for this
+ 	 * class and reset the timer.
+ 	 */
+ 	pw->pw_passwd = getnewpasswd(pw);
  
  	pw->pw_change = 0;
  	pw_copy(pfd, tfd, pw);

>Audit-Trail:
>Unformatted: