In a process of deep contemplation, abdul mulla carefully constucted the
following missive on 10/11/2005 5:45 AM:
Hi Folks,
Wondered if anyone out there might have examples they
can provide me on how I can create a W2K domain user
in AD using LDAP that also permits them terminal
services using LDAP-Perl.
Regards, Abdul
This code snippet creates a user, changes his password and moves him out
of the Domain Users group (required for the project this was part of).
It doesn't have anything about Terminal Services, but all the constants
are here, experiment:
You have to have a Administrative Bind with a LDAP/SSL connection for
this to work.
##########################################################
# AD Constants
##########################################################
use constant ADS_UF_SCRIPT => 0x0001;
use constant ADS_UF_ACCOUNTDISABLE => 0x0002;
use constant ADS_UF_HOMEDIR_REQUIRED => 0x0008;
use constant ADS_UF_LOCKOUT => 0x0010;
use constant ADS_UF_PASSWD_NOTREQD => 0x0020;
use constant ADS_UF_PASSWD_CANT_CHANGE => 0x0040;
use constant ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED => 0x0080;
use constant ADS_UF_TEMP_DUPLICATE_ACCOUNT => 0x0100;
use constant ADS_UF_NORMAL_ACCOUNT => 0x0200;
use constant ADS_UF_INTERDOMAIN_TRUST_ACCOUNT => 0X0800;
use constant ADS_UF_WORKSTATION_TRUST_ACCOUNT => 0X1000;
use constant ADS_UF_SERVER_TRUST_ACCOUNT => 0X2000;
use constant ADS_UF_PASSWORD_NEVER_EXPIRES => 0x10000;
use constant ADS_UF_MNS_LOGON_ACCOUNT => 0X20000;
use constant ADS_UF_SMARTCARD_REQUIRED => 0X40000;
use constant ADS_UF_TRUSTED_FOR_DELEGATION => 0X80000;
use constant ADS_UF_NOT_DELEGATED => 0X100000;
use constant ADS_UF_USE_DES_KEY_ONLY => 0x200000;
use constant ADS_UF_DONT_REQUIRE_PREAUTH => 0x400000;
use constant ADS_UF_PASSWORD_EXPIRED => 0x800000;
use constant ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION => 0x1000000;
use constant INITIAL_ADS_ACCOUNT => ADS_UF_ACCOUNTDISABLE +
ADS_UF_NORMAL_ACCOUNT ;
use constant FINAL_ADS_ACCOUNT => ADS_UF_NORMAL_ACCOUNT +
ADS_UF_PASSWORD_EXPIRED;
use constant DISABLED_USER => ADS_UF_NORMAL_ACCOUNT + ADS_UF_ACCOUNTDISABLE;
my $objectClass = [ 'top', 'person', 'organizationalPerson', 'user',
'inetOrgPerson' ];
my $charmap = Unicode::Map8->new('latin1') or die;
# Get Group Token for alternate primary group
$mesg = $ldap->search(base => SOMEGROUP,
filter => '(objectclass=*)',
attrs => ['primaryGroupToken']
);
$mesg->code && die "Searching for ".SOMEGROUP.":".$mesg->error;
$mesg->count() || die "No entry found for ".SOMEGROUP." primaryGroupToken";
$adentry = $mesg->pop_entry();
my $primaryGroupToken = $adentry->get_value('primaryGroupToken');
my $dn = "cn=$username,$ou,".ADBASE;
my $adentry = Net::LDAP::Entry->new;
$adentry->dn($dn);
$adentry->add('sAMAccountName' => $username);
# Set up single cn, or reference to an array of cn
$adentry->add('cn' => $username);
$adentry->add('userAccountControl' => INITIAL_ADS_ACCOUNT);
$adentry->add('objectClass' => $objectClass);
foreach my $attr (keys %attrs) {
$attrs{$attr} && $adentry->add($attr => $attrs{$attr});
}
my $result = $ldap->add( $adentry );
$result->code && die "failed to add entry: $dn:", $result->error ;
if ($result->code == 0) {
$mesg = $ldap->modify(SOMEGROUP,
add => { member => $dn} );
$mesg->code && die "Adding User to group
".SOMEGROUP.":".$mesg->error;
my $newUniPW = $charmap->tou('"'.$userpassword.'"')->byteswap()->utf16();
$mesg = $ldap->modify($dn,
changes => [
replace => [ unicodePwd => $newUniPW,
primaryGroupID => $primaryGroupToken,
userAccountControl => FINAL_ADS_ACCOUNT ] ]);
$mesg->code && die $mesg->error;
$mesg = $ldap->modify(DOMUSERGROUPNAME,
delete => { member => $dn } );
$mesg->code && die "Deleting Member from
".DOMUSERGROUPNAME.":".$mesg->error;