LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Unexpected curly braces in expect script spawn command & bash suid problem (https://www.linuxquestions.org/questions/programming-9/unexpected-curly-braces-in-expect-script-spawn-command-and-bash-suid-problem-638899/)

slinx 04-30-2008 10:15 AM

Unexpected curly braces in expect script spawn command & bash suid problem
 
Hello,

I'm trying to write an expect script that will login to a group of servers, and copy a specified local user's .ssh/id_dsa.pub key to a remote host's .ssh/authorized_keys file.

I have a few problems with this script:

I want the script to be executable by the zabbix group, but I want the script to run as the zabbix user, so it can read ~zabbix/.ssh/id_dsa.pub

I set the script to SUID, but it still only runs as me. The only way I can get the script to see ~zabbix/.ssh is to sudo run the script.

Code:

-rwsrwsr-x 1 zabbix zabbix 760 2008-04-30 10:54 install_authorized_key.sh
Here is the bash code that parses a file of hostnames, user names (root), and passwords:

Code:

#!/bin/bash -x
me=zabbix
MYHOME=~${me}
echo $MYHOME

echo -e "\nI am $me\n"

while read LINE
do
        if [ ${LINE:0:1} != '#' ]; then
                myhost=`echo "$LINE" | awk '{print $1}'`
                myuser=`echo "$LINE" | awk '{print $2}'`
                mypass=`echo "$LINE" | awk '{print $3}'`
                echo "host=$myhost, user=$myuser"

                echo -e "\nCopy .ssh/id_dsa.pub to remote host\n"
                ./scplogin.exp ${myuser} ${mypass} ${myhost} ${MYHOME}/.ssh/id_dsa.pub /tmp
                ./sshlogin.exp ${myuser} ${mypass} ${myhost} 'cat ~/.ssh/authorized_keys >> /tmp/id_dsa.pub'
                ./sshlogin.exp ${myuser} ${mypass} ${myhost} 'uniq /tmp/id_dsa.pub > ~/.ssh/authorized_keys'
        fi
done < Zabbix-Host_and_Pass.txt

The Expect script contained in scplogin.exp:

Code:

#!/usr/bin/expect  --
#exp_internal 1
set user [lrange $argv 0 0]
set password [lrange $argv 1 1]
set ipaddr [lrange $argv 2 2]
set fromcopy [lrange $argv 3 3]
set tocopy [lrange $argv 4 4]

set timeout 30
spawn scp $fromcopy $user@$ipaddr:$tocopy
expect {
 "*yes/no*"
 { send -- "yes\r" }
 "*?assword:*"
 { send -- "$password\r" }
}

expect eof

The Expect script contained in sshlogin.exp:
Code:

#!/usr/bin/expect -f
set user [lrange $argv 0 0]
set password [lrange $argv 1 1]
set ipaddr [lrange $argv 2 2] 
set scriptname [lrange $argv 3 3]
set arg1 [lrange $argv 4 4]
set arg2 [lrange $argv 5 5]
set arg3 [lrange $argv 6 6]
set timeout -1 
# now connect to remote UNIX box (ipaddr) with given script to execute
#spawn ssh $user@$ipaddr $scriptname $arg1 $arg2 $arg3
spawn -noecho ssh $user@$ipaddr "$scriptname $arg1 $arg2 $arg3"
match_max 100000
expect {
 "*yes/no*"
 { send -- "yes\r" }
 "*?assword:*"
 { send -- "$password\r" }
}
# Look for passwod prompt
#expect "*?assword:*"
# Send password aka $password
#send -- "$password\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof

Now here is the partial output of the code (with -x option in bash).
Where are the extra curly braces { } surrounding my remote commands coming from?
Why am I unable to read the zabbix user's .ssh/id_dsa.pub even when I run the script SUID as root?

Code:

+ ./scplogin.exp root <password> ta999 '~zabbix/.ssh/id_dsa.pub' /tmp
spawn scp ~zabbix/.ssh/id_dsa.pub root@ta999:/tmp
root@ta999's password:
~zabbix/.ssh/id_dsa.pub: No such file or directory
+ ./sshlogin.exp root <password> ta999 'cat ~/.ssh/authorized_keys >> /tmp/id_dsa.pub'
root@ta999's password:
bash: line 1: {cat: command not found
+ ./sshlogin.exp root <password> ta999 'uniq /tmp/id_dsa.pub > ~/.ssh/authorized_keys'
root@ta999's password:
bash: line 1: {uniq: command not found

I need to surround the arguments to sshlogin.exp with ticks to prevent the local shell from expanding variables that should be expanded on the remote host.

Thanks for your help!

ta0kira 05-02-2008 01:47 PM

Scripts never run under suid/sgid for security reasons. It's compiled into the kernel that way. As far as the { problem, you need to put a space after each one so that the shell doesn't take it as part of the command name. You should also precede each } with ; and a space to separate it from the end of the command.
ta0kira


All times are GMT -5. The time now is 12:22 AM.