radagast has asked for the wisdom of the Perl Monks concerning the following question:
I'm trying to set up a CGI script to allow users to change their account passwords via a web interface. As root, I would normally type passwd <user> and be prompted to enter and reenter the passwords. As there are no flags to pass on the commandline which will accept the password from there, such as adduser has, eliminating any interaction, I am resigned to the fact that I have to do some sort of interprocess communication.
The Programming Perl book in Chapter 6 mentions Comm.pl as a possible package to use to manage that interaction automatically but I can't seem to find it on CPAN where it suggests. Any suggestions where I can find it or another suitable package? I have decided, for safety and sanity, to not do any file editing on my master.passwd file, and have opted instead to use the system utilities. Any help would be appreciated.
Radagast
Re: Interprocess Communication
by splinky (Hermit) on Jul 04, 2000 at 16:06 UTC
|
Expect.pm is what you want. It supersedes comm.pl.
*Woof* | [reply] |
Re: Interprocess Communication
by ahunter (Monk) on Jul 04, 2000 at 18:59 UTC
|
I have no experience with Expect.pm, so maybe that is
what you want, but if not, or you want to stick with
modules that are part of the standard distribution,
IPC::Open2 and IPC::Open3 give you the ability to open
pipes both to and from a child process. Something like
(untested):
use IPC::Open2;
local (*RD, *WR);
my $child = open2(\*RD, \*WR, 'passwd');
# RD and WR are now pipes connected to STDOUT/STDERR and
# STDIN respectively of the child process. $child contains
# the PID.
my $prompt = <RD>; # not caring what the prompt is, here
print WR "password\n";
$prompt = <WR> # prompted again
print WR "password\n";
Though, to make the code robust, you will want to check the prompts, and probably deal with SIGCHLD yourself so you can get return conditions and so on. You should also set an alarm to time out if something blocks unexpectedly.
Andrew. | [reply] [d/l] |
Re: Interprocess Communication
by httptech (Chaplain) on Jul 04, 2000 at 19:59 UTC
|
I don't know if you realize are re-inventing the wheel here,
but if you don't want to do that you can check Freshmeat
for a few different implementations of this. One that I know
of, written in Perl, is CPM Cyberlot Password Manager
Even if you don't use it, reading the source code may be helpful
to determine the best approach to the problem.
| [reply] |
Re: Interprocess Communication
by c-era (Curate) on Jul 05, 2000 at 14:59 UTC
|
Here's how to use Comm.pl,
require "Comm.pl"
&Comm'init(1.8);
&set_traps;
$program=&open_proc("some program");
($success, $matched, $before_match, $after_match ) = &expect ( $progra
+m, 10(time out in sec), 'what you are expecting');
die "Time out\n" unless ($success);
print $program "What you want to send to the program\n";
I don't have time to test it, but if it doesn't work let me know and I will fix it. | [reply] [d/l] |
RE: Interprocess Communication
by TQuid (Sexton) on Jul 04, 2000 at 19:59 UTC
|
Actually, if you really want to avoid IPC for this, you could just edit (hey, wordwrap! Thanks!) your /etc/master.passwd (or /etc/passwd, shame on you for not shadowing) file directly with Perl, and issue a mkpwdb command once you're finished.
Of course, it's pretty important to use file-locking so that your program doesn't step on others' (or its own!) toes.
If I ever finish the program that does what you are talking about (as well as much more), I will post some code here. Pray it doesn't kill me first.
--TQuid | [reply] |
|
I believe master.passwd is the BSD equivalent of /etc/shadow,
where /etc/passwd is the world readable file, and /etc/master.passwd
is the root-readable-only file with the crypted passwords in
it. For the same reason, he may not have mkpwdb either (I don't
find it on my Linux box or BSDi boxes)
| [reply] |
Re: Interprocess Communication
by jdawg (Novice) on Jul 05, 2000 at 17:06 UTC
|
My shop uses a web interface to change user passwords on our ftp server (solaris 7). We use a perl program running suid root in the background to process work orders that are created by the web interface script. Just have the web interface write username and encrypted password to a file in a certian directory, and have the background process check that directory every few minutes. The bg process uses a temp file and careful file locking to make changes to /etc/shadow. If anyone has questions on the details, post back here and I'll do my best to answer them. | [reply] |
Re: Interprocess Communication
by extremely (Priest) on Jul 04, 2000 at 21:43 UTC
|
Are you on a redhat machine or related distribution?
Take a look at `man usermod` and see if it helps. Suse
has it too, at the very least.
--
mark | [reply] |
|
|