Subject: Re: batch passwd
To: None <netbsd-users@netbsd.org>
From: Steve Bellovin <smb@research.att.com>
List: netbsd-users
Date: 08/12/2001 18:26:39
In message <Pine.NEB.4.33.0108122215591.299-100000@wojtek.3miasto.net>, Wojciec
h Puchar writes:
>> >
>> > but it still inputs from console
>>
>> "passwd" reads from the tty, not standard input. Try
>>
>>   passwd &
>>   echo password\npassword >`tty`
>>
>> or some variation thereof.
>unfortunately doesn't work.
>
>i need such thing to make CGI program allowing user to change password
>(for those who can only click, and telnet/ssh is too difficult for them)
>
>
OK.  A quick glance at passwd.c shows that it calls local_passwd.c; a 
quick glance at it shows that getpass.c reads the actual passwords.
Here's the relevant source code:

        /*
         * read and write to /dev/tty if possible; else read from
         * stdin and write to stderr.
         */
        if ((outfp = fp = fopen(_PATH_TTY, "w+")) == NULL) {
                outfp = stderr;
                fp = stdin;
        }

A CGI script *probably* doesn't have a control tty, which means that it 
should be trying to write to, and read from, stderr.  (Note, of course, 
that to debug this you'll have to do it in the CGI environment.)  
A small C program to set up the file descriptor plumbing to a pipe
should do the trick.  You can't easily have the password read directly 
from a file, since getpass is going to open the file for output, thereby
truncating the file.

A different approach is to use makekey to produce the hashed password, 
and then use some script of your own as the editor passed to vipw.

Finally, the command that emulates a human typing on a tty is 'expect'.
There seem to be several variants in pkgsrc, with interfaces to Perl 
(that may be a Perl implementation of it), tcl, tk, and python.


		--Steve Bellovin, http://www.research.att.com/~smb