From 1fdee035794b9f2f9a1e43c2dfdac93a233be01e Mon Sep 17 00:00:00 2001 From: lissav Date: Thu, 21 Jun 2012 13:00:38 +0000 Subject: [PATCH] Move xcatd validate routine into and create an xcatd library. This should help with development and debug git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@13138 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/sbin/xcatd | 205 +---------------------------------------- 1 file changed, 2 insertions(+), 203 deletions(-) diff --git a/xCAT-server/sbin/xcatd b/xCAT-server/sbin/xcatd index 4c09351d1..d33ff691f 100755 --- a/xCAT-server/sbin/xcatd +++ b/xCAT-server/sbin/xcatd @@ -31,6 +31,7 @@ use lib "$::XCATROOT/lib/perl"; use Storable qw(freeze thaw); use xCAT::Utils; use xCAT::MsgUtils; +use xCAT::xcatd; use File::Path; use Time::HiRes qw(sleep); use Thread qw(yield); @@ -1742,7 +1743,7 @@ sub service_connection { #we have a full request.. #printf $request."\n"; $request=""; - if (validate($peername,$peerhost,$req)) { + if (xCAT::xcatd->validate($peername,$peerhost,$req,\@deferredmsgargs)) { $req->{'_xcat_authname'} = [$peername]; $req->{'_xcat_clienthost'} = [$peerhost]; $req->{'_xcat_clientfqdn'} = [$peerfqdn]; @@ -1949,208 +1950,6 @@ sub relay_fds { #Relays file descriptors from pipes to children to the SSL socke return $rc; } -sub validate { - #Here is where we check if $peername is allowed to do $request in policy tbl. - # $peername, if set signifies client has a cert that the xCAT CA accepted. - # Logs to syslog and auditlog table all user commands, see site.auditskipcmds - # attribute. - # returns 1 if policy engine allows the action, 0 if denied. - - - # now check the policy table if user can run the command - my $peername=shift; - my $peerhost=shift; - my $request=shift; - my $policytable = xCAT::Table->new('policy'); - unless ($policytable) { - xCAT::MsgUtils->message("S","Unable to open policy data, denying"); - return 0; - } - - my $policies = $policytable->getAllEntries; - $policytable->close; - my $rule; - my $peerstatus="untrusted"; - # check to see if peerhost is trusted - foreach $rule (@$policies) { - - if (($rule->{name} and ($rule->{name} eq $peerhost)) && ($rule->{rule}=~ /trusted/i)) { - $peerstatus="Trusted"; - last; - } - } - RULE: foreach $rule (@$policies) { - if ($rule->{name} and $rule->{name} ne '*') { - #TODO: more complex matching (lists, wildcards) - next unless ($peername and $peername eq $rule->{name}); - } - if ($rule->{time} and $rule->{time} ne '*') { - #TODO: time ranges - } - if ($rule->{host} and $rule->{host} ne '*') { - #TODO: more complex matching (lists, noderanges?, wildcards) - next unless ($peerhost eq $rule->{host}); - } - if ($rule->{commands} and $rule->{commands} ne '*') { - #TODO: syntax for multiple commands - next unless ($request->{command}->[0] eq $rule->{commands}); - } - if ($rule->{parameters} and $rule->{parameters} ne '*') { - my $parms; - if ($request->{arg}) { - $parms = join(' ',@{$request->{arg}}); - } else { - $parms = ""; - } - my $patt = $rule->{parameters}; - unless ($parms =~ /$patt/) { - next; - } - } - if ($rule->{noderange} and $rule->{noderange} ne '*') { - my $matchall=0; - if ($rule->{rule} =~ /allow/i or $rule->{rule} =~ /accept/i or $rule->{rule} =~ /trusted/i) { - $matchall=1; - } - if (defined $request->{noderange}->[0]) { - my @tmpn=noderange($request->{noderange}->[0]); - $request->{node}=\@tmpn; - } - unless (defined $request->{node}) { - next RULE; - } - my @reqnodes = @{$request->{node}}; - my %matchnodes; - foreach (noderange($rule->{noderange})) { - $matchnodes{$_}=1; - } - REQN: foreach (@reqnodes) { - if (defined ($matchnodes{$_})) { - if ($matchall) { - next REQN; - } else { - last REQN; - } - } elsif ($matchall) { - next RULE; - } - } - } - # If we are still in, that means this rule is the first match and dictates behavior. - # We are not going to log getdestiny,getbladecons,getipmicons commands, way - # too many of them - #print Dumper($request); - if ($rule->{rule}) { - my $logst; - my $rc; - my $status; - if ($rule->{rule} =~ /allow/i or $rule->{rule} =~ /accept/i or $rule->{rule} =~ /trusted/i) { - $logst = "xCAT: Allowing ".$request->{command}->[0]; - $status = "Allowed"; - $rc=1; - } else { - $logst = "xCAT: Denying ".$request->{command}->[0]; - $status = "Denied"; - $rc=0; - } - if (($request->{command}->[0] ne "getdestiny") && ($request->{command}->[0] ne "getbladecons") && ($request->{command}->[0] ne "getipmicons")) { - # set username authenticated to run command - # if from Trusted host, use input username, else set from creds - if (($request->{username}) && defined($request->{username}->[0])) { - if ($peerstatus ne "Trusted" ) { # then set to peername - $request->{username}->[0] = $peername; - } - } else { - $request->{username}->[0] = $peername; - } - if ($request->{noderange} && defined($request->{noderange}->[0])) - { - $logst .= " to ".$request->{noderange}->[0]; - } else { # no noderange maybe a nodes - - if ($request->{node} && defined($request->{node}->[0])) { - my @reqnodes = @{$request->{node}}; - if (@reqnodes) { - $logst .= " to "; - foreach my $node (@reqnodes) { - $logst .= "$node,"; - } - chop $logst; - } - } - } - # add each argument - my $args = $request->{arg}; - my $arglist; - foreach my $argument (@$args){ - - $arglist .= " " . $argument; - } - if ($arglist) { $logst .= $arglist; } - if($peername) { $logst .= " for " . $request->{username}->[0]}; - if ($peerhost) { $logst .= " from " . $peerhost }; - - # read site.auditskipcmds attribute, - # if set skip commands else audit all cmds. - my @skipcmds=($::XCATSITEVALS{auditskipcmds}); #xCAT::Utils->get_site_attribute('auditskipcmds'); - # if not "ALL" and not a command from site.auditskipcmds - # and not getcredentials and not getcredentials , - # put in syslog and auditlog - my $skip = 0; - my $all = "all"; - if (defined($skipcmds[0])) { # if there are values - if (grep(/$all/i, @skipcmds)) { # skip all - $skip = 1; - } else { - if (grep(/$request->{command}->[0]/, @skipcmds)) { # skip the command - $skip = 1; - } - } - } - @deferredmsgargs=(); #should be redundant, but just in case - if (($request->{command}->[0] ne "getpostscript") && ($request->{command}->[0] ne "getcredentials") && ($skip == 0)) { - - # put in audit Table and syslog - my $rsp = {}; - $rsp->{syslogdata}->[0] = $logst; - if ($peername) { - $rsp->{userid} ->[0] = $request->{username}->[0]; - } - if ($peerhost) { - $rsp->{clientname} -> [0] = $peerhost; - } - if (defined $request->{clienttype}) { - $rsp->{clienttype} -> [0] = $request->{clienttype} -> [0]; - } else { - if (defined $request->{becomeuser}) { - $rsp->{clienttype} -> [0] = "webui"; - } else { - $rsp->{clienttype} -> [0] = "other"; - } - } - $rsp->{command} -> [0] = $request->{command}->[0]; - if ($request->{noderange} && defined($request->{noderange}->[0])) { - $rsp->{noderange} -> [0] = $request->{noderange}->[0]; - } - $rsp->{args} -> [0] =$arglist; - $rsp->{status} -> [0] = $status; - @deferredmsgargs = ("SA",$rsp); - } else { # getpostscript or getcredentials, just syslog - unless ($::XCATSITEVALS{skipvalidatelog}) { @deferredmsgargs=("S",$logst); } - } - } # end getbladecons,etc check - return $rc; - } else { #Shouldn't be possible.... - xCAT::MsgUtils->message("S","Impossible line in xcatd reached"); - return 0; - } - } # end RULE - #Reached end of policy table, reject by default. - xCAT::MsgUtils->message("S","Request matched no policy rule: peername=$peername, peerhost=$peerhost ".$request->{command}->[0]); - return 0; -} - - # Enable the trace of subroutine calling. # Replace the original subroutine with a trace added subroutine to output more debug trace sub enable_callingtrace{