Re: Setting LDAP_SERVER_PERMISSIVE_MODIFY_OID to allow empty values in AD
"Alexander Farber" <[email protected]>
| Newsgroups | gmane.comp.lang.perl.modules.ldap |
|---|---|
| Message-ID | <[email protected]> |
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
fix-phones.txt
(text/plain, 2.5 KB)
#!/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();