Part 3: The SubRoutines
Now for the tools. There's a lot here, but in further articles you will see how this can be useful. I'll go through each tool with what it does, how to call it, and then the code itself.
NOTE: This uses the foundations in parts 1 and 2. You can find them here: Part 1 Part 2
Simple Anonymous Bind
Use this if you are only doing read operations. This will only work if your LDAP server allows anonymous reads.
&ldapBindAnon;
sub bindLdapAnon{
$base= "$defaultBase";
$ldap = Net::LDAP->new ( "$secondaryLdap" ) or die "$@";
$ssl = new IO::Socket::SSL("$secondaryLdap:636");
$mesg=$ldap->start_tls(verify => 'none',
cafile => $caFile,
ciphers=> 'AES256-SHA');
$ldap->bind;
}
Authenticated Bind
Use for write operations
my $bindResult = &bindLdapAuth($username,$password)
sub bindLdapAuth{
my ($user,$passwd) = @_;
my $dn;
if ( $user =~/^$/ ){
$dn = "cn=Manager,$defaultBase";
}elsif ($user =~/Manager/){
$dn = "cn=Manager,$defaultBase";
} else {
$dn = "uid=$user,$peopleBase";
}
$base= "$defaultBase";
$ldap = Net::LDAP->new ( "$primaryLdap" ) or die "$@";
$ssl = new IO::Socket::SSL("$primaryLdap:636");
$mesg=$ldap->start_tls(verify => 'none',
cafile => "$cafile",
ciphers=> 'AES256-SHA');
$mesg = $ldap->bind( "$dn",
password => $passwd,
version => 3);
my $code = $mesg->code;
return $code;
}
Unbind When you are done.
&unbindLdap;
sub unbindLdap{
$ldap->unbind;
}
Search LDAP
This is required by a lot of later operations. Typically I use this for searching for uids.
my $searchResult = &ldapSearch($searchString,$base,$attrs);
sub ldapSearch {
my ($searchString,$base,$attrs) = @_;
if (!$base ) { $base = "$peopleBase"; }
if (!$attrs ) { $attrs = [ 'uid','givenName' ]; }
my $result = $ldap->search ( base => "$base",
scope => "sub",
filter => "$searchString",
attrs => "$attrs"
);
}
Modifying an existing attribute for a user
my $modResult = &ldapModify($uid,$attribute,$value);
sub ldapModify {
my ($uid,$attribute,$value) = @_;
my $dn = "uid=$uid,$peopleBase";
my $resultmod = $ldap->modify( $dn,
changes => [
replace => [$attribute => $value]
]
);
my $code = $resultmod->code;
return $code;
}
Add an attribute for a user
my $addResult = &ldapAdd($uid,$attribute,$value);
sub ldapAdd {
my ($uid,$attribute,$value) = @_;
my $dn = "uid=$uid,$peopleBase";
my $resultmod = $ldap->modify( $dn,
changes => [
add => [$attribute => $value]
]
);
my $code = $resultmod->code;
return $code;
}
Delete an attribute for a user
Requires that you know the value, have not looked into why. Use &ldapGetUserAttribute to get the value first.
my $deleteResult = &ldapDelete($uid,$attribute,$value);
sub ldapDelete {
my ($uid,$attribute,$value) = @_;
my $dn = "uid=$uid,$peopleBase";
my $resultmod = $ldap->modify( $dn,
changes => [
delete => [$attribute => $value]
]
);
my $code = $resultmod->code;
return $code;
}
Retrieve one attribute
my $attributeValue = &getUserAttribute($uid,$attribute);
sub getUserAttribute{
my ($uid,$attribute) = @_;
my $resultsearch = ldapSearch ("uid=$uid",$base,$attribute);
my @entries = $resultsearch->entries;
my $entr;
my $value;
foreach $entr (@entries){
my $dn = $entr->dn;
my $attr;
foreach $attr (sort $entr->attributes){
if ($attr =~ /^$attribute$/) {
$value = $entr->get_value($attr);
}
}
}
return $value;
}
Get a full User List
my @users = &getUserList;
sub getUserList{
my $base = "$peopleBase";
my @Attrs=("uid","givenName","sambaPwdMustChange");
my $resultsearch = ldapSearch ("uid=*",$base,@Attrs);
my @entries = $resultsearch->entries;
my $entr;
my @users;
foreach $entr (@entries){
my $dn = $entr->dn;
my $uid = $entr->get_value('uid');
push (@users,$uid);
}
return @users;
}
Get Full Group List
my @groupList = &getGroupList;
sub getGroupList{
my $base = "$groupBase";
my @Attrs=("cn");
my $resultsearch = ldapSearch ("cn=*",$base,@Attrs);
my @entries = $resultsearch->entries;
my $entr;
my @groups;
foreach $entr (@entries){
my $dn = $entr->dn;
my $cn = $entr->get_value('cn');
push (@groups,$cn);
}
return @groups;
}
Get Members of a Group
my @groupMembers = &getGroupMembers($group);
sub getGroupMembers{
my ($group) = @_;
my @Attrs=("cn","memberUid");
my $resultsearchGroups = ldapSearch ("cn=$group",$base,@Attrs);
my @groupEntries = $resultsearchGroups->entries;
my $entr;
my @group;
foreach $entr ( @groupEntries ) {
my $dn = $entr->dn;
my $attr;
foreach $attr ( sort $entr->attributes ) {
if ($attr =~ /memberUid/){
my $member;
foreach $member ($entr->get_value ($attr)){
push (@group,$member);
}
}
}
}
return @group;
}
Get membership for a group
my @groupMembership = &getGroupMembership($uid);
sub getGroupMembership{
my ($uid) = @_;
my @Attrs=("cn","memberUid");
my $resultSearchGroups = &ldapSearch("cn=*",$groupBase,@Attrs);
my @entries = $resultSearchGroups->entries;
my $entr;
my @groups;
foreach $entr (@entries){
my $attr;
my $cn;
foreach $attr (sort $entr->attributes ) {
if ($attr =~ /cn/) {
$cn = $entr->get_value($attr);
}
if ($attr =~ /memberUid/) {
my @members = $entr->get_value ( $attr);
my $member;
foreach $member (@members){
if ($member eq $uid){
push (@groups,$cn);
}
}
}
}
}
return @groups;
}
Take a difference of UNIX time and make it human readable
I use this when calculating expiring accounts...
&diffTime($unixTimeToDiff)
sub diffTime{
(my ($timeToDiff)) = @_;
my $now = time;
my $diff = $timeToDiff - $now;
my $days = int($diff / 86400);
my $hours = int($diff / 3600);
my $minutes = int($diff /60);
if ($days == 0){
if ($hours == 0){
return "$minutes minutes";
}else{
return "$hours hours";
}
}else{
return "$days days";
}
}
Convert days to seconds
I use this when I am going to add days to unix time (for instance when I need to update an expiration time) This is just a shortcut for simple math. It adds a number of days, to the second, from right now.
my $newTime = &addDays($numberOfDaysToAdd);
sub addDays{
my ($daysToAdd) = @_;
return $daysToAdd * 86400 + time;
}
Send off an email
Shortcut to fire off an email.
&sendMailToUser($from,$to,$cc,$bcc,$subject,@message);
sub sendMailToUser{
my ($from,$to,$cc,$bcc,$subject,@message) = @_;
my $server = "$mailServer";
my %mail;
$mail{Smtp} = $server;
$mail{From} = $from;
$mail{To} = $to;
$mail{Cc} = "$cc";
$mail{Bcc} = $bcc;
$mail{Subject} = "$subject";
$mail{Message} = "@message";
sendmail %mail;
}
Generate a username from Frist Last
This will put a username into the format of firstInitalLastName (IE: Sean Hart turns into shart) Fairly standard username format. Will put up with apostrophes and spaces in lastname (IE: O'Hara and Von Drake)
my $username = &genUserName($firstName, $lastName
sub genUserName{
my ($firstName,$lastName) = @_;
my $holdFirstname = $firstName;
my $holdLastName = $lastName;
my $letters = length ($firstName);
while ($letters > 1) {
chop ($firstName);
$letters = length ($firstName);
}
my $firstInitialLc = lc $firstName;
my $lastNameLc = lc $lastName;
#remove all spaces from $lastName in case of prefixes etc
$lastNameLc =~ s/\s//g;
my $userName = "$firstInitialLc" . "$lastNameLc";
$userName =~ s/'//;
return $userName;
}
Check Password Complexity
Requires password have 3 of 4 character classes and be at least 8 characters long
my$complex = &checkPassComplexity($password);
sub checkPassComplexity{
my ($passToCheck) = @_;
my $complexPoints;
if ($passToCheck =~ /[A-Z]/){
$complexPoints += 1;
}
if ($passToCheck =~ /[a-z]/){
$complexPoints += 1; }
if ($passToCheck =~ /[0-9]/){
$complexPoints += 1;
}
if ($passToCheck =~ /\W/) {
$complexPoints += 1;
}
if (length($passToCheck)
$complexPoints = 0;
}
if ($passToCheck =~ /\s/){
$complexPoints = 0;
}
if ($complexPoints
return 1;
}else {
return 0;
}
}
Generate a random password of n characters
Defaults to 25 characters
my$randomPassword = &genRandomPassword($n);
sub genRandomPassword {
my $password;
my $_rand;
my $password_length = $_[0];
if (!$password_length) {
$password_length = 25;
}
my @chars = split(" ", "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m
n o p q r s t u v w x y z - _ % # | 0 1 2 3 4 5 6 7 8 9");
srand;
for (my $i=0; $i
$_rand = int(rand 67);
$password .= $chars[$_rand];
}
return $password;
}
Generate password hashes
Will give you an SHA, and LanMan and NT hashes (for use with samba + LDAP)
my @hashes = &genPasswordHashes($password);
my $shaHash = $hashes[0];
my $lanManHash = $hashes[1];
my $ntHash = $hashes[2];
sub genPasswdHashes{
my ($passwd) = @_;
my @return;
my $hashedPasswd = '{SHA}' . sha1_base64($passwd) . '=';
my $lm;
my $nt;
ntlmgen($passwd, $lm, $nt);
@return =("$hashedPasswd","$lm","$nt");
return @return;
}
Generate date for better sorting
Puts date into YYYYMMDD format for sorting
my $date=&genDate;
sub genDate{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $day = $mday;
$year += 1900;
$mon += 1;
if ($mon
$mon = "0" . "$mon";
}
if ($day
$day ="0" . "$day";
}
return "$year"."$mon"."$day";
}
Round up
Round a number up. Useful when rounding up dollars/cents etc.
sub roundup {
my $n = shift;
return(($n == int($n)) ? $n : int($n + 1))
}
Reading and writing files
Shortcut for reading and writing files
my $data = &read_file($path_to_file);
&write_file($path_to_file,@data);
sub read_file {
my ( $f ) = @_;
open (F, "
my @f =
close F;
return wantarray ? @f : \@f;
}
sub write_file {
my ( $f, @data ) = @_;
@data = () unless @data;
open F, "> $f" or die "Can't open $f : $!";
print F @data;
close F;
}
Print a webpage header
This simply does a lot of header information for cgi scripts, and sets a lot of things that really belong in css. As I was just whipping these out, and each script was on it's own subdomain css didn't make sense.
&printHeader;
sub printHeader{
my $title = $_[0];
my $cookie = $_[1];
if ($cookie =~ /^$/){
print header(-charset => "ISO10646") ,
}else{
print header(-charset => "ISO10646", -cookie => $cookie) ,
}
print start_html($title),
'
',
"
$title
",;
}
Print Login Form
&printLogin; ","
", ","
", ",
sub printLogin{
print start_form,
"
",
"
","Username:
",textfield('uid',,),"
"
","Password:
",password_field(-name=>'passwd',-override=>1),"
"
submit,end_form;
}
- shart's blog
- Log in to post comments
- 5849 reads