diff --git a/perl-xCAT-2.0/xCAT/Client.pm b/perl-xCAT-2.0/xCAT/Client.pm index 103b87f52..10dcc6db2 100644 --- a/perl-xCAT-2.0/xCAT/Client.pm +++ b/perl-xCAT-2.0/xCAT/Client.pm @@ -66,6 +66,12 @@ my %resps; sub submit_request { my $request = shift; my $callback = shift; + my $keyfile = shift; + my $certfile = shift; + my $cafile = shift; + unless ($keyfile) { $keyfile = $ENV{HOME}."/.xcat/client-key.pem"; } + unless ($certfile) { $certfile = $ENV{HOME}."/.xcat/client-cert.pem"; } + unless ($cafile) { $cafile = $ENV{HOME}."/.xcat/ca.pem"; } # If XCATBYPASS is set, invoke the plugin process_request method directly @@ -107,12 +113,12 @@ sub submit_request { } my $client = IO::Socket::SSL->new( PeerAddr => $xcathost, - SSL_key_file => $ENV{HOME}."/.xcat/client-key.pem", - SSL_cert_file => $ENV{HOME}."/.xcat/client-cert.pem", - SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem", + SSL_key_file => $keyfile, + SSL_cert_file => $certfile, + SSL_ca_file => $cafile, SSL_use_cert => 1, ); - die "Connection failure: $@\n" unless ($client); + die "Connection failure: $@ (SSL Timeout may mean the credentials in ~/.xcat are incorrect)\n" unless ($client); my $msg=XMLout($request,RootName=>xcatrequest,NoAttr=>1,KeyAttr=>[]); print $client $msg; my $response; diff --git a/xCAT-server-2.0/etc/init.d/xcatd b/xCAT-server-2.0/etc/init.d/xcatd index cb821b274..8fb504e9a 100755 --- a/xCAT-server-2.0/etc/init.d/xcatd +++ b/xCAT-server-2.0/etc/init.d/xcatd @@ -11,6 +11,9 @@ # Short-Description: xCATd # Description: xCAT management service ### END INIT INFO +if [ -r /etc/sysconfig/xcat ]; then + . /etc/sysconfig/xcat +fi MStatus() diff --git a/xCAT-server-2.0/lib/xcat/plugins/blade.pm b/xCAT-server-2.0/lib/xcat/plugins/blade.pm index 6ecf27e77..64f0e7838 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/blade.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/blade.pm @@ -875,7 +875,7 @@ sub process_request { $invreq{arg} = ['mac']; $invreq{command} = ['rinv']; my $mac; - my $ip = $request->{'!xcat_clientip'}; + my $ip = $request->{'_xcat_clientip'}; my $arptable = `/sbin/arp -n`; my @arpents = split /\n/,$arptable; foreach (@arpents) { diff --git a/xCAT-server-2.0/lib/xcat/plugins/bmcconfig.pm b/xCAT-server-2.0/lib/xcat/plugins/bmcconfig.pm index a0a759c7c..7eea99f83 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/bmcconfig.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/bmcconfig.pm @@ -51,7 +51,7 @@ sub net_parms { sub process_request { my $request = shift; my $callback = shift; - my $node = $request->{'!xcat_clienthost'}->[0]; + my $node = $request->{'_xcat_clienthost'}->[0]; my $sitetable = xCAT::Table->new('site'); my $ipmitable = xCAT::Table->new('ipmi'); my $passtable = xCAT::Table->new('passwd'); diff --git a/xCAT-server-2.0/lib/xcat/plugins/destiny.pm b/xCAT-server-2.0/lib/xcat/plugins/destiny.pm index a276522b0..4470317fe 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/destiny.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/destiny.pm @@ -129,11 +129,11 @@ sub nextdestiny { #TODO: service third party getdestiny.. } else { #client asking to move along its own chain #TODO: SECURITY with this, any one on a node could advance the chain, for node, need to think of some strategy to deal with... - unless ($request->{'!xcat_clienthost'}->[0]) { + unless ($request->{'_xcat_clienthost'}->[0]) { #ERROR? malformed request return; #nothing to do here... } - my $node = $request->{'!xcat_clienthost'}->[0]; + my $node = $request->{'_xcat_clienthost'}->[0]; ($node) = noderange($node); unless ($node) { #not a node, don't trust it @@ -186,11 +186,11 @@ sub getdestiny { @nodes = ($request->{node}); } } else { # a client asking for it's own destiny. - unless ($request->{'!xcat_clienthost'}->[0]) { + unless ($request->{'_xcat_clienthost'}->[0]) { $callback->({destiny=>[ 'discover' ]}); return; } - my ($node) = noderange($request->{'!xcat_clienthost'}->[0]); + my ($node) = noderange($request->{'_xcat_clienthost'}->[0]); unless ($node) { # it had a valid hostname, but isn't a node $callback->({destiny=>[ 'discover' ]}); return; diff --git a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm index 8a0c06c08..0e1600abd 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm @@ -86,7 +86,7 @@ sub process_request { my $callback = shift; my $doreq = shift; my $node = $request->{node}->[0]; - my $ip = $request->{'!xcat_clientip'}; + my $ip = $request->{'_xcat_clientip'}; openlog("xCAT node discovery",'','local0'); #First, fill in tables with data fields.. if (defined($request->{mtm}) or defined($request->{serial})) { diff --git a/xCAT-server-2.0/lib/xcat/plugins/switch.pm b/xCAT-server-2.0/lib/xcat/plugins/switch.pm index 284e27161..7bf0cdc4e 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/switch.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/switch.pm @@ -18,7 +18,7 @@ sub process_request { my $req = shift; my $cb = shift; my $doreq = shift; - my $ip = $req->{'!xcat_clientip'}; + my $ip = $req->{'_xcat_clientip'}; my $mac = ''; my $arptable = `/sbin/arp -n`; my @arpents = split /\n/,$arptable; diff --git a/xCAT-server-2.0/sbin/xcatd b/xCAT-server-2.0/sbin/xcatd index 3e1bb6d68..e57e88fb9 100755 --- a/xCAT-server-2.0/sbin/xcatd +++ b/xCAT-server-2.0/sbin/xcatd @@ -7,6 +7,7 @@ BEGIN use lib "$::XCATROOT/lib/perl"; use xCAT::Utils; use File::Path; +use xCAT::Client submit_request; use IO::Socket::SSL; if (xCAT::Utils->isLinux()) { @@ -255,9 +256,9 @@ if (xCAT::Utils->isLinux()) { $peerhost=gethostbyaddr($client,AF_INET)."\n"; my $req = eval { XMLin($data, SuppressEmpty=>undef,ForceArray=>1) }; if ($req and $req->{command} and ($req->{command}->[0] eq "findme")) { - $req->{'!xcat_clienthost'}=gethostbyaddr($client,AF_INET)."\n"; - $req->{'!xcat_clientip'}=inet_ntoa($client); - $req->{'!xcat_clientport'}=$sport; + $req->{'_xcat_clienthost'}=gethostbyaddr($client,AF_INET)."\n"; + $req->{'_xcat_clientip'}=inet_ntoa($client); + $req->{'_xcat_clientport'}=$sport; if (defined($cmd_handlers{"findme"})) { $req->{cacheonly}->[0] = 1; plugin_command($req,undef,\&convey_response); @@ -566,10 +567,60 @@ sub dispatch_request { my $req = shift; my $callback = shift; my $modname = shift; + my $reqs = []; no strict "refs"; - ${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request); + + #Hierarchy support. Originally, the default scope for noderange commands was + #going to be the servicenode associated unless overriden. + #However, assume for example that you have blades and a blade is the service node + #rpower being executed by the servicenode for one of its subnodes would have to + #reach it's own management module. This has the potential to be non-trivial for some quite possible network configurations. + #Since plugins may commonly experience this, a preprocess_request implementation + #will for now be required for a command to be scaled through service nodes + #If the plugin offers a preprocess method, use it to set the request array + if (defined(${"xCAT_plugin::".$modname."::"}{preprocess_request})) { + $reqs = ${"xCAT_plugin::".$modname."::"}{preprocess_request}->($req); + } else { #otherwise, pass it in without hierarchy support + $reqs = [$req]; + } + + #TODO: calls to dispatch must be parallelized + foreach (@{$reqs}) { + if ($_->{'_xcatdest'} and thishostisnot($_->{'_xcatdest'})) { + my $oldenv = $ENV{XCATHOST}; + $ENV{XCATHOST} = ( $_->{'_xcatdest'} =~ /:/ ? $_->{'_xcatdest'} : $_->{'_xcatdest'}.":3001" ); + eval { + undef $_->{'_xcatdest'}; + xCAT::Client::submit_request($_,$callback,$xcatdir."/cert/server-key.pem",$xcatdir."/cert/server-cert.pem",$xcatdir."/cert/ca.pem"); + }; + if ($@) { + $callback->({error=>["Error dispatching command to ".$ENV{XCATHOST}.""],errorcode=>[1]}); + syslog("local4|err","Error dispatching request: ".$@); + } + $ENV{XCATHOST} = $oldenv; + } else { + ${"xCAT_plugin::".$modname."::"}{process_request}->($_,$callback,\&do_request); + } + } } +sub thishostisnot { + my $comparison = shift; + my @ips = split /\n/,`/sbin/ip addr`; + my $comp=inet_aton($comparison); + foreach (@ips) { + if (/^\s*inet/) { + my @ents = split(/\s+/); + my $ip=$ents[2]; + $ip =~ s/\/.*//; + if (inet_aton($ip) eq $comp) { + return 0; + } + #print Dumper(inet_aton($ip)); + } + } + return 1; +} sub do_request { my $req = shift; my $second = shift; @@ -627,7 +678,6 @@ sub convey_response { } print $parent_fd XMLout($resp,KeyAttr=>[], NoAttr=>1,RootName=>'xcatresponse'); <$parent_fd>; #Block until parent acks data - #print "woo"; # KeyAttr => [], NoAttr => 1) } @@ -672,9 +722,9 @@ sub service_connection { #printf $request."\n"; $request=""; if (validate($peername,$peerhost,$req)) { - $req->{'!xcat_authname'} = [$peername]; - $req->{'!xcat_clienthost'} = [$peerhost]; - $req->{'!xcat_clientport'}= [$peerport]; + $req->{'_xcat_authname'} = [$peername]; + $req->{'_xcat_clienthost'} = [$peerhost]; + $req->{'_xcat_clientport'}= [$peerport]; $$progname="xCATd SSL: ".$req->{command}->[0]." for ".($peername ? $peername ."@".$peerhost : $peerhost); if ($cmd_handlers{$req->{command}->[0]}) { return plugin_command($req,$sock,\&convey_response);