diff --git a/xCAT-client/bin/xcatclient b/xCAT-client/bin/xcatclient index 217a8fca6..5bb9a5441 100755 --- a/xCAT-client/bin/xcatclient +++ b/xCAT-client/bin/xcatclient @@ -60,6 +60,11 @@ if ($arg ne "NO_NODE_RANGE") { $cmdref->{noderange}->[0]=$arg; } push (@{$cmdref->{arg}}, @ARGV); +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/xcatclientnnr b/xCAT-client/bin/xcatclientnnr index 3a41c0763..4462369b1 100755 --- a/xCAT-client/bin/xcatclientnnr +++ b/xCAT-client/bin/xcatclientnnr @@ -25,6 +25,11 @@ if (-p STDIN) { } push (@{$cmdref->{arg}}, @ARGV); +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); exit $xCAT::Client::EXITCODE; diff --git a/xCAT-server/lib/perl/xCAT/ADUtils.pm b/xCAT-server/lib/perl/xCAT/ADUtils.pm index 4d81c6ef3..9a4527f9d 100644 --- a/xCAT-server/lib/perl/xCAT/ADUtils.pm +++ b/xCAT-server/lib/perl/xCAT/ADUtils.pm @@ -107,7 +107,9 @@ sub add_user_account { return {error=>"Unable to determine all required parameters"}; } my $newpassword = $args{password}; - unless ($newpassword) { + if ($newpassword) { + $newpassword = '"'.$newpassword.'"'; + } else { $newpassword = '"'.genpassword(8).'"'; } Encode::from_to($newpassword,"utf8","utf16le"); #ms uses utf16le, we use utf8 @@ -186,8 +188,6 @@ sub add_user_account { } elsif (not $rc==8192) { return {error=>"Unknown error $rc"}; } - open(HUH,">","/tmp/huhh"); - print HUH $ldif; $rc = system("echo '$ldif'|ldapmodify -H ldaps://$directoryserver"); return {password=>$newpassword}; } @@ -264,7 +264,7 @@ sub krb_login { if (-x "/usr/kerberos/bin/kinit") { $kinit = "/usr/kerberos/bin/kinit"; } - my $kinit = open3($krbin,$krbout,$krberr,$kinit,$username."@".$realm); + $kinit = open3($krbin,$krbout,$krberr,$kinit,$username."@".$realm); my $ksel = IO::Select->new($krbout,$krberr); my @handles; while (@handles = $ksel->can_read()) { @@ -338,7 +338,8 @@ sub find_free_params { #search for things like next available uidNumber #use Data::Dumper; #print krb_login(username=>"Administrator",password=>"cluster",realm=>"XCAT.E1350"); #print Dumper(find_free_params(directoryserver=>"v4.xcat.e1350",ou=>"dc=xcat,dc=e1350")); -#print Dumper add_user_account(dnsdomain=>'xcat.e1350',username=>'ffuu',directoryserver=>'v4.xcat.e1350'); +#use Data::Dumper; +#print Dumper(add_user_account(dnsdomain=>'xcat.e1350',username=>'ffuu',directoryserver=>'v4.xcat.e1350')); #print Dumper add_machine_account(node=>'ufred.xcat.e1350',directoryserver=>'v4.xcat.e1350'); 1; diff --git a/xCAT-server/lib/xcat/plugins/activedirectory.pm b/xCAT-server/lib/xcat/plugins/activedirectory.pm index b4c05d1d4..ed3c70833 100644 --- a/xCAT-server/lib/xcat/plugins/activedirectory.pm +++ b/xCAT-server/lib/xcat/plugins/activedirectory.pm @@ -7,12 +7,16 @@ BEGIN my $callback; use lib "$::XCATROOT/lib/perl"; use Getopt::Long; +use xCAT::ADUtils; +use Net::DNS; + sub handled_commands { return { addclusteruser => 'site:directoryprovider', addclouduser => 'site:directoryprovider', }; } + sub process_request { my $request = shift; my $command = $request->{command}->[0]; @@ -24,26 +28,91 @@ sub process_request { my $fullname; my $gid; my $uid; + my $ou; @ARGV=@{$request->{arg}}; Getopt::Long::Configure("bundling"); - Getopt::Long::Configure("pass_through"); + Getopt::Long::Configure("no_pass_through"); if (!GetOptions( 'd=s' => \$homedir, 'c=s' => \$fullname, 'g=s' => \$gid, + 'o=s' => \$ou, 'u=s' => \$uid)) { - die "Not possible"; + die "TODO: usage message"; } my $username = shift @ARGV; - my %args = ( username => $username ); + my $domain; + my $sitetab = xCAT::Table->new('site'); + if ($username =~ /@/) { + ($username,$domain) = split /@/,$username; + $domain = lc($domain); + } else { + $domain = $sitetab->getAttribs({key=>'domain'},['value']); + unless ($domain and $domain->{value}) { + sendmsg([1,"Domain not provided and none set in site table"]); + } + $domain = $domain->{value}; + } + #TODO: if multi-domain support implemented, use the domains table to reference between realm and domain + my $server = $sitetab->getAttribs({key=>'directoryserver'},['value']); + if ($server and $server->{value}) { + $server = $server->{value}; + } else { + my $res = Net::DNS::Resolver->new; + my $query = $res->query("_ldap._tcp.$domain","SRV"); + if ($query) { + foreach my $srec ($query->answer) { + $server = $srec->{target}; + } + } + unless ($server) { + sendmsg([1,"Unable to determine a directory server to communicate with, try site.directoryserver"]); + } + } + + my $realm = $sitetab->getAttribs({key=>'realm'},['value']); + if ($realm and $realm->{value}) { + $realm = $realm->{value}; + } else { + $realm = uc($domain); + $realm =~ s/\.$//; #remove trailing dot if provided + } + #my $domainstab = xCAT::Table->new('domains'); + #$realm = $domainstab->getAttribs({domain=>$domain}, + my $passtab = xCAT::Table->new('passwd'); + my $adpent = $passtab->getAttribs({key=>'activedirectory'},[qw/username password/]); + unless ($adpent and $adpent->{username} and $adpent->{password}) { + sendmsg([1,"activedirectory entry missing from passwd table"]); + return 1; + } + + my $err = xCAT::ADUtils::krb_login(username=>$adpent->{username},password=>$adpent->{password},realm=>$realm); + if ($err) { + sendmsg([1,"Error authenticating to Active Directory"]); + return 1; + } + my %args = ( + username => $username, + dnsdomain => $domain, + directoryserver=> $server, + ); if ($fullname) { $args{fullname} = $fullname }; - sendmsg("Full name: ".$fullname); - sendmsg(join(" ",@ARGV)); + if ($ou) { $args{ou} = $ou }; + if ($request->{environment} and + $request->{environment}->[0]->{XCAT_USERPASS}) { + $args{password} = $request->{environment}->[0]->{XCAT_USERPASS}->[0]; + } + #TODO: args password + if (defined $gid) { $args{gid} = $gid }; + if (defined $uid) { $args{uid} = $uid }; + #TODO: smbHome for windows + if (defined $homedir) { $args{homedir} = $homedir }; + my $ret = xCAT::ADUtils::add_user_account(%args); + if (ref $ret and $ret->{error}) { + sendmsg([1,$ret->{error}]); + } } - - - }