-hostaccountadd/hostaccountdel/hostaccountlist

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@5401 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2010-03-08 17:25:31 +00:00
parent dab2117644
commit 8c43db338a
2 changed files with 264 additions and 20 deletions

View File

@ -80,11 +80,81 @@ replace: userAccountControl
userAccountControl: 512';
sub del_host_account {
my %args = @_;
my $directoryserver = $args{directoryserver};
my $dnsdomain = $args{dnsdomain};
my $account = $args{account};
unless ($dnsdomain and $directoryserver and $account) {
die "Invalid arguments $dnsdomain and $directoryserver and $account";
}
my $domain_components = $dnsdomain;
$domain_components =~ s/^\.//;
$domain_components =~ s/\./,dc=/g;
$domain_components =~ s/^/dc=/;
my @searchcmd = qw/ldapsearch -H /;
push @searchcmd,"ldaps://$directoryserver","-b",$domain_components;
push @searchcmd,"(&(&(&(objectClass=user)(objectClass=computer))(!(isCriticalSystemObject=TRUE)))(name=$account))","dn";
my $searchout;
my $searchin;
my $searcherr = gensym;
my $search = open3($searchin,$searchout,$searcherr,@searchcmd);
print $searchout;
print $searchin;
my $searchselect = IO::Select->new($searchout,$searcherr);
my @handles;
my $failure;
my $dn;
while (@handles = $searchselect->can_read()) {
foreach (@handles) {
my $line = <$_>;
print $line;
if (not defined $line) {
$searchselect->remove($_);
next;
}
print $line;
if ($_ == $searcherr) {
if ($line =~ /error/i or $line =~ /problem/i) {
return {error=>$line};
}
} elsif ($line =~ /^dn: (.*)$/) {
if ($dn) { die "TODO: identify these cases, let xcat-user know this can happen"; }
$dn = $1;
}
}
}
my $ldif = "dn: $dn
changetype: delete";
my $deletein;
my $deleteout;
my $deleteerr = gensym;
my $deletion = open3($deletein,$deleteout,$deleteerr,'ldapmodify','-H',"ldaps://$directoryserver");
print $deletein $ldif."\n";
close($deletein);
print $ldif;
my $delselect = IO::Select->new($deleteout,$deleteerr);
while (@handles = $delselect->can_read()) {
foreach (@handles) {
my $line = <$_>;
print $line;
if (not defined $line) {
$delselect->remove($_);
next;
}
if ($_ == $deleteerr) {
if ($line =~ /error/i or $line =~ /problem/i) {
return {error=> $line};
}
}
}
}
}
sub del_user_account {
my %args = @_;
my $directoryserver = $args{directoryserver};
my $dnsdomain = $args{dnsdomain};
my $account = $args{username};
my $account = $args{account};
unless ($dnsdomain and $directoryserver and $account) {
die "Invalid arguments $dnsdomain and $directoryserver and $account";
}
@ -151,6 +221,61 @@ changetype: delete";
}
}
sub list_host_accounts { #provide enough data to construct an /etc/passwd looking output
my %args = @_;
my $directoryserver = $args{directoryserver};
my $dnsdomain = $args{dnsdomain};
unless ($dnsdomain and $directoryserver) {
die "Invalid arguments";
}
my $domain_components = $dnsdomain;
$domain_components =~ s/^\.//;
$domain_components =~ s/\./,dc=/g;
$domain_components =~ s/^/dc=/;
my @searchcmd = qw/ldapsearch -H /;
push @searchcmd,"ldaps://$directoryserver","-b",$domain_components;
push @searchcmd,qw/(&(&(objectClass=user)(objectClass=computer))(!(isCriticalSystemObject=TRUE))) name operatingSystem operatingSystemServicePack/;
my $searchout;
my $searchin;
my $searcherr = gensym;
my $search = open3($searchin,$searchout,$searcherr,@searchcmd);
my $searchselect = IO::Select->new($searchout,$searcherr);
my @handles;
my $failure;
my %currvalues =();
my %acchash= ();
while (@handles = $searchselect->can_read()) {
foreach (@handles) {
my $line = <$_>;
if (not defined $line) {
$searchselect->remove($_);
next;
}
if ($_ == $searcherr) {
if ($line =~ /error/i or $line =~ /problem/i) {
print $line;
$failure=1;
}
} elsif ($line =~ /^dn: (.*)$/) {
foreach(keys %currvalues) {
$acchash{$currvalues{accountname}}->{$_} = $currvalues{$_};
}
%currvalues=();
} elsif ($line =~ /^name: (.*)$/) {
$currvalues{accountname} = $1;
} elsif ($line =~ /^OperatingSystem: (.*)$/) {
$currvalues{os} = $1;
} elsif ($line =~ /^OperatingSystemServicePack: (.*)$/) {
$currvalues{osservicepack} = $1;
}
}
}
if ($failure) { return undef; }
foreach(keys %currvalues) {
$acchash{$currvalues{accountname}}->{$_} = $currvalues{$_};
}
return \%acchash;
}
sub list_user_accounts { #provide enough data to construct an /etc/passwd looking output
my %args = @_;
my $directoryserver = $args{directoryserver};
@ -333,11 +458,11 @@ sub add_user_account {
return {password=>$newpassword};
}
=cut
add_machine_account
add_host_account
Arguments are in a hash:
node=>name of machine to add
=cut
sub add_machine_account {
sub add_host_account {
my %args = @_;
my $nodename = $args{node};
my $dnsdomain = $args{dnsdomain};

View File

@ -13,16 +13,17 @@ use strict;
sub handled_commands {
return {
addclusteruser => 'site:directoryprovider',
addclouduser => 'site:directoryprovider',
delclusteruser => 'site:directoryprovider',
delclouduser => 'site:directoryprovider',
listclusterusers => 'site:directoryprovider',
listcloudusers => 'site:directoryprovider',
clusteruseradd => 'site:directoryprovider',
clusteruserdel => 'site:directoryprovider',
clusteruserlist => 'site:directoryprovider',
hostaccountlist => 'site:directoryprovider',
hostaccountadd => 'site:directoryprovider',
hostaccountdel => 'site:directoryprovider',
};
}
sub process_request {
$ENV{LDAPCONF}='/etc/xcat/ad.ldaprc';
my $request = shift;
my $command = $request->{command}->[0];
$callback = shift;
@ -66,7 +67,7 @@ sub process_request {
return;
}
}
if ($command =~ /list.*user/) { #user management command, listing
if ($command =~ /userlist/) { #user management command, listing
my $passwdfmt;
if ($request->{arg}) {
@ARGV=@{$request->{arg}};
@ -107,8 +108,66 @@ sub process_request {
sendmsg($account);
}
}
} elsif ($command =~ /del.*user/) {
my $username = shift @{$request->{arg}};
} elsif ($command =~ /hostaccountlist/) {
unless ($domain and $realm) {
sendmsg([1,"Unable to determine domain from arguments or site table"]);
return undef;
}
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 $accounts = xCAT::ADUtils::list_host_accounts(
dnsdomain => $domain,
directoryserver=> $server,
);
my $account;
foreach $account (keys %$accounts) {
sendmsg($account);
}
} elsif ($command =~ /hostaccountdel/) {
my $accountname;
my %loggedrealms = ();
foreach $accountname (@{$request->{node}}) {
if ($request->{arg} and scalar @{$request->{arg}}) {
die "TODO: usage";
}
if ($accountname =~ /@/) {
($accountname,$domain) = split /@/,$accountname;
$domain = lc($domain);
}
unless ($domain) {
sendmsg([1,"Unable to determine domain from arguments or site table"]);
return undef;
}
#my $domainstab = xCAT::Table->new('domains');
#$realm = $domainstab->getAttribs({domain=>$domain},
unless ($realm) {
$realm = uc($domain);
$realm =~ s/\.$//; #remove trailing dot if provided
}
$ENV{KRB5CCNAME}="/tmp/xcat/krbcache.$realm.$$";
unless ($loggedrealms{$realm}) {
my $err = xCAT::ADUtils::krb_login(username=>$adpent->{username},password=>$adpent->{password},realm=>$realm);
if ($err) {
sendmsg([1,"Error authenticating to Active Directory"],$accountname);
next;
}
$loggedrealms{$realm}=1;
}
my %args = (
account => $accountname,
dnsdomain => $domain,
directoryserver=> $server,
);
my $ret = xCAT::ADUtils::del_host_account(%args);
}
foreach my $realm (keys %loggedrealms) {
unlink "/tmp/xcat/krbcache.$realm.$$";
}
} elsif ($command =~ /userdel/) {
my $username = shift @{$request->{arg}};
if (scalar @{$request->{arg}}) {
die "TODO: usage";
}
@ -127,18 +186,24 @@ sub process_request {
$realm = uc($domain);
$realm =~ s/\.$//; #remove trailing dot if provided
}
$ENV{KRB5CCNAME}="/tmp/xcat/krbcache.$realm.$$";
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 $ret = xCAT::ADUtils::del_user_account(
username => $username,
dnsdomain => $domain,
directoryserver=> $server,
);
} elsif ($command =~ /add.*user/) { #user management command, adding
my %args = (
account => $username,
dnsdomain => $domain,
directoryserver=> $server,
);
if ($command =~ /userdel/) {
my $ret = xCAT::ADUtils::del_user_account(%args);
} elsif ($command =~ /hostaccountdel/) {
my $ret = xCAT::ADUtils::del_host_account(%args);
}
} elsif ($command =~ /useradd$/) { #user management command, adding
my $homedir;
my $fullname;
my $gid;
@ -198,9 +263,63 @@ sub process_request {
if (ref $ret and $ret->{error}) {
sendmsg([1,$ret->{error}]);
}
} elsif ($command =~ /hostaccountadd$/) { #user management command, adding
my $ou;
if ($request->{arg}) {
@ARGV=@{$request->{arg}};
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions('o=s' => \$ou)) {
die "TODO: usage message";
}
}
#my $domainents = $domaintab->getNodesAttribs($request->{node},['ou','domain']); #TODO: have this in schema
my $nodename;
my %loggedrealms=();
foreach $nodename (@{$request->{node}}) {
if ($nodename =~ /\./) {
($nodename,$domain) = split /\./,$nodename,2;
$domain = lc($domain);
}
unless ($domain) {
sendmsg([1,"Unable to determine domain from arguments or site table"]);
return undef;
}
#my $domainstab = xCAT::Table->new('domains');
#$realm = $domainstab->getAttribs({domain=>$domain},
unless ($realm) {
$realm = uc($domain);
$realm =~ s/\.$//; #remove trailing dot if provided
}
unless ($loggedrealms{$realm}) {
my $err = xCAT::ADUtils::krb_login(username=>$adpent->{username},password=>$adpent->{password},realm=>$realm);
if ($err) {
sendmsg([1,"Error authenticating to Active Directory"],$nodename);
next;
}
$loggedrealms{$realm}=1;
}
my %args = (
node => $nodename,
dnsdomain => $domain,
directoryserver=> $server,
);
if ($ou) { $args{ou} = $ou };
if ($request->{environment} and
$request->{environment}->[0]->{XCAT_HOSTPASS}) {
$args{password} = $request->{environment}->[0]->{XCAT_HOSTPASS}->[0];
}
my $ret = xCAT::ADUtils::add_host_account(%args);
if (ref $ret and $ret->{error}) {
sendmsg([1,$ret->{error}]);
} elsif (ref $ret) {
print $ret->{password};
}
}
}
}
sub sendmsg {