From nobody  Wed Aug  6 12:08:55 1997
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.5/8.8.5) id MAA13607;
          Wed, 6 Aug 1997 12:08:55 -0700 (PDT)
Message-Id: <199708061908.MAA13607@hub.freebsd.org>
Date: Wed, 6 Aug 1997 12:08:55 -0700 (PDT)
From: schweikh@noc.dfn.de
To: freebsd-gnats-submit@freebsd.org
Subject: chpass only occasionally works in conjunction with ed
X-Send-Pr-Version: www-1.0

>Number:         4238
>Category:       bin
>Synopsis:       chpass only occasionally works in conjunction with ed
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    davidn
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug  6 12:10:01 PDT 1997
>Closed-Date:    Wed Jun 28 10:31:09 EST 2000
>Last-Modified:  Wed Jun 28 10:35:23 EST 2000
>Originator:     Jens Schweikhardt
>Release:        2.2.2-Release
>Organization:
DFN
>Environment:
2.2.2-Release HAL9000
>Description:
When I try to change the home directory of user 'toor' from
/root to whatever using the editor ed (see below) and chpass
then chpass only accepts the changes occasionally. IOW, I try
it between 2 and a dozen times until it succeeds. I read the
man page of chpass and could not find any explanation.
>How-To-Repeat:
% printf ',s,: /root,: /opt/home/root,\nw\nq\n' | EDITOR=ed chpass toor
282
291
chpass: no changes made
chpass: /etc/master.passwd: unchanged
% printf ',s,: /root,: /opt/home/root,\nw\nq\n' | EDITOR=ed chpass toor
282
291
chpass: no changes made
chpass: /etc/master.passwd: unchanged
% printf ',s,: /root,: /opt/home/root,\nw\nq\n' | EDITOR=ed chpass toor
282
291
chpass: no changes made
chpass: /etc/master.passwd: unchanged
% printf ',s,: /root,: /opt/home/root,\nw\nq\n' | EDITOR=ed chpass toor
282
291
chpass: no changes made
chpass: /etc/master.passwd: unchanged
% printf ',s,: /root,: /opt/home/root,\nw\nq\n' | EDITOR=ed chpass toor
282
291
chpass: rebuilding the database...
chpass: done

Notes:
282 is the number of chars before editing
291 is the number after the substitution is done
and the file is written, so the substitution did *not* fail.

If this is the correct behaviour of chpass then I'm slightly
confused. Doing the change interactively using vi always
succeeds right away.

And no, the system is not busy -- there is no one editing
password information databases other than me.
>Fix:

>Release-Note:
>Audit-Trail:

From: j@uriah.heep.sax.de (J Wunsch)
To: schweikh@noc.dfn.de
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/4238: chpass only occasionally works in conjunction with ed
Date: Thu, 7 Aug 1997 08:18:36 +0200

 As schweikh@noc.dfn.de wrote:
 
 > When I try to change the home directory of user 'toor' from
 > /root to whatever using the editor ed (see below) and chpass
 > then chpass only accepts the changes occasionally.
 
 UTSL.  You could have easily found the reason yourself:
 
 		if (begin.st_mtime == end.st_mtime) {
 			warnx("no changes made");
 			pw_error(NULL, 0, 0);
 		}
 
 That is, the editing process needs to last for at least one second
 right now, in order for chpass(1) to notice the modification on the
 file since it's only done using the file modification timestamp.
 
 Fix: include st_mtimensec into the consideration.
 
 -- 
 cheers, J"org
 
 joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE
 Never trust an operating system you don't have sources for. ;-)

From: Daniel Hagan <dhagan@cs.vt.edu>
To: John Polstra <jdp@polstra.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH]
Date: Tue, 11 Jan 2000 14:29:55 -0500 (EST)

 Ok, given that the nsec granularity isn't available, would a work-around
 like this be more appropriate?
 
 Daniel
 
 Index: edit.c
 ===================================================================
 RCS file: /src/cvs/src/usr.bin/chpass/edit.c,v
 retrieving revision 1.16
 diff -r1.16 edit.c
 41a42
 > #include <sys/time.h>
 67a69
 > 	struct timeval temp_time[2];
 69a72,81
 > 		/*
 > 		 * Avoid race condition when user edits file in under a 
 > 		 * second by back-dating file.
 > 		 */
 > 		gettimeofday(&(temp_time[0]), NULL);
 > 		gettimeofday(&(temp_time[1]), NULL);
 > 		temp_time[1].tv_sec--;
 > 		if (utimes(tempname, temp_time))
 > 			pw_error(tempname, 1, 1);
 > 
 
 -- 
 Daniel Hagan                                             Computer Science CSE
 dhagan@cs.vt.edu                                http://www.cs.vt.edu/~dhagan/
 
 

From: John Polstra <jdp@polstra.com>
To: Daniel Hagan <dhagan@cs.vt.edu>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH]
Date: Tue, 11 Jan 2000 18:53:37 -0800 (PST)

 Daniel Hagan wrote:
 > Ok, given that the nsec granularity isn't available, would a work-around
 > like this be more appropriate?
 
 BTW, a context diff would have been nice. :-)
 
 > 
 > Daniel
 > 
 > Index: edit.c
 > ===================================================================
 > RCS file: /src/cvs/src/usr.bin/chpass/edit.c,v
 > retrieving revision 1.16
 > diff -r1.16 edit.c
 > 41a42
 >> #include <sys/time.h>
 > 67a69
 >>      struct timeval temp_time[2];
 > 69a72,81
 >>              /*
 >>               * Avoid race condition when user edits file in under a 
 >>               * second by back-dating file.
 >>               */
 >>              gettimeofday(&(temp_time[0]), NULL);
 >>              gettimeofday(&(temp_time[1]), NULL);
 >>              temp_time[1].tv_sec--;
 >>              if (utimes(tempname, temp_time))
 >>                      pw_error(tempname, 1, 1);
 >> 
 
 I can't decide whether you should be ridiculed mercilessly for this
 disgusting hack, or hailed as a genuine genius. :-) I would rule
 it out in an instant, except that the file's only a temporary file
 anyway.  I guess it's OK, but don't tell anybody I said so.
 
 Minor style nit: you should remove the redundant parentheses in the
 gettimeofday() calls.
 
               gettimeofday(&temp_time[0], NULL);
               gettimeofday(&temp_time[1], NULL);
 
 If you don't do it, Bruce will.
 
 John
 

From: Daniel Hagan <dhagan@cs.vt.edu>
To: John Polstra <jdp@polstra.com>
Cc: freebsd-gnats-submit@freebsd.org, jhb@freebsd.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH]
Date: Wed, 12 Jan 2000 08:45:03 -0500 (EST)

 On Tue, 11 Jan 2000, John Polstra wrote:
 
 > I can't decide whether you should be ridiculed mercilessly for this
 > disgusting hack, or hailed as a genuine genius. :-) I would rule
 > it out in an instant, except that the file's only a temporary file
 > anyway.  I guess it's OK, but don't tell anybody I said so.
 
 I would vote for the disgusting hack category myself :).  I was
 complaining to John Baldwin (jhb) about it, and he mentioned the
 work-around (I never would have thought of it, being too tied to my
 anti-disgusting-hack philosophy).  It seems harmless enough in this
 special case, but I won't take it personally if someone cans the patch.
 
 > Minor style nit: you should remove the redundant parentheses in the
 > gettimeofday() calls.
 
 Ok, taken care of.  Here's the updated diff (in context diff format even
 ;-))
 
 Index: edit.c
 ===================================================================
 RCS file: /src/cvs/src/usr.bin/chpass/edit.c,v
 retrieving revision 1.16
 diff -c -r1.16 edit.c
 *** edit.c	1999/12/21 19:30:09	1.16
 --- edit.c	2000/01/12 13:31:30
 ***************
 *** 39,44 ****
 --- 39,45 ----
   
   #include <sys/param.h>
   #include <sys/stat.h>
 + #include <sys/time.h>
   
   #include <ctype.h>
   #include <err.h>
 ***************
 *** 65,72 ****
 --- 66,84 ----
   	struct passwd *pw;
   {
   	struct stat begin, end;
 + 	struct timeval temp_time[2];
   
   	for (;;) {
 + 		/*
 + 		 * Avoid race condition when user edits file in under a 
 + 		 * second by back-dating file.
 + 		 */
 + 		gettimeofday(&temp_time[0], NULL);
 + 		gettimeofday(&temp_time[1], NULL);
 + 		temp_time[1].tv_sec--;
 + 		if (utimes(tempname, temp_time))
 + 			pw_error(tempname, 1, 1);
 + 
   		if (stat(tempname, &begin))
   			pw_error(tempname, 1, 1);
   		pw_edit(1);
 
 -- 
 Daniel Hagan                                             Computer Science CSE
 dhagan@cs.vt.edu                                http://www.cs.vt.edu/~dhagan/
 
 

From: Peter Wemm <peter@netplex.com.au>
To: Daniel Hagan <dhagan@cs.vt.edu>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH] 
Date: Wed, 12 Jan 2000 21:57:28 +0800

 Daniel Hagan wrote:
 [..]
 >  I would vote for the disgusting hack category myself :).  I was
 >  complaining to John Baldwin (jhb) about it, and he mentioned the
 >  work-around (I never would have thought of it, being too tied to my
 >  anti-disgusting-hack philosophy).  It seems harmless enough in this
 >  special case, but I won't take it personally if someone cans the patch.
 
 Just as a by-the-way, this won't work on a system with a raised securelevel
 which will prevent the time being set backwards.  So don't make it a fatal
 error if the time cannot be set.  Or, if it fails to set back, sleep for a
 second instead...  Or even do a while loop waiting for the current time to
 tick over to the next second and be later than the time on the file (again
 using usleep or something for a 1/10th of a second sleep interval).
 
 The sure-fire way to detect an edit is to do a md5 of the file.  There's
 quite a few examples of code to do this sort of thing around the tree (ie:
 taking the md5 checksum).  Then compare a before-and-after checksum.
 
 Cheers,
 -Peter
 
 

From: Daniel Hagan <dhagan@cs.vt.edu>
To: Peter Wemm <peter@netplex.com.au>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH] 
Date: Wed, 12 Jan 2000 09:26:11 -0500 (EST)

 On Wed, 12 Jan 2000, Peter Wemm wrote:
 
 > Just as a by-the-way, this won't work on a system with a raised securelevel
 > which will prevent the time being set backwards.  So don't make it a fatal
 > error if the time cannot be set.  Or, if it fails to set back, sleep for a
 > second instead...  Or even do a while loop waiting for the current time to
 > tick over to the next second and be later than the time on the file (again
 > using usleep or something for a 1/10th of a second sleep interval).
 > 
 > The sure-fire way to detect an edit is to do a md5 of the file.  There's
 > quite a few examples of code to do this sort of thing around the tree (ie:
 > taking the md5 checksum).  Then compare a before-and-after checksum.
 
 I have no problem writing the code to do a md5 sum.  I didn't realize the
 effects of secure-levels here, so it probably makes sense to move to the
 checksum method.  I'll try to do a rewrite over the next couple of days.
 
 Daniel
 
 -- 
 Daniel Hagan                                             Computer Science CSE
 dhagan@cs.vt.edu                                http://www.cs.vt.edu/~dhagan/
 
 

From: Bruce Evans <bde@zeta.org.au>
To: Peter Wemm <peter@netplex.com.au>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH] 
Date: Thu, 13 Jan 2000 02:16:11 +1100 (EST)

 On Wed, 12 Jan 2000, Peter Wemm wrote:
 
 >  Just as a by-the-way, this won't work on a system with a raised securelevel
 >  which will prevent the time being set backwards.  So don't make it a fatal
 
 Erm, it only changes file times.  The inode change time (which can't be
 backdated) is probably adequate for detecting intrusive backdating of files.
 
 Bruce
 
 

From: Daniel Hagan <dhagan@cs.vt.edu>
To: John Polstra <jdp@polstra.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/4238 - chpass time delay sensitivity [PATCH]
Date: Wed, 12 Jan 2000 10:56:56 -0500 (EST)

 Updated to use MD5 hashes to detect changes.
 
 -Daniel
 
 Index: Makefile
 ===================================================================
 RCS file: /src/cvs/src/usr.bin/chpass/Makefile,v
 retrieving revision 1.20
 diff -c -r1.20 Makefile
 *** Makefile	1999/12/18 13:55:13	1.20
 --- Makefile	2000/01/12 14:31:27
 ***************
 *** 27,34 ****
   #Some people need this, uncomment to activate
   #COPTS+= -DRESTRICT_FULLNAME_CHANGE
   
 ! DPADD=	${LIBRPCSVC} ${LIBCRYPT}
 ! LDADD+=	-lrpcsvc -lcrypt
   
   CLEANFILES= ${GENSRCS}
   
 --- 27,34 ----
   #Some people need this, uncomment to activate
   #COPTS+= -DRESTRICT_FULLNAME_CHANGE
   
 ! DPADD=	${LIBRPCSVC} ${LIBCRYPT} ${LIBMD}
 ! LDADD+=	-lrpcsvc -lcrypt -lmd
   
   CLEANFILES= ${GENSRCS}
   
 Index: edit.c
 ===================================================================
 RCS file: /src/cvs/src/usr.bin/chpass/edit.c,v
 retrieving revision 1.16
 diff -c -r1.16 edit.c
 *** edit.c	1999/12/21 19:30:09	1.16
 --- edit.c	2000/01/12 14:36:31
 ***************
 *** 39,48 ****
 --- 39,50 ----
   
   #include <sys/param.h>
   #include <sys/stat.h>
 + #include <sys/types.h>
   
   #include <ctype.h>
   #include <err.h>
   #include <errno.h>
 + #include <md5.h>
   #include <paths.h>
   #include <pwd.h>
   #include <stdio.h>
 ***************
 *** 65,81 ****
   	struct passwd *pw;
   {
   	struct stat begin, end;
   
   	for (;;) {
   		if (stat(tempname, &begin))
   			pw_error(tempname, 1, 1);
   		pw_edit(1);
   		if (stat(tempname, &end))
   			pw_error(tempname, 1, 1);
 ! 		if (begin.st_mtime == end.st_mtime) {
   			warnx("no changes made");
   			pw_error(NULL, 0, 0);
   		}
   		if (verify(pw))
   			break;
   		pw_prompt();
 --- 67,89 ----
   	struct passwd *pw;
   {
   	struct stat begin, end;
 + 	char *begin_sum, *end_sum;
   
   	for (;;) {
   		if (stat(tempname, &begin))
   			pw_error(tempname, 1, 1);
 + 		begin_sum = MD5File(tempname, (char *)NULL);
   		pw_edit(1);
   		if (stat(tempname, &end))
   			pw_error(tempname, 1, 1);
 ! 		end_sum = MD5File(tempname, (char *)NULL);
 ! 		if ((begin.st_mtime == end.st_mtime) &&
 ! 		    (strcmp(begin_sum, end_sum) == 0)) {
   			warnx("no changes made");
   			pw_error(NULL, 0, 0);
   		}
 + 		free(begin_sum);
 + 		free(end_sum);
   		if (verify(pw))
   			break;
   		pw_prompt();
 
 
 -- 
 Daniel Hagan                                             Computer Science CSE
 dhagan@cs.vt.edu                                http://www.cs.vt.edu/~dhagan/
 
 

From: Daniel Hagan <dhagan@cs.vt.edu>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/4238: chpass only occasionally works in conjunction with ed
Date: Wed, 05 Apr 2000 21:13:56 -0400

 Is this patch just suffering shelf rot, or has someone found a problem with
 it?
 
 http://www.freebsd.org/cgi/query-pr.cgi?pr=4238
 
 Daniel
 
 
Responsible-Changed-From-To: freebsd-bugs->sheldonh 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Thu Apr 6 13:50:21 PDT 2000 
Responsible-Changed-Why:  
I'll take this one. 

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/4238: chpass only occasionally works in conjunction with ed
Date: Tue, 11 Apr 2000 11:25:48 +0200

 I want to test this through a ``make world'' before I commit it, but the
 change looks good.
 
 By the way <sys/types.h> was not required, since we already include
 <sys/param.h> -- see style(9) for an explanation.
 
 Ciao,
 Sheldon.
 
State-Changed-From-To: open->analyzed 
State-Changed-By: sheldonh 
State-Changed-When: Wed Apr 12 01:50:56 PDT 2000 
State-Changed-Why:  
Committed in rev 1.21 of Makefile and rev 1.17 of edit.c, thanks! 
Since this isn't a critical bug fix, we'll give it a while in 
5.0-CURRENT before merging it onto the RELENG_4 and RELENG_3 
branches.  Bug me if I haven't done it in a month. :-) 
Responsible-Changed-From-To: sheldonh->davidn 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Tue Jun 27 01:40:59 PDT 2000 
Responsible-Changed-Why:  
David is interested in password-related code. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4238 
State-Changed-From-To: analyzed->closed 
State-Changed-By: davidn 
State-Changed-When: Wed Jun 28 10:31:09 EST 2000 
State-Changed-Why:  
Fix committed in -current is now merged into all active branches. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4238 
>Unformatted:
