mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 19:32:31 +00:00 
			
		
		
		
	-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:
		| @@ -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}; | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user