diff options
Diffstat (limited to 'fs_passwd')
-rwxr-xr-x | fs_passwd/fs_passwd | 2 | ||||
-rwxr-xr-x | fs_passwd/fs_passwd.cgi | 57 | ||||
-rw-r--r-- | fs_passwd/fs_passwd.html | 25 | ||||
-rwxr-xr-x | fs_passwd/fs_passwd_server | 31 | ||||
-rwxr-xr-x | fs_passwd/fs_passwdd | 17 |
5 files changed, 121 insertions, 11 deletions
diff --git a/fs_passwd/fs_passwd b/fs_passwd/fs_passwd index bcf09f1fe..0b467aefc 100755 --- a/fs_passwd/fs_passwd +++ b/fs_passwd/fs_passwd @@ -20,7 +20,7 @@ use vars qw($opt_f $opt_s); my($fs_passwdd_socket)="/usr/local/freeside/fs_passwdd_socket"; my($freeside_uid)=scalar(getpwnam('freeside')); -$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; +$ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin'; $ENV{'SHELL'} = '/bin/sh'; $ENV{'IFS'} = " \t\n"; $ENV{'CDPATH'} = ''; diff --git a/fs_passwd/fs_passwd.cgi b/fs_passwd/fs_passwd.cgi new file mode 100755 index 000000000..3f676fff3 --- /dev/null +++ b/fs_passwd/fs_passwd.cgi @@ -0,0 +1,57 @@ +#!/usr/bin/perl -Tw + +use strict; +use Getopt::Std; +use Socket; +use IO::Handle; +use CGI; +use CGI::Carp qw(fatalsToBrowser); + +my $fs_passwdd_socket = "/usr/local/freeside/fs_passwdd_socket"; +my $freeside_uid = scalar(getpwnam('freeside')); + +$ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin'; +$ENV{'SHELL'} = '/bin/sh'; +$ENV{'IFS'} = " \t\n"; +$ENV{'CDPATH'} = ''; +$ENV{'ENV'} = ''; +$ENV{'BASH_ENV'} = ''; + +die "fs_passwd.cgi isn't running as freeside user\n" if $> != $freeside_uid; + +my $cgi = new CGI; + +$cgi->param('username') =~ /^([^\n]{0,255}$)/ or die "Illegal username"; +my $me = $1; + +$cgi->param('old_password') =~ /^([^\n]{0,255}$)/ or die "Illegal old_password"; +my $old_password = $1; + +$cgi->param('new_password') =~ /^([^\n]{0,255}$)/ or die "Illegal new_password"; +my $new_password = $1; + +die "New passwords don't match" + unless $new_password eq $cgi->param('new_password2'); + +socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!"; +connect(SOCK, sockaddr_un($fs_passwdd_socket)) or die "connect: $!"; +print SOCK join("\n", $me, $old_password, $new_password, '', ''), "\n"; +SOCK->flush; +my $error = <SOCK>; +chomp $error; + +if ($error) { + die $error; +} else { + print $cgi->header(), <<END; +<html> + <head> + <title>Password changed</title> + </head> + <body bgcolor="#e8e8e8"> + <h3>Password changed</h3> +<br>Your password has been changed. + </body> +</html> +END +} diff --git a/fs_passwd/fs_passwd.html b/fs_passwd/fs_passwd.html new file mode 100644 index 000000000..fadc4df8b --- /dev/null +++ b/fs_passwd/fs_passwd.html @@ -0,0 +1,25 @@ +<html> + <head> + <title>Change password</title> + </head> + <body bgcolor="#e8e8e8"> + <h3>Change password</h3> + <form action="/cgi-bin/fs_passwd.cgi" method="post"> + <table bgcolor="#cccccc" border=0 cellspacing=2> + <tr><th align="right">Username</th> + <td><input type="text" name="username" size="18"></td> + </tr> + <tr><th align="right">Current password</th> + <td><input type="password" name="old_password" size="18"></td> + </tr> + <tr><th align="right">New password</th> + <td><input type="password" name="new_password" size="18"></td> + </tr> + <tr><th align="right">Re-enter new password</th> + <td><input type="password" name="new_password2" size="18"></td> + </tr> + </table> + <br><input type="submit" value="Change password"> + </body> +</html> + diff --git a/fs_passwd/fs_passwd_server b/fs_passwd/fs_passwd_server index 99e7c4351..a29b2c738 100755 --- a/fs_passwd/fs_passwd_server +++ b/fs_passwd/fs_passwd_server @@ -11,25 +11,36 @@ # crypt-aware, s/password/_password/; ivan@sisd.com 98-aug-23 use strict; +use vars qw($pid); +use subs qw(killssh); use IO::Handle; -use FS::SSH qw(sshopen2); +use Net::SSH qw(sshopen2); use FS::UID qw(adminsuidsetup); use FS::Record qw(qsearchs); use FS::svc_acct; -$SIG{CHLD} = sub { wait() }; +my $user = shift or die &usage; +adminsuidsetup $user; -&adminsuidsetup; +my($shellmachine)=shift or die &usage; -my($fs_passwdd)="/usr/local/sbin/fs_passwdd"; +#causing trouble for some folks +#$SIG{CHLD} = sub { wait() }; + +$SIG{HUP} = \&killssh; +$SIG{INT} = \&killssh; +$SIG{QUIT} = \&killssh; +$SIG{TERM} = \&killssh; +$SIG{PIPE} = \&killssh; + +sub killssh { kill 'TERM', $pid if $pid; exit; }; -my($shellmachine)=shift; -die "Usage: fs_passwd_server shellmachine\n" unless $shellmachine; +my($fs_passwdd)="/usr/local/sbin/fs_passwdd"; while (1) { my($reader,$writer)=(new IO::Handle, new IO::Handle); $writer->autoflush(1); - sshopen2($shellmachine,$reader,$writer,$fs_passwdd); + $pid = sshopen2($shellmachine,$reader,$writer,$fs_passwdd); while (1) { my($username,$old_password,$new_password,$new_gecos,$new_shell); defined($username=<$reader>) or last; @@ -57,7 +68,7 @@ while (1) { unless ( $svc_acct ) { print $writer "Incorrect password.\n"; next; } my(%hash)=$svc_acct->hash; - my($new_svc_acct) = create FS::svc_acct ( \%hash ); + my($new_svc_acct) = new FS::svc_acct ( \%hash ); $new_svc_acct->setfield('_password',$new_password) if $new_password && $new_password ne $old_password; $new_svc_acct->setfield('finger',$new_gecos) if $new_gecos; @@ -71,3 +82,7 @@ while (1) { warn "Connection to $shellmachine lost! Reconnecting...\n"; } +sub usage { + die "Usage:\n\n fs_passwd_server user shellmachine\n"; +} + diff --git a/fs_passwd/fs_passwdd b/fs_passwd/fs_passwdd index 582e13ccd..cce98e787 100755 --- a/fs_passwd/fs_passwdd +++ b/fs_passwd/fs_passwdd @@ -9,9 +9,10 @@ use strict; use Socket; -my($fs_passwdd_socket)="/usr/local/freeside/fs_passwdd_socket"; +my $fs_passwdd_socket = "/usr/local/freeside/fs_passwdd_socket"; +my $pid_file = "$fs_passwdd_socket.pid"; -$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; +$ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin'; $ENV{'SHELL'} = '/bin/sh'; $ENV{'IFS'} = " \t\n"; $ENV{'CDPATH'} = ''; @@ -28,6 +29,18 @@ unlink($fs_passwdd_socket); bind(Server, $uaddr) or die "bind: $!"; listen(Server,SOMAXCONN) or die "listen: $!"; +if ( -e $pid_file ) { + open(PIDFILE,"<$pid_file"); + #chomp( my $old_pid = <PIDFILE> ); + my $old_pid = <PIDFILE>; + close PIDFILE; + $old_pid =~ /^(\d+)$/; + kill 'TERM', $1; +} +open(PIDFILE,">$pid_file"); +print PIDFILE "$$\n"; +close PIDFILE; + my($paddr); for ( ; $paddr = accept(Client,Server); close Client) { my($me,$old_password,$new_password,$new_gecos,$new_shell); |