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;
}
Maybe Matching 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