I'm looking for a way to batch create a list of computers accounts in Active directroy running on Windows 2000 PDC. I tried to use perl ldap to create those objects but I didn't manage to set the sAMAccountType to "805306369" ( apparently this is a read only auto generated value) Is there any way to do that under Linux ? Thanks, Thomas #! /usr/bin/perl use strict; use Net::LDAP; use Net::LDAP::Entry; my $base_dn = "DC=my,DC=domain"; my $computer_name = "host01"; my $computer_branche = "OU=Workstations"; my $computer_dn = "CN=$computer_name,$computer_branche,$base_dn"; my $ldap = Net::LDAP->new( 'ldap://20.20.1.11') or die "$@"; my $mesg = $ldap->bind ("CN=Administrator,CN=Users,$base_dn", password => "secret"); $mesg->code && die $mesg->error; my $entry = Net::LDAP::Entry->new; $entry->dn("$computer_dn"); $entry->add ( objectClass => [ qw(top person organizationalPerson user computer) ], cn => "$computer_name", name => $computer_name, dNSHostName => $computer_name . '.ep.parl.union.eu' , sAMAccountName => uc($computer_name) .'$', objectCategory => 'CN=Computer,CN=Schema,CN=Configuration,$base_dn', operatingSystem => 'EP Linux Desktop LXD', operatingSystemVersion => '3', mail => 'ISPcell-SALX at europarl.europa.eu', userPrincipalName => 'HOST/'. uc($computer_name) .'@MY.DOMAIN', servicePrincipalName => [ 'HOST/'. $computer_name .'.my.domain', 'HOST/'. $computer_name, 'CIFS/'. $computer_name .'.my.domain', 'CIFS/'. $computer_name, 'nfs/'. $computer_name .'.my.domain', 'nfs/'. $computer_name ], userAccountControl => "544", ); my $mesg = $entry->update ( $ldap ); # update directory server $mesg->code && die $mesg->error; my $mesg = $ldap->modify ( "CN=Domain Computers,CN=Users,$base_dn", add => { "member" => "$computer_dn" } ); $mesg->code && die $mesg->error; my $mesg = $ldap->modify ( $computer_dn, replace => { "primaryGroupID" => "515" } ); $mesg->code && die $mesg->error; my $mesg = $ldap->modify ( "CN=Domain Users,CN=Users,$base_dn", delete => { "member" => "$computer_dn" } ); $mesg->code && die $mesg->error; my $mesg = $ldap->search( # perform a search base => "$base_dn", filter => "CN=$computer_name" ); $mesg->code && die $mesg->error; # DEBUG foreach my $entry ($mesg->entries) { foreach my $attr ( $entry->attributes) { if ($attr eq "objectSid" or $attr eq "objectGUID" ) { print "$attr : ". _sid2string($entry->get_value ($attr))."\n" } else { print "$attr : ". $entry->get_value ($attr)."\n"; } } }
I found the solution by setting userAccountControl to "4096" ( the samba net ads join set this value to "69632" and I think that's incorrect ) If somebody is interested : #! /usr/bin/perl use strict; use Net::LDAP; use Net::LDAP::Entry; my $base_dn = "DC=my,DC=domain"; my $computer_name = "host02"; my $computer_branche = "OU=Workstations"; my $computer_dn = "CN=$computer_name,$computer_branche,$base_dn"; my $domain = "my.domain"; my $ldap = Net::LDAP->new( 'ldap://epluxsdc01') or die "$@"; my $mesg = $ldap->bind ("CN=Administrator,CN=Users,$base_dn", password => "password"); $mesg->code && die $mesg->error; my $entry = Net::LDAP::Entry->new; $entry->dn("$computer_dn"); $entry->add ( objectClass => [ qw(top person organizationalPerson user computer) ], cn => "$computer_name", name => $computer_name, dNSHostName => $computer_name . '.ep.parl.union.eu' , sAMAccountName => uc($computer_name) .'$', objectCategory => "CN=Computer,CN=Schema,CN=Configuration,$base_dn", operatingSystem => 'EP Linux Desktop LXD', operatingSystemVersion => '3', mail => 'ISPcell-SALX at europarl.europa.eu', userPrincipalName => 'HOST/'. uc($computer_name) .'@'.uc($domain), servicePrincipalName => [ "HOST/$computer_name.$domain", "HOST/$computer_name", "CIFS/$computer_name.$domain", "CIFS/$computer_name", "nfs/$computer_name.$domain", "nfs/$computer_name" ], userAccountControl => "4096", ); my $mesg = $entry->update ( $ldap ); # update directory server $mesg->code && die $mesg->error; my $mesg = $ldap->search( # perform a search base => "$base_dn", filter => "CN=$computer_name" ); $mesg->code && die $mesg->error; foreach my $entry ($mesg->entries) { foreach my $attr ( $entry->attributes) { if ($attr eq "objectSid" or $attr eq "objectGUID" ) { print "$attr : ". _sid2string($entry->get_value ($attr))."\n" } else { print "$attr : ". $entry->get_value ($attr)."\n"; } } } sub _sid2string { my $sid = shift; my (@unpack) = unpack( "H2 H2 n N V*", $sid ); my ( $sid_rev, $num_auths, $id1, $id2, @ids ) = (@unpack); my $string = join( "-", "S", $sid_rev, ( $id1 << 32 ) + $id2, @ids ); return $string; } sub _string2sid { my $string = shift; my (@split) = split( m/\-/, $string ); my ( $prefix, $sid_rev, $auth_id, @ids ) = (@split); if ( $auth_id != scalar(@ids) ) { die "bad string: $string"; } my $sid = pack( "C4", "$sid_rev", "$auth_id", 0, 0 ); $sid .= pack( "C4", ( $auth_id & 0xff000000 ) >> 24, ( $auth_id & 0x00ff0000 ) >> 16, ( $auth_id & 0x0000ff00 ) >> 8, $auth_id & 0x000000ff ); for my $i (@ids) { $sid .= pack( "I", $i ); } return $sid; }
Reasonably Related Threads
- failes replication ldap, error SPN
- Samba 3.5.8 / Windows error and system errors while mapping network drive on some PC's
- failes replication ldap, error SPN
- Authenticating against ActiveDirectory - can't read userPassword/unicodePwd?
- failes replication ldap, error SPN