diff --git a/xCAT-server/lib/perl/xCAT/ADUtils.pm b/xCAT-server/lib/perl/xCAT/ADUtils.pm new file mode 100644 index 000000000..718d69a58 --- /dev/null +++ b/xCAT-server/lib/perl/xCAT/ADUtils.pm @@ -0,0 +1,109 @@ +# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html + +#This module provides simplified methods for adding machine/user accounts to active directory, +#as well as setting passwords for aforementioned accounts. + +#there exists direct perl ldap module, but too rare to bank on, going to use ldapmodify from +#system calls + +use strict; +use MIME::Base64; +use Encode; +use xCAT::Utils qw/genpassword/; + + +my $machineldiftemplate = 'dn: CN=##UPCASENODENAME##,##OU## +changetype: add +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: user +objectClass: computer +cn: ##UPCASENODENAME## +distinguishedName: CN=##UPCASENODENAME##,##OU## +objectCategory: CN=Computer,CN=Schema,CN=Configuration##REALMDCS## +instanceType: 4 +displayName: ##UPCASENODENAME##$ +name: ##UPCASENODENAME## +userAccountControl: 4096 +codePage: 0 +countryCode: 0 +accountExpires: 0 +sAMAccountName: ##UPCASENODENAME##$ +dNSHostName: ##UPCASENODENAME####DNSDOMAIN## +servicePrincipalName: HOST/##UPCASENODENAME## +servicePrincipalName: HOST/##UPCASENODENAME####DNSDOMAIN## + +dn: CN=##UPCASENODENAME##,##OU## +changetype: modify +replace: unicodePwd +unicodePwd::##B64PASSWORD##'; + + +=cut +add_machine_account +Arguments are in a hash: + node=>name of machine to add +=cut +sub add_machine_account { + my %args = @_; + my $nodename = $args{node}; + my $ou = $args{ou}; + my $dnsdomain = $args{dnsdomain}; + if (not $dnsdomain and $nodename =~ /\./) { #if no domain provided, guess from nodename + $dnsdomain = $nodename; + $dnsdomain =~ s/^[^\.]*//; + } + unless ($dnsdomain =~ /^\./) { + $dnsdomain = '.'.$dnsdomain; + } + $nodename =~ s/\..*//; #strip dns domain if part of nodename + my $upnodename = uc($nodename); + my $domain_components = $dnsdomain; + $domain_components =~ s/\./,dc=/g; + unless ($domain_components =~ /^,dc=/) { + $domain_components = ",dc=".$domain_components; + } + if ($ou) { + unless ($ou =~ /$domain_components\z/) { + $ou .= $domain_components; + } + } else { + $ou = "CN=Computers".$domain_components; + } + my $directoryserver = $args{directoryserver}; + unless ($domain_components and $dnsdomain and $ou and $upnodename and $directoryserver) { + return {error=>"Unable to determine all required parameters"}; + } + my $newpassword = $args{password}; + unless ($newpassword) { + $newpassword = '"'.genpassword(8).'"'; + } + Encode::from_to($newpassword,"utf8","utf16le"); #ms uses utf16le, we use utf8 + my $b64password = encode_base64($newpassword); + my $ldif = $machineldiftemplate; + $ldif =~ s/##B64PASSWORD##/$b64password/g; + $ldif =~ s/##OU##/$ou/g; + $ldif =~ s/##REALMDCS##/$domain_components/g; + $ldif =~ s/##DNSDOMAIN##/$dnsdomain/g; + $ldif =~ s/##UPCASENODENAME##/$upnodename/g; + my $dn = "CN=$upnodename,$ou"; + my $rc = system("ldapsearch -H ldaps://$directoryserver -b $dn"); + if ($rc == 0) { + return {error=>"System already exists"}; + } elsif (not $rc==8192) { + return {error=>"Unknown error $rc"}; + } + $rc = system("echo '$ldif'|ldapmodify -H ldaps://$directoryserver"); + + + + + + + + + return {password=>$newpassword}; +} +use Data::Dumper; +print Dumper(add_machine_account(node=>'v6.xcat.e1350',directoryserver=>'v4.xcat.e1350'));