diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm
index b90157d1c..aff404e07 100644
--- a/perl-xCAT/xCAT/Schema.pm
+++ b/perl-xCAT/xCAT/Schema.pm
@@ -705,7 +705,7 @@ linuximage => {
},
},
passwd => {
- cols => [qw(key username password cryptmethod comments disable)],
+ cols => [qw(key username password cryptmethod authdomain comments disable)],
keys => [qw(key username)],
table_desc => 'Contains default userids and passwords for xCAT to access cluster components. In most cases, xCAT will also actually set the userid/password in the relevant component when it is being configured or installed. Userids/passwords for specific cluster components can be overidden in other tables, e.g. mpa, ipmi, ppchcp, etc.',
descriptions => {
@@ -713,6 +713,7 @@ passwd => {
username => 'The default userid for this type of component',
password => 'The default password for this type of component',
cryptmethod => 'Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod is not supported however the code attempts to auto-discover MD5 encrypted passwords.',
+ authdomain => 'The domain in which this entry has meaning, e.g. specifying different domain administrators per active directory domain',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
},
diff --git a/xCAT-server/lib/perl/xCAT/Template.pm b/xCAT-server/lib/perl/xCAT/Template.pm
index 1cfd1afb4..a38a5dcf5 100644
--- a/xCAT-server/lib/perl/xCAT/Template.pm
+++ b/xCAT-server/lib/perl/xCAT/Template.pm
@@ -290,7 +290,18 @@ sub windows_account_data {
unless ($::XCATSITEVALS{directoryprovider} eq "activedirectory" and $::XCATSITEVALS{domain}) {
return $useraccountxml;
}
- $useraccountxml.="\n\nAdministrators\nDomain Admins\n\n".$::XCATSITEVALS{domain}."\n\n\n";
+ my $domain;
+ my $doment;
+ my $domaintab = xCAT::Table->new('domain',-create=>0);
+ if ($domaintab) {
+ $doment = $domaintab->getNodeAttribs($node,['authdomain'],prefetchcache=>1);
+ }
+ if ($doment and $doment->{authdomain}) {
+ $domain = $doment->{authdomain};
+ } else {
+ $domain = $::XCATSITEVALS{domain};
+ }
+ $useraccountxml.="\n\nAdministrators\nDomain Admins\n\n".$domain."\n\n\n";
return $useraccountxml;
}
#this will examine table data, decide *if* a Microsoft-Windows-UnattendedJoin is warranted
@@ -304,16 +315,31 @@ sub windows_join_data {
}
#we are still here, meaning configuration has a domain and activedirectory set, probably want to join..
#TODO: provide a per-node 'disable' so that non-AD could be mixed into a nominally AD environment
- my $adinfo = machinepassword(wantref=>1); #TODO: needs rearranging in non prejoin case
my $prejoin =1;
if (defined $::XCATSITEVALS{prejoinactivedirectory} and not $::XCATSITEVALS{prejoinactivedirectory} ) {
$prejoin = 0;
}
- my $componentxml = ''."\n\n".$adinfo->{domain}."\n";
- if ($adinfo->{ou}) {
- $componentxml .= "".$adinfo->{ou}."\n";
+ my $domain;
+ my $doment;
+ my $domaintab = xCAT::Table->new('domain',-create=>0);
+ if ($domaintab) {
+ $doment = $domaintab->getNodeAttribs($node,['ou','authdomain'],prefetchcache=>1);
+ }
+ my $ou;
+ if ($doment and $doment->{ou}) {
+ $ou = $doment->{ou};
+ }
+ if ($doment and $doment->{authdomain}) {
+ $domain = $doment->{authdomain};
+ } else {
+ $domain = $::XCATSITEVALS{domain};
+ }
+ my $componentxml = ''."\n\n".$domain."\n";
+ if ($ou) {
+ $componentxml .= "".$ou."\n";
}
if ($prejoin) {
+ my $adinfo = machinepassword(wantref=>1); #TODO: needs rearranging in non prejoin case
#a note, MS is incorrect when they document unsecure join as " UnsecureJoin is performed, by using a null session with a pre-existing account. This means there is no authentication to the domain controller when configuring the machine account; it is done anonymously".
#the more informative bit is http://technet.microsoft.com/en-us/library/cc730845%28v=ws.10%29.aspx which says of 'securejoin': this method is actually less secure because the credentials reside in the ImageUnattend.xml file in plain text.
#xCAT is generating a one-time password that is kept as limited as is feasible for the deployment strategy
@@ -322,7 +348,22 @@ sub windows_join_data {
$componentxml .= "".$adinfo->{password}."\ntrue\n";
} else { #this is the pass-through credentials case, currrently inaccessible until TODO, this must be used
#with care as used incorrectly, an LDAP manager account is at high risk of compromise
- $componentxml .= "".$adinfo->{domain}."\n".$adinfo->{adminuser}."\n".$adinfo->{adminpass}."\n\n";
+ my $passtab = xCAT::Table->new('passwd',-create=>0);
+ unless ($passtab) { sendmsg([1,"Error authenticating to Active Directory"],$node); return; }
+ my @adpents = $passtab->getAttribs({key=>'activedirectory'},['username','password','authdomain']);
+ my $adpent;
+ my $username;
+ my $password;
+ foreach $adpent (@adpents) {
+ if ($adpent and $adpent->{authdomain} and $adpent->{authdomain} ne $domain) { next; }
+ if ($adpent and $adpent->{username} and $adpent->{password}) {
+ $username = $adpent->{username};
+ $password = $adpent->{password};
+ last;
+ }
+ }
+ unless ($username and $password) { die "Missing active directory admin auth data from passwd table" }
+ $componentxml .= "".$domain."\n".$username."\n".$password."\n\n";
}
$componentxml .= "\n\n";
@@ -407,25 +448,30 @@ sub machinepassword {
$ENV{HOME}='/etc/xcat';
$ENV{LDAPRC}='ad.ldaprc';
my $ou;
+ my $domain;
if ($domaintab) {
- my $ouent = $domaintab->getNodeAttribs('node','ou');
+ my $ouent = $domaintab->getNodeAttribs($node,['ou','authdomain'],prefetchcache=>1);
if ($ouent and $ouent->{ou}) {
$ou = $ouent->{ou};
}
+ if ($ouent and $ouent->{authdomain}) {
+ $domain = $ouent->{authdomain};
+ }
}
$passdata->{ou}=$ou;
#my $sitetab = xCAT::Table->new('site');
#unless ($sitetab) {
# return "ERROR: unable to open site table";
#}
- my $domain;
#(my $et) = $sitetab->getAttribs({key=>"domain"},'value');
+ unless ($domain) {
my @domains = xCAT::TableUtils->get_site_attribute("domain");
my $tmp = $domains[0];
if (defined($tmp)) {
$domain = $tmp;
} else {
- return "ERROR: no domain set in site table";
+ return "ERROR: no domain set in site table or in domain.authdomain for $node";
+ }
}
$passdata->{domain}=$domain;
my $realm = uc($domain);
@@ -435,8 +481,19 @@ sub machinepassword {
unless ($loggedrealms{$realm}) {
my $passtab = xCAT::Table->new('passwd',-create=>0);
unless ($passtab) { sendmsg([1,"Error authenticating to Active Directory"],$node); return; }
- (my $adpent) = $passtab->getAttribs({key=>'activedirectory'},['username','password']);
- unless ($adpent and $adpent->{username} and $adpent->{password}) {
+ my @adpents = $passtab->getAttribs({key=>'activedirectory'},['username','password','authdomain']);
+ my $adpent;
+ my $username;
+ my $password;
+ foreach $adpent (@adpents) {
+ if ($adpent and $adpent->{authdomain} and $adpent->{authdomain} ne $domain) { next; }
+ if ($adpent and $adpent->{username} and $adpent->{password}) {
+ $username = $adpent->{username};
+ $password = $adpent->{password};
+ last;
+ }
+ }
+ unless ($username and $password) {
return "ERROR: activedirectory entry missing from passwd table";
}
my $err = xCAT::ADUtils::krb_login(username=>$adpent->{username},password=>$adpent->{password},realm=>$realm);
@@ -448,7 +505,7 @@ sub machinepassword {
#my $server = $sitetab->getAttribs({key=>'directoryserver'},['value']);
my $server;
my @servers = xCAT::TableUtils->get_site_attribute("directoryserver");
- $tmp = $servers[0];
+ my $tmp = $servers[0];
if (defined($tmp)) {
$server = $tmp;
} else {