Commit e2c5c93d authored by Brian Kroth's avatar Brian Kroth

allow using both an ipmi kg encryption key and user/password

also support alterntive ipmi privilege levels
parent 8243b154
...@@ -55,6 +55,7 @@ use POSIX ":sys_wait_h"; ...@@ -55,6 +55,7 @@ use POSIX ":sys_wait_h";
my $debug = 0; my $debug = 0;
# Always parallelize for now cause we are vulnerable to timeouts with # Always parallelize for now cause we are vulnerable to timeouts with
# unreachable nodes or weird iLO crap. # unreachable nodes or weird iLO crap.
# NOTE: ipmi doesn't appear to be handled if $parallelize isn't set.
my $parallelize = 1; my $parallelize = 1;
# Turn off line buffering on output # Turn off line buffering on output
...@@ -99,7 +100,9 @@ sub iloctrl($$@) { ...@@ -99,7 +100,9 @@ sub iloctrl($$@) {
} }
my ($IP) = $res->fetchrow(); my ($IP) = $res->fetchrow();
$res = DBQueryFatal("select key_role,key_uid,mykey" . # FIXED: Handle multiple rows here like power_ipmi.pm does.
# This is so we can grab a kgkey separately from the user password.
$res = DBQueryFatal("select key_role,key_uid,mykey,key_privlvl" .
" from outlets_remoteauth" . " from outlets_remoteauth" .
" where node_id='$n' and key_type='$type'"); " where node_id='$n' and key_type='$type'");
if (!defined($res) || !$res || $res->num_rows() == 0) { if (!defined($res) || !$res || $res->num_rows() == 0) {
...@@ -107,20 +110,53 @@ sub iloctrl($$@) { ...@@ -107,20 +110,53 @@ sub iloctrl($$@) {
++$exitval; ++$exitval;
next; next;
} }
my ($krole,$kuid,$kkey) = $res->fetchrow(); my ($krole,$kuid,$kkey,$kgkey,$kprivlvl);
while (my $row = $res->fetchrow_hashref()) {
$krole = $row->{'key_role'};
if ($krole eq "ipmi-passwd") {
$kuid = $row->{'key_uid'};
$kkey = $row->{'mykey'};
if ($row->{'key_privlvl'}) {
$kprivlvl = $row->{'key_privlvl'};
}
}
elsif ($krole eq "ipmi-kgkey") {
$kgkey = $row->{'mykey'} =~ s/^0x//;
# NOTE: key_privlvl is currently ignored in case this is the
# only authentication mechanism being used.
}
}
if ($kgkey && $kkey) {
$krole = 'ipmi-kgkey-passwd';
}
elsif ($kkey) {
$krole = 'ipmi-passwd';
}
elsif ($kgkey) {
$krole = 'ipmi-kgkey';
# restore previous behavior
$kkey = $kgkey;
$kgkey = undef;
$kprivlvl = undef;
}
else {
# all of the keys were empty which is weird and the last key_role
# returned from the db wins
}
$ilo_nodeinfo{$n} = [ $n,$IP,$krole,$kuid,$kkey ]; $ilo_nodeinfo{$n} = [ $n,$IP,$krole,$kuid,$kkey,$kgkey,$kprivlvl ];
} }
my $timeout = 30; my $timeout = 30;
if ($parallelize) { if ($parallelize) {
my $coderef = sub { my $coderef = sub {
my ($n,$IP,$krole,$kuid,$kkey) = @{ $_[0] }; my ($n,$IP,$krole,$kuid,$kkey,$kgkey,$kprivlvl) = @{ $_[0] };
my $tret; my $tret;
eval { eval {
if ($type =~ /^ipmi/) { if ($type =~ /^ipmi/) {
$tret = ipmiexec($n,$type,$cmd,$IP,$krole,$kuid,$kkey,$timeout); $tret = ipmiexec($n,$type,$cmd,$IP,$krole,$kuid,$kkey,$kgkey,$kprivlvl,$timeout);
} else { } else {
$tret = iloexec($n,$type,$cmd,$IP,$krole,$kuid,$kkey,$timeout); $tret = iloexec($n,$type,$cmd,$IP,$krole,$kuid,$kkey,$timeout);
} }
...@@ -368,10 +404,10 @@ sub iloexec($$$$$$$;$) { ...@@ -368,10 +404,10 @@ sub iloexec($$$$$$$;$) {
} }
# #
# Arguments: $node_id,$type,$cmd,$IP,$key_role,$key_uid,$key[,$timeout] # Arguments: $node_id,$type,$cmd,$IP,$key_role,$key_uid,$key[,$kgkey,$privlvl,$timeout]
# #
sub ipmiexec($$$$$$$;$) { sub ipmiexec($$$$$$$;$$$) {
my ($node_id,$type,$cmd,$IP,$key_role,$key_uid,$key,$timeout) = @_; my ($node_id,$type,$cmd,$IP,$key_role,$key_uid,$key,$kgkey,$privlvl,$timeout) = @_;
if ($debug) { if ($debug) {
print "ipmiexec called with (" . join(',',@_) . ")\n"; print "ipmiexec called with (" . join(',',@_) . ")\n";
...@@ -407,12 +443,15 @@ sub ipmiexec($$$$$$$;$) { ...@@ -407,12 +443,15 @@ sub ipmiexec($$$$$$$;$) {
if ($key_role eq 'ipmi-passwd') { if ($key_role eq 'ipmi-passwd') {
$usekey = 0; $usekey = 0;
} elsif ($key_role eq 'ipmi-kgkey-passwd') {
$usekey = 1;
} elsif ($key_role eq 'ipmi-kgkey') { } elsif ($key_role eq 'ipmi-kgkey') {
if ($type eq 'ipmi15') { if ($type eq 'ipmi15') {
warn "Cannot use key_role 'kgkey' for IPMI 1.5!"; warn "Cannot use key_role 'kgkey' for IPMI 1.5!";
return -21; return -21;
} }
$usekey = 1; $usekey = 1;
$kgkey = $key;
} else { } else {
warn "Unsupported IPMI key_role $key_role!"; warn "Unsupported IPMI key_role $key_role!";
return -14; return -14;
...@@ -421,13 +460,14 @@ sub ipmiexec($$$$$$$;$) { ...@@ -421,13 +460,14 @@ sub ipmiexec($$$$$$$;$) {
# XXX IPMI takes about 40 seconds to timeout and doesn't # XXX IPMI takes about 40 seconds to timeout and doesn't
# have an option to control?! # have an option to control?!
my $ipmicmd = "ipmitool -I $iface -H $IP -U $key_uid -E -K power $cmd"; my $privlvl_args = ($key_privlvl) ? " -L $key_privlvl" : '';
my $ipmicmd = "ipmitool -I $iface -H $IP -U $key_uid $privlvl_args -E -K power $cmd";
print "*** Executing '$ipmicmd', output:\n" print "*** Executing '$ipmicmd', output:\n"
if ($debug > 1); if ($debug > 1);
# Set the password and key environment variables # Set the password and key environment variables
$ENV{'IPMI_PASSWORD'} = substr($key, 0, $pwdmax); $ENV{'IPMI_PASSWORD'} = substr($key, 0, $pwdmax);
$ENV{'IPMI_KGKEY'} = $key $ENV{'IPMI_KGKEY'} = $kgkey
if ($usekey); if ($usekey);
my $output = `$ipmicmd 2>&1`; my $output = `$ipmicmd 2>&1`;
...@@ -447,3 +487,7 @@ sub ipmiexec($$$$$$$;$) { ...@@ -447,3 +487,7 @@ sub ipmiexec($$$$$$$;$) {
} }
1; 1;
# vim: set ft=perl et sw=4 ts=8:
# Not sure what the (no)et sw=? ts=? rules should be in this file - they're kind of mixed.
# Seems like a leading tab in some places and then 4 expanded spaces. Maybe et sw=4 ts=8.
...@@ -81,7 +81,7 @@ sub new($$$;$) { ...@@ -81,7 +81,7 @@ sub new($$$;$) {
$self->{KGKEY} = ""; $self->{KGKEY} = "";
# Fetch authentication credentials from the DB. # Fetch authentication credentials from the DB.
my $res = DBQueryFatal("select key_role,key_uid,mykey" . my $res = DBQueryFatal("select key_role,key_uid,mykey,key_privlvl" .
" from outlets_remoteauth" . " from outlets_remoteauth" .
" where node_id='$devicename'". " where node_id='$devicename'".
" and key_type='$KTYPE'"); " and key_type='$KTYPE'");
...@@ -93,6 +93,9 @@ sub new($$$;$) { ...@@ -93,6 +93,9 @@ sub new($$$;$) {
if ($role eq "ipmi-passwd") { if ($role eq "ipmi-passwd") {
$self->{USERNAME} = $row->{'key_uid'}; $self->{USERNAME} = $row->{'key_uid'};
$self->{PASSWORD} = $row->{'mykey'}; $self->{PASSWORD} = $row->{'mykey'};
if ($row->{'key_privlvl'}) {
$self->{PRIVLVL} = $row->{'key_privlvl'};
}
} }
elsif ($role eq "ipmi-kgkey") { elsif ($role eq "ipmi-kgkey") {
$self->{KGKEY} = $row->{'mykey'} =~ s/^0x//; $self->{KGKEY} = $row->{'mykey'} =~ s/^0x//;
...@@ -106,6 +109,9 @@ sub new($$$;$) { ...@@ -106,6 +109,9 @@ sub new($$$;$) {
} elsif ($self->{DEVICETYPE} eq "ipmi-ms") { } elsif ($self->{DEVICETYPE} eq "ipmi-ms") {
$self->{IPMICMD} .= " -I lanplus"; $self->{IPMICMD} .= " -I lanplus";
} }
if ($self->{PRIVLVL}) {
$self->{IPMICMD} .= " -L $self->{PRIVLVL}";
}
# Do a quick query, to see if it works # Do a quick query, to see if it works
system("$self->{IPMICMD} power status >/dev/null 2>\&1"); system("$self->{IPMICMD} power status >/dev/null 2>\&1");
...@@ -274,3 +280,7 @@ sub _get_msaddr($$) { ...@@ -274,3 +280,7 @@ sub _get_msaddr($$) {
# End with true # End with true
1; 1;
# vim: set ft=perl et sw=4 ts=8:
# Not sure what the (no)et sw=? ts=? rules should be in this file - they're kind of mixed.
# Seems like a leading tab in some places and then 4 expanded spaces. Maybe et sw=4 ts=8.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment