On Wed, Dec 3, 2008 at 6:43 PM, Graham Barr <[EMAIL PROTECTED]> wrote:
> On Dec 2, 2008, at 8:20 AM, A. Farber wrote:
>> I have a script which reads phone numbers from a CSV file
>> and stores them in Active Directory (w2k3), so that you can
>> find a user phone number in the address book of Exchange.
>>
>> After some searching I've found a suggestion to set
>> LDAP_SERVER_PERMISSIVE_MODIFY_OID so that
>> AD does not prevent me from emptying empty values:
>> http://msdn.microsoft.com/en-us/library/aa366984.aspx

> Try
> use constant LDAP_SERVER_PERMISSIVE_MODIFY_OID  '1.2.840.113556.1.4.1413';
>
> $mod = $ldap->modify($entry,
>  control => [ { type => LDAP_SERVER_PERMISSIVE_MODIFY_OID } ],
>  replace => {
>    homePhone => $href->{HOME},
>    mobile => $href->{MOBILE},
>    facsimileTelephoneNumber => $href->{FAX}
>  }
> );
>

Thank you, but unfortunately I still get:

Failed to modify user: 00000057: LdapErr: DSID-0C090A85, comment:
Error in attribute conversion operation, data 0, vece at
./fix-phones.pl line 78, <> line 374.

Regards
Alex
#!/usr/bin/perl -wT

# This script imports phone numbers into AD
# Usage: ./fix-phones.pl phonebook.csv
# Execute "sudo yum install perl-LDAP" first if needed

use strict;
use Net::LDAPS;
use Data::Dumper;
use constant LDAP_SERVER_PERMISSIVE_MODIFY_OID => '1.2.840.113556.1.4.1413';

$ENV{PATH} = '/bin:/usr/bin';
$Data::Dumper::Useqq = 1;

use constant ROOTDN   => 'OU=Imported,OU=User 
Accounts,DC=internal,DC=XXX,DC=com';
use constant DOMAIN   => 'internal.XXX.com';
use constant SERVER   => ['ablwdc01.' . DOMAIN, 'ablwdc02.' . DOMAIN, 
'ablwdc03.' . DOMAIN];
use constant ADMIN    => 'Admin';
use constant ADMPW    => 'XXXXXX';

my ($rot13, $ldap, $search, $mod, $href, %phones);

($rot13 = ADMPW) =~ y/A-Za-z/N-ZA-Mn-za-m/;
$ldap = Net::LDAPS->new(SERVER) or 
        die('Can not connect to LDAP server');
$ldap->bind(ADMIN . '@' . DOMAIN, password => $rot13) or
        die('Can not bind to LDAP server as ' . ADMIN);

while(<>) {
        tr/"//d;
        tr/\r//d;
        next unless /^([^,]+),[^,]+,([^,]*),([^,]*),([^,\n]*)/;
        my ($full, $home, $mobile, $fax) = ($1, $2, $3, $4);

        $full =~ s/\xDF/ss/g;
        # replace german umlauts by asterisks
        $full =~ s/[\xC0-\xFF]/\*/g;
        # split full name in first and last name
        next unless $full =~ /^(\S+)\s+(\S+)$/;
        my ($last, $first) = ($1, $2);

        my $filter = 
"(&(objectCategory=Person)(objectClass=User)(givenName=$first)(sn=$last))";

        # Workaround: AD does not like it if you set empty attributes to empty, 
so use 'n/a' as default
        #$phones{$filter} = {HOME => $home || 'n/a', MOBILE => $mobile || 
'n/a', FAX => $fax || 'n/a'};
        $phones{$filter} = {HOME => $home, MOBILE => $mobile, FAX => $fax};
}

#print STDERR Dumper(\%phones);
#exit 0;

while (my ($filter, $href) = each %phones) {

        $search = $ldap->search(
            base    => ROOTDN,
            attrs   => [qw(givenName sn)],
            filter  => $filter,
            sizelimit => 1,
        );
        $search->code() && die $search->error();

        foreach my $entry ($search->entries()) { 
                my $givenName   = $entry->get_value('givenName');
                my $sn          = $entry->get_value('sn');

                next unless $givenName && $sn;

                printf STDERR "%-16s %-16s -> %16s %16s %16s\n", 
                    $givenName, $sn, $href->{HOME}, $href->{MOBILE}, 
$href->{FAX};

                $mod = $ldap->modify($entry, 
                    control => [ { type => LDAP_SERVER_PERMISSIVE_MODIFY_OID } 
],
                    replace => { 
                        homePhone => $href->{HOME},
                        mobile => $href->{MOBILE}, 
                        facsimileTelephoneNumber => $href->{FAX} });
                $mod->code() && die 'Failed to modify user: ' . $mod->error();

                #$entry->dump; 
        }
}

$ldap->unbind();

Reply via email to