From eaeb3d611f3dfd1c5ec110d872ac268996124ba5 Mon Sep 17 00:00:00 2001 From: lissav Date: Fri, 3 Apr 2009 15:42:59 +0000 Subject: [PATCH] first installment of code to support ssh key setup for non-root users git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3078 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/DSHCLI.pm | 45 +++--- perl-xCAT/xCAT/Utils.pm | 295 +++++++++++++++++++++++++++++++-------- 2 files changed, 267 insertions(+), 73 deletions(-) diff --git a/perl-xCAT/xCAT/DSHCLI.pm b/perl-xCAT/xCAT/DSHCLI.pm index 3496c1f08..f353b668a 100644 --- a/perl-xCAT/xCAT/DSHCLI.pm +++ b/perl-xCAT/xCAT/DSHCLI.pm @@ -42,7 +42,7 @@ our @dsh_valid_env = ( 'DSH_PATH', 'DSH_SYNTAX', 'DSH_TIMEOUT', 'DSH_REMOTE_PASSWORD', 'DSH_TO_USERID', 'DSH_FROM_USERID', - 'DEVICETYPE', + 'DEVICETYPE', ); select(STDERR); $| = 1; @@ -1044,7 +1044,7 @@ sub fork_fanout_dsh if (my $specified_usr = ($$target_properties{'user'} || $$options{'user'})) { - my $current_usr = getlogin(); + my $current_usr = getpwuid($>); if ($specified_usr ne $current_usr) { delete $$target_properties{'localhost'}; @@ -3707,6 +3707,21 @@ sub parse_and_run_dsh xCAT::DSHCLI->ignoreEnv($options{'ignore_env'}); } + # this was determined in the xdsh client code, because non-root user + # actions must be taken there. + # either -l option or current user + if (!($ENV{'DSH_TO_USERID'})) + { + my $rsp = (); + $rsp->{data}->[0] = "DSH_TO_USERID not setup./n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return; + } + else + { + $options{'user'} = $ENV{'DSH_TO_USERID'}; + } + # # build list of nodes my @nodelist; @@ -3754,7 +3769,10 @@ sub parse_and_run_dsh $options{'command'} = join ' ', @ARGV; + # # -K option just sets up the ssh keys on the nodes and exits + # + if (defined $options{'ssh-setup'}) { @@ -3770,8 +3788,6 @@ sub parse_and_run_dsh # Rules: if (current userid running command) not eq touserid, # the current running userid must be root # - # if not set then the touserid will be defaulted to - # the current running userid. # DSH_REMOTE_PASSWORD env variable must be set to the correct # password for the key update. This was setup in xdsh client # frontend. remoteshell.expect depends on this @@ -3796,8 +3812,8 @@ sub parse_and_run_dsh } - if (!($ENV{'DSH_TO_USERID'})) # id to logon to the node and update the - # keys + if (!($ENV{'DSH_TO_USERID'})) # id to logon to the node and update the + # keys { my $rsp = (); $rsp->{data}->[0] = @@ -3807,24 +3823,21 @@ sub parse_and_run_dsh } - my $current_userid = $ENV{'DSH_FROM_USERID'}; - my $to_userid = $ENV{'DSH_TO_USERID'}; - + my $to_userid = $ENV{'DSH_TO_USERID'}; # if current_userid ne touserid then current_userid # must be root if ( ($current_userid ne $to_userid) - && ($current_userid ne "root")) + && ($current_userid ne "root")) { - my $rsp = (); - $rsp->{data}->[0] = - "When touserid:$to_userid is not the same as the current user:$current_userid. The the command must be run by root id."; - xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); - return; + my $rsp = (); + $rsp->{data}->[0] = + "When touserid:$to_userid is not the same as the current user:$current_userid. The the command must be run by root id."; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return; } - # setting up IB switch ssh, different interface that ssh for # userid on node. Must build special ssh command to be sent # to the IB switch to setup ssh diff --git a/perl-xCAT/xCAT/Utils.pm b/perl-xCAT/xCAT/Utils.pm index 8788c3f03..addbd5691 100644 --- a/perl-xCAT/xCAT/Utils.pm +++ b/perl-xCAT/xCAT/Utils.pm @@ -1063,9 +1063,12 @@ sub getHomeDir { my ($class, $username) = @_; my @user; - if ($username) { + if ($username) + { @user = getpwnam($username); - } else { + } + else + { @user = getpwuid($>); } return $user[7]; @@ -1159,57 +1162,40 @@ sub setupSSH } $::REMOTE_SHELL = "/usr/bin/ssh"; - # make the directory to hold keys to transfer to the nodes - if (!-d $SSHdir) - { - mkdir("/install", 0755); - mkdir("/install/postscripts", 0755); - mkdir("/install/postscripts/_ssh", 0755); - } + # + # if we are running as root + # for non-root users, keys were generated in the xdsh client code + # - # Generate the keys, if they do not already exist my $rsp = {}; # Get the home directory my $home = xCAT::Utils->getHomeDir($from_userid); $ENV{'DSH_FROM_USERID_HOME'} = $home; - # generates new keys, if they do not already exist - xCAT::Utils->runcmd("$::REMOTESHELL_EXPECT -k", 0); - if ($::RUNCMD_RC != 0) - { # error - $rsp->{data}->[0] = "remoteshell.expect failed generating keys."; - xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + if ($from_userid eq "root") + { + # make the directory to hold keys to transfer to the nodes + if (!-d $SSHdir) + { + mkdir("/install", 0755); + mkdir("/install/postscripts", 0755); + mkdir("/install/postscripts/_ssh", 0755); + } + + # generates new keys for root, if they do not already exist + xCAT::Utils->runcmd("$::REMOTESHELL_EXPECT -k", 0); + if ($::RUNCMD_RC != 0) + { # error + $rsp->{data}->[0] = "remoteshell.expect failed generating keys."; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + + } } - # build the perl copy script in $HOME/.ssh/copy.perl - #open(FILE, ">$home/.ssh/copy.perl") - # or die "cannot open file $home/.ssh/copy.perl\n"; - #print FILE "#!/usr/bin/perl - #my (\$name,\$passwd,\$uid,\$gid,\$quota,\$comment,\$gcos,\$dir,\$shell,\$expire) = getpwnam($to_userid); - #my \$home = \$dir; - #umask(0077); - #\$dest_dir = \"\$home/.ssh/\"; - #if (! -d \"\$dest_dir\" ) { - # create a local directory - # \$cmd = \"mkdir -p \$dest_dir\"; - # system(\"\$cmd\"); - # chmod 0700, \$dest_dir; - #} - #`cat /tmp/$to_userid/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1`; - #`cat /tmp/$to_userid/.ssh/authorized_keys2 >> \$home/.ssh/authorized_keys2 2>&1`; - #`cp /tmp/$to_userid/.ssh/id_rsa \$home/.ssh/id_rsa 2>&1`; - #`cp /tmp/$to_userid/.ssh/id_dsa \$home/.ssh/id_dsa 2>&1`; - #`chmod 0600 \$home/.ssh/id_* 2>&1`; - #`rm -f /tmp/$to_userid/.ssh/* 2>&1`; - #rmdir(\"/tmp/$to_userid/.ssh\"); - #rmdir(\"/tmp/$to_userid\");"; - # close FILE; - # chmod 0744, "$home/.ssh/copy.perl"; - - # Replace the perl script with a shell script - # Shell is needed because the nodes may not have Perl installed + # build the shell copy script, needed Perl not always there + # for root and non-root ids open(FILE, ">$home/.ssh/copy.sh") or die "cannot open file $home/.ssh/copy.sh\n"; print FILE "#!/bin/sh @@ -1227,12 +1213,13 @@ rmdir \"/tmp/$to_userid/.ssh\" rmdir \"/tmp/$to_userid\""; close FILE; - chmod 0744, "$home/.ssh/copy.sh"; + chmod 0777,"$home/.ssh/copy.sh"; if (xCAT::Utils->isMN()) { # if on Management Node if ($from_userid eq "root") { + my $rc = xCAT::Utils->cpSSHFiles($SSHdir); if ($rc != 0) { # error @@ -1259,6 +1246,11 @@ rmdir \"/tmp/$to_userid\""; } } } + else + { # from_userid is not root + # build the authorized key files for non-root user + xCAT::Utils->bldnonrootSSHFiles($from_userid); + } } # send the keys to the nodes for root or some other id @@ -1272,12 +1264,12 @@ rmdir \"/tmp/$to_userid\""; } - # Remove $home/.ssh/authorized_keys* - # Easy to remote this code, if we want - # The MN to be able to ssh to itself + #remove $home/.ssh/authorized_keys* + #Easy to remote this code, if we want + #The MN to be able to ssh to itself and nodes to ssh to the MN if (xCAT::Utils->isMN()) { - $cmd = "rm $home/.ssh/authorized_keys*"; + $cmd = "rm $home/.ssh/authorized_keys*"; xCAT::Utils->runcmd($cmd, 0); my $rsp = {}; if ($::RUNCMD_RC != 0) @@ -1326,7 +1318,7 @@ rmdir \"/tmp/$to_userid\""; and for root and puts them in /install/postscripts/_ssh Arguments: - directory path + install directory path Returns: Globals: @@ -1334,7 +1326,7 @@ rmdir \"/tmp/$to_userid\""; Error: Example: - xCAT::Utils->cpSSHFiles; + xCAT::Utils->cpSSHFiles($dir); Comments: none @@ -1355,14 +1347,15 @@ sub cpSSHFiles } my $home = xCAT::Utils->getHomeDir("root"); - my $authorized_keys = "$SSHdir/authorized_keys"; - my $authorized_keys2 = "$SSHdir/authorized_keys2"; if ( !(-e "$home/.ssh/identity.pub") || !(-e "$home/.ssh/id_rsa.pub") || !(-e "$home/.ssh/id_dsa.pub")) { return 1; } + + # copy to install directory + my $authorized_keys = "$SSHdir/authorized_keys"; $cmd = " cp $home/.ssh/identity.pub $authorized_keys"; xCAT::Utils->runcmd($cmd, 0); my $rsp = {}; @@ -1381,6 +1374,8 @@ sub cpSSHFiles xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); } } + + # copy to home ssh directory $cmd = " cp $home/.ssh/identity.pub $home/.ssh/authorized_keys"; xCAT::Utils->runcmd($cmd, 0); my $rsp = {}; @@ -1401,6 +1396,8 @@ sub cpSSHFiles } } + # copy to install directory + my $authorized_keys2 = "$SSHdir/authorized_keys2"; $cmd = "cp $home/.ssh/id_rsa.pub $authorized_keys2"; xCAT::Utils->runcmd($cmd, 0); if ($::RUNCMD_RC != 0) @@ -1418,6 +1415,8 @@ sub cpSSHFiles xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); } } + + # copy to home ssh directory $cmd = "cp $home/.ssh/id_rsa.pub $home/.ssh/authorized_keys2"; xCAT::Utils->runcmd($cmd, 0); if ($::RUNCMD_RC != 0) @@ -1437,6 +1436,7 @@ sub cpSSHFiles } } + # add dsa key to install directory my $rsp = {}; $cmd = "cat $home/.ssh/id_dsa.pub >> $authorized_keys2"; xCAT::Utils->runcmd($cmd, 0); @@ -1456,6 +1456,26 @@ sub cpSSHFiles } } + # add dsa key to home ssh directory + my $rsp = {}; + $cmd = "cat $home/.ssh/id_dsa.pub >> $home/.ssh/authorized_keys2"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "$cmd failed.\n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + return (1); + + } + else + { + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + if (!(-e "$authorized_keys") || !(-e "$authorized_keys2")) { return 1; @@ -1463,6 +1483,169 @@ sub cpSSHFiles return (0); } +#-------------------------------------------------------------------------------- + +=head3 bldnonrootSSHFiles + + Builds authorized_keyfiles for the non-root id + It must not only contain the public keys for the non-root id + but also the public keys for root + + Arguments: + from_userid -current id running xdsh from the command line + Returns: + + Globals: + $::CALLBACK + Error: + + Example: + xCAT::Utils->bldnonrootSSHFiles; + + Comments: + none + +=cut + +#-------------------------------------------------------------------------------- + +sub bldnonrootSSHFiles +{ + my ($class, $from_userid) = @_; + my ($cmd, $rc); + my $rsp = {}; + if ($::VERBOSE) + { + $rsp->{data}->[0] = "Building SSH Keys for $from_userid"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + my $home = xCAT::Utils->getHomeDir($from_userid); + my $roothome = xCAT::Utils->getHomeDir("root"); + + if ( !(-e "$home/.ssh/identity.pub") + || !(-e "$home/.ssh/id_rsa.pub") + || !(-e "$home/.ssh/id_dsa.pub")) + { + return 1; + } + $cmd = " cp $home/.ssh/identity.pub $home/.ssh/authorized_keys"; + xCAT::Utils->runcmd($cmd, 0); + my $rsp = {}; + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "$cmd failed.\n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + return (1); + + } + else + { + chmod 0600, "$home/.ssh/authorized_keys"; + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + + my $rsp = {}; + $cmd = "cp $home/.ssh/id_rsa.pub $home/.ssh/authorized_keys2"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "$cmd failed.\n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + return (1); + + } + else + { + chmod 0600, "$home/.ssh/authorized_keys2"; + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + + my $rsp = {}; + $cmd = "cat $home/.ssh/id_dsa.pub >> $home/.ssh/authorized_keys2"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "$cmd failed.\n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + return (1); + + } + else + { + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + + # add roots keys + # if cannot access, warn and continue + my $rsp = {}; + $cmd = "cat $roothome/.ssh/identity.pub >> $home/.ssh/authorized_keys"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "Warning: Cannot give $from_userid root ssh authority. \n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + + } + else + { + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + my $rsp = {}; + $cmd = "cat $roothome/.ssh/id_rsa.pub >> $home/.ssh/authorized_keys2"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "Warning: Cannot give $from_userid root ssh authority. \n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + + } + else + { + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + + my $rsp = {}; + $cmd = "cat $roothome/.ssh/id_dsa.pub >> $home/.ssh/authorized_keys2"; + xCAT::Utils->runcmd($cmd, 0); + if ($::RUNCMD_RC != 0) + { + $rsp->{data}->[0] = "Warning: Cannot give $from_userid root ssh authority. \n"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); + return (1); + + } + else + { + if ($::VERBOSE) + { + $rsp->{data}->[0] = "$cmd succeeded.\n"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } + } + + return (0); +} + #------------------------------------------------------------------------------- =head3 isServiceNode @@ -3496,12 +3679,11 @@ sub checkCredFiles $rsp->{data}->[0] = "Error: $dir is missing."; xCAT::MsgUtils->message("I", $rsp, $cb); } - my $dir = "/etc/xcat/cert"; if (-d $dir) { - my $file = "$dir/server-cred.pem"; # from getcredentials + my $file = "$dir/server-cred.pem"; # from getcredentials if (!(-e $file)) { @@ -3516,7 +3698,6 @@ sub checkCredFiles $rsp->{data}->[0] = "Error: $dir is missing."; xCAT::MsgUtils->message("I", $rsp, $cb); } - my $dir = "/install/postscripts/ca"; if (-d $dir) @@ -3558,8 +3739,8 @@ sub checkCredFiles my $file = "$dir/ca.pem"; if (-e $file) { - my $file2 = "$dir/*" ; - my $cmd = "/bin/chmod 0644 $file2"; + my $file2 = "$dir/*"; + my $cmd = "/bin/chmod 0644 $file2"; my $outref = xCAT::Utils->runcmd("$cmd", 0); if ($::RUNCMD_RC != 0) {