#auth.pl version 1.3 #global variables: #$uid= userid of logged in user #param('pass1')= new password #param('pass2')= verification of new password #param('authuser') = id of user to change password for (if $uid is manager) #$ismanager=set to true if logged in user is Cyrus imap manager uid #required functions for a generic auth.pl # &auth_changepass - returns 0 for success # &auth_getuserserver - returns a server name or 0; use Net::LDAP; use Net::LDAP::Util qw(ldap_error_text); my $dn; sub auth_disconnect { $ld->unbind if $ld; undef ($ld); } sub auth_getdn { my ($ld,$uid)=@_; # Since we've entered our UID, not our CN, we must first find the DN of a # person who matches the UID in $ldap_bind_uid @attrs = (); $filter = "(uid=$uid)"; $result=$ld->search(base=>$LDAP_BASEDN,scope=>"sub",filter=>$filter,attrs=>\@attrs); if ($result->code) { $ld->unbind; return -1; } # Obtain a pointer to the first entry matching our query. We are making the # assumption that since UID means Unique ID that this is the only time we # need to do this. @entries=$result->entries; $ent=$entries[0]; if ($ent ) { # We only need the DN from the entry we matched. $dn = $ent->dn; my $user=$ent->get_value('uid'); if ($uid ne $user) { $ld->unbind; return -1; #Failure } return $dn; } return 0; } sub auth_connect { my ($uid,$pass)=@_; # First initialize our connection to the LDAP Server and bind anonymously. $ld = Net::LDAP->new($LDAP_SERVER) or die "$@"; $mesg=$ld->bind; if ($mesg->code) { print "Error: Unable to Bind Anonymously to the Directory.",p; print "bind_s: " . ldap_error_text($mesg->code) . "\n"; $ld->unbind; return -1; } $dn=&auth_getdn($ld,$uid); return -1 if !$dn; #Failure # Attempt to bind with the DN and Password supplied previously. $mesg=$ld->bind($dn,password=>$pass); if ($mesg->code) { $ld->unbind; print "Error binding to $dn!!!"; return -1; # Return Failure } return $ld; # Return Success } sub auth_getuserserver { $mailhostatt='mailroutingaddress' if !$mailhostatt; # Get the mail server address for imap my $err=&auth_connect($uid,$pass); if ($err<0) { $err=''; &auth_disconnect; return -1 ; } $err=''; my (@mra)=$ent->get_value($mailhostatt); if ($mra[0]) { $imapserver=$mra[0]; } if ($imapserver) { &auth_disconnect; return $imapserver; } else { &auth_disconnect; return ''; } } sub encrypt { my ($pass1)=@_; $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; # Seeding with time and proccess id is not normally recommended, but we're # only generating the salt, not the password. srand( time() ^ ($$ + ($$ << 15)) ); $salt = ""; for ($i = 0; $i <2; $i++) { $saltno = int rand length($chars); $mychar = substr($chars,$saltno,1); $salt = $salt . $mychar; } $pass1 = "{CRYPT}".crypt $pass1, $salt; return $pass1; } sub auth_changepass { # Lets Check the Password... If non-empty, encrypt and add to %ldapmod my $err; my $pass1 = param("pass1"); my $pass2 = param("pass2"); my $authuser = param('authuser'); param('pass1',''); param('pass2',''); param('authuser',''); if (!$pass1 && !$pass2) {return 0;} if ($pass1 eq "" || $pass2 eq "") { return 0; } else { if ($pass1 eq $pass2) { # Encrypt as necessary... if ($ENCRYPT_PASS == 1) { $pass1=&encrypt($pass1); } $ldapmod{'userPassword'} = $pass1; print "
Warning: You must login with your new password by clicking HERE\n
" if !$authuser; } else { print "Warning: Passwords Did Not Match...Not Changed...\n
"; return 1; } } # Perform a synchronous MODIFY operation on our $dn @change_keys = keys %ldapmod; if ($#change_keys >= 0) { if (($ld=&auth_connect($uid,$pass))<0) { print "Password change: Unable to bind to Ldap server...\n",p; print "Ldap error: ".ldap_error_text($mesg->code) . "\n"; exit; } if ($authuser) { $dn=&auth_getdn($ld,$authuser); if (!$dn) { $err= "Password change: $authuser does not exist in directory$err
"; return 1 ; } } sub auth_saveattrib { my ($att,$val)=@_; $ldapmod{$att}=$val; my $ld=&auth_connect($uid,$pass); my $dn=&auth_getdn($ld,$uid); my $res=&auth_changeatt($ld,$dn,$att,$val); return $res; } sub auth_getattrib { my ($att)=@_; my $ld=&auth_connect($uid,$pass); my $dn=&auth_getdn($ld,$uid); my $val=&auth_getatt($ld,$dn,$att); return $val; } sub auth_changeatt { my ($ld,$dn,$att,$val)=@_; $ldapmod{$att}=$val; $result=$ld->modify($dn,replace=>{%ldapmod}); if ($result->code) { print "Ldap Error: ".ldap_error_text($result->code) . "\n"; } return $result-code; } sub auth_getatt { my ($ld,$dn,$att)=@_; my $result=$ld->search(base=>$dn,filter=>"(objectclass=*)"); if ($result->code) { return; } my @ent=$result->entries; my @val=$ent[0]->get_value($att); return $val[0]; } 1;