#!/usr/bin/perl -w # # $Id$ # # Simple CGI script to change your password, currently 'configured' # for dovecotpw, but could easy be ported to something else. # # License: BSDLike # Rick van der Zwet use CGI; $q = CGI->new; $MIN_PASSWD_LENGTH=8; $PASSWDFILE='/usr/local/etc/dovecot.passwd'; $DOVECOTPW='/usr/local/sbin/dovecotpw'; if (! -w $PASSWDFILE || ! -x $DOVECOTPW) { print $q->header(-status=>$error); print $q->start_html('Problems'); print $q->h2('Not able to open internals (database or binary)'); exit 1; }; # Message 'buffer', entries in here will be pushed on top of form @messages = (); # # Verify validity of CGI input sub check_cgi() { if ($q->request_method() eq "POST") { if (! ($q->param('username') && $q->param('old_password') && $q->param('new_password') && $q->param('verify_password'))) { push(@messages, "Not all fields are provided"); return 1; } if ($q->param('new_password') ne $q->param('verify_password')) { push(@messages, 'New passwords does not match'); return 1; } if ($q->param('new_password') eq $q->param('old_password')) { push(@messages, 'New password equal to old password not changing'); return 1; } if (length($q->param('new_password')) < $MIN_PASSWD_LENGTH) { push(@messages, "New password to short (minimal $MIN_PASSWD_LENGTH characters)"); return 1; } return 0; } return 1; } # # Process CGI, assuming all values are correct sub process_cgi_for_dovecotpw() { my $username = $q->param('username'); my $old_password = $q->param('old_password'); my $new_password = $q->param('new_password'); # XXX: Untested LOCK setup open(LOCK, '>> /tmp/changepw.lock'); flock LOCK, 2; my $password = `$DOVECOTPW -p $old_password`; open(FH, "<$PASSWDFILE"); my @users = ; close(FH); # Find all lines _NOT_ matching this entry my @lines = grep (!/^$username:$password/, @users); # If we still have the same amount of lines we did not remove anything if ((scalar(@lines) - scalar(@users)) == 0) { push(@messages, "Username or password invalid"); flock LOCK, 2; close(LOCK); return; } $password = `$DOVECOTPW -p $new_password`; push(@lines,"$username:$password"); open(FH, ">$PASSWDFILE"); print FH sort(@lines); close(FH); push(@messages, "Password changed"); flock LOCK, 2; close(LOCK); } # Only process if field are valid if (check_cgi() == 0) { process_cgi_for_dovecotpw(); } print $q->header; print $q->start_html('Change Email Password'); print $q->start_center(); if (@messages) { print $q->h2($q->ul({-style => 'list-style-type: none'}, $q->li(@messages))); }; print $q->start_form(); print $q->table($q->caption($q->h2('Please provide your values to change password')), $q->Tr([$q->td(['username', $q->textfield('username','somebody@example.org')])]), $q->Tr([$q->td(['old password', $q->password_field('old_password')])]), $q->Tr([$q->td(['new password', $q->password_field('new_password')])]), $q->Tr([$q->td(['verify new password', $q->password_field('verify_password')])]), $q->Tr([$q->td({-colspan=>2,-align=>'center'},[$q->submit('submit', 'Change Password')])]) ); print ''; print $q->end_form(); print $q->end_center(); print $q->end_html;