#!/opt/csw/bin/perl -w # Adds new object classes and attributes to # LDAP user records. # Copyright 2008 Netmojo Systems (http://www.netmojo.ca) # Mon Mar 31 16:10:25 MDT 2008 ### **** DISCLAIMER: Use of this script is entirely at your own risk. If ### you choose to use it, you assume full responsibility for any and all ### consequences. ### If you do not understand the code below, DO NOT USE IT!!! **** use strict; use Data::UUID; my $ug = new Data::UUID; # global variables my $search_filter = "(objectclass=posixAccount)"; my $search_base = "ou=People,o=MyORG"; my @required_objectclasses = ("top", "person", "organizationalPerson", "inetOrgPerson", "posixAccount", "shadowAccount", "apple-user", "extensibleObject"); # an array of hashes for attributes + data my %required_attributes = ("authAuthority", ";basic;", "apple-user-homedirectory", "/Network/Servers/mynfs.server.ca/home/", "displayName", "Test User", "givenName", "FirstName", "apple-generateduid", "UUID" ); # Start a Net::LDAP object use Net::LDAP; use Net::LDAP::Entry; my $ldap = Net::LDAP->new("localhost"); my $result = $ldap->bind("cn=Directory Manager", password => "mypassword"); die $result->error() if $result->code(); my $msg = $ldap->search( base => "$search_base", scope => "sub", filter => "$search_filter" ); # iterate through the LDAP entries my $count = 0; if ( $msg->count() >= 1 ) { foreach my $entry ( $msg->all_entries ) { my $dn = $entry->dn(); my $cn = $entry->get_value("cn") or die("No cn attribute for $dn!\n"); my $uid = $entry->get_value("uid") or die("No uid attribute for $dn!\n"); my $uidNumber = $entry->get_value("uidNumber") or die("No uidNumber attribute for $dn!\n"); print qq{### For $dn:\n\n}; my @classes = $entry->get_value("objectClass"); my @attributes = $entry->attributes; # debug #print "existing attributes: \n"; #foreach my $attrib(@attributes) #{ # print "\t$attrib\n"; #} my @needed_classes; foreach my $req (@required_objectclasses) { if( !in_array($req, @classes) ) { push(@needed_classes, $req); } } my $num_objects = @needed_classes; my %modhash; if( $num_objects > 0 ) { print qq{Needed objectclasses are:\n}; $modhash{objectclass} = [ @needed_classes ]; foreach my $need (@needed_classes) { print qq{\t$need\n}; # 'sn' is a required attribute of the person class if( $need eq "person" ) { my @fullname = split /\ /, $cn; $required_attributes{sn} = pop @fullname; } } } my @needed_attributes; while ((my $key, my $value) = each(%required_attributes)) { if( !in_array($key, @attributes) ) { push(@needed_attributes, $key); } } my $num_attribs = @needed_attributes; if ( $num_attribs > 0 ) { print "Needed attributes are:\n"; foreach my $need (@needed_attributes) { print qq{\t$need}; # append the username to the generic homedirectory path if( $need eq "apple-user-homedirectory" ) { print " => $required_attributes{$need}$uid\n"; $modhash{$need} = "$required_attributes{$need}$uid"; } elsif( $need eq "apple-generateduid" ) { my $ob = $ug->create_from_name("MyOrg", "$uidNumber"); my $uuid = $ug->to_string($ob); print " => $uuid\n"; $modhash{$need} = "$uuid"; } elsif( $need eq "displayName" ) { print " => $cn\n"; $modhash{$need} = "$cn"; } elsif( $need eq "givenName" ) { my @fullname = split /\ /, $cn; my $firstname = shift(@fullname); chomp($firstname); print " => $firstname\n"; $modhash{$need} = "$firstname"; } else { print " => $required_attributes{$need}\n"; $modhash{$need} = "$required_attributes{$need}"; } } } # debug #print "\n Modify hash for $dn:\n"; #print %modhash; #print "\n"; if ( keys(%modhash) > 0 ) { $result = $ldap->modify($dn, add => { %modhash }); die $result->error() if $result->code(); print "\nModified $dn!\n"; $count++; } else { print "\nNo changes required.\n"; } # update the displayName field #if( !in_array("displayName", @needed_attributes) ) #{ # print "\nSetting displayName to: $cn\n"; # $result = $ldap->modify( "$dn", replace => { "displayName" => "$cn" } ); # die $result->error() if $result->code(); #} print "\n------------------------------------\n"; } } else { print "No matches found.\n"; } print "Done! $count records updated.\n"; $ldap->unbind(); # a useful subroutine sub in_array() { my $val = shift @_ || return 0; my @array = @_; foreach (@array) { return 1 if ($val eq $_); } return 0; }