how to invoke sudo su - user from python code (without password)? Tried -> stdin, stdout, stderr = ssh.exec_command('sudo su - user') - python-3.x

I am writing a script to execute some operation in multiple server.
Where i used to login in server using 1 account, later need to do sudo to switch the account, that is not working.
Tried below cmd
stdin, stdout, stderr = ssh.exec_command('sudo su - user')
Getting below error
stdin, stdout, stderr = ssh.exec_command('sudo su - user')
^
TabError: inconsistent use of tabs and spaces in indentation
.......
ssh = paramiko.SSHClient() `ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())`
ssh.connect(host,username=uname,password=pwd)
stdin, stdout, stderr = ssh.exec_command("hostname")
stdin, stdout, stderr = ssh.exec_command('sudo su - user')
.....
Post ssh connection my script should switch the user.
For e.x-> server abc.com , uname = abhi, password = pwd, user = xyz
Than output will be
login as: abhi
abhi#abc.com's password:
Last login: Thu Apr 4 01:49:06 2019 from abc.com
[abhi#abc.com ~]$ sudo su - xyz
Last login: Thu Apr 4 06:38:36 CDT 2019 on pts/6
[xyz#abc.com ~]$

Related

python3: can't restore the out on console to a file from the program beginning to end& pexpect.EOF issue

Below is my code about using pexpect module achieve SSH logon function.
#!/usr/bin/env python
import pexpect
import sys
#use ssh to logon server
user="inteuser" #username
host="146.11.85.xxx" #host ip
password="xxxx" #password
command="ls -l" #list file on home/user directory
child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))
child.expect('password:')
child.sendline(password)
childlog = open('prompt.log',"ab") # restore prompt log to file prompt.log
__console__ = sys.stdout # make a backup of system output to console
sys.stdout = childlog # print the system output to childlog
child.expect(pexpect.EOF)
childlog.close()
sys.stdout = __console__ # back to the original state of system output
print(child.before) # print the contents before match expect function
after I execute my script
[~/Liaohaifeng]$ python3 ssh_test.py
b' \r\ntotal 69636\r\n-rw-rw-r-- 1 inteuser inteuser 949 Nov 28 02:01
01_eITK_trtest01_CrNwid.log\r\n
[~/Liaohaifeng]$ cat prompt.log
total 69412
-rw-rw-r-- 1 inteuser inteuser 949 Nov 28 02:01 01_eITK_trtest01_CrNwid.log
I think this result is not my expected. when I remove the code child.expect(pexpect.EOF) in my script, the output about print(child.before) can be correct(it should print the content before matching password)
Below is the output after I remove child.expect(pexpect.EOF)
[~/Liaohaifeng]$ python3 ssh_test.py
b"\r\n-------------------------------------------------------------------------------\r\n...
These computer resources are provided for authorized users only. For legal,
\r\n
security and cost reasons, utilization and access of resources are sxx, in\r\n
accordance with approved internal procedures, at any time if IF YOU ARE NOT AN AUTHORIZED USER; PLEASE EXIT IMMEDIATELY...\r\n "
my purpose is print out all the output to a file after executing the script,but the log file still only contains the output of listing directory. So why this happen? could you please help update my script? thank you very much.
You can use the spawn().logfile_read.
[STEP 101] # cat example.py
import pexpect, sys
child = pexpect.spawn('bash --norc')
if sys.version_info[0] <= 2:
# python2
child.logfile_read = open('/tmp/pexpect.log', 'w')
else:
# python3
fp = open('/tmp/pexpect.log', 'w')
child.logfile_read = fp.buffer
child.expect('bash-[.0-9]+[$#] ')
child.sendline('echo hello world')
child.expect('bash-[.0-9]+[$#] ')
child.sendline('exit')
child.expect(pexpect.EOF)
child.logfile_read.close()
[STEP 102] # python3 example.py
[STEP 103] # cat /tmp/pexpect.log
bash-4.4# echo hello world
hello world
bash-4.4# exit
exit
[STEP 104] #
It is a simple question, just adjust code order is OK.
#!/usr/bin/env python
import pexpect
import sys
#use ssh to logon server
user="inteuser" #username
host="146.11.85.xxx" #host ip
password="xxxx" #password
command="ls -l" #list file on home/user directory
child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))
childlog = open('prompt.log',"ab")
child.logfile = childlog
child.expect('password:')
child.sendline(password)
child.expect(pexpect.EOF)
childlog.close()

Linux Service unexpectedly died

Running Ubuntu 17.04, I'd like to have a systemctl service which oversees a main bash script, where three programs (here substituted by dummy script foo_script tagged with an argument) run under an endless loop (because of possible program crashes).
The main script, foo_main.sh, works correctly if called from a command line; but the service I'm trying to set up from it crashes soon.
File foo_script.sh:
#!/bin/bash
echo "FooScripting "$1 >> "foo.d/"$1
File loop.sh:
#!/bin/bash
nLoop=0
prgName=$1
prgArg=$2
echo "<< START of "${prgName} ${prgArg}" loop >>"
while :
do
let nLoop=nLoop+1
echo "<< looping "${prgName} ${prgArg}" >>" ${nLoop}
"./"${prgName} ${prgArg}
sleep 1
done
echo "<< END of "${prgName} ${prgArg}" loop >>"
File foo_main.sh:
#!/bin/bash
echo "foo_main start in "${PWD}
./loop.sh "foo_script.sh" "fb" &
sleep 2
./loop.sh "foo_script.sh" "gc" &
./loop.sh "foo_script.sh" "gb" &
echo "foo_main end"
File /etc/systemd/system/food.service:
[Unit]
Description = Foo Daemon
After = network.target
[Service]
Type = simple
# User = <<USER>>
# PIDFile=/var/food.pid
WorkingDirectory = /home/john/bin
ExecStart = /home/john/bin/foo_main.sh
# ExecStop = killall loop.sh
# ExecReload = killall loop.sh && /home/john/bin/foo_main.sh
# Restart = on-abort
[Install]
WantedBy = multi-user.target
What I obtain from every sudo systemctl status food.service (after a start ofc) is almost the same output
● food.service - Foo Daemon
Loaded: loaded (/etc/systemd/system/food.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Sep 28 14:54:30 john-host systemd[1]: Started Foo Daemon.
Sep 28 14:54:30 john-host foo_main.sh[7376]: foo_main script start in /home/john/bin
Sep 28 14:54:30 john-host foo_main.sh[7376]: << START of foo_script.sh fb loop >>
Sep 28 14:54:30 john-host foo_main.sh[7376]: << looping foo_script.sh fb >> 1
Sep 28 14:54:31 john-host foo_main.sh[7376]: << looping foo_script.sh fb >> 2
Sep 28 14:54:32 john-host foo_main.sh[7376]: foo_main script end
Sep 28 15:24:30 john-host foo_main.sh[7921]: << START of foo_script.sh gb loop >>
Sep 28 15:24:30 john-host foo_main.sh[7921]: << START of foo_script.sh gc loop >>
Sep 28 15:24:30 john-host foo_main.sh[7921]: << looping foo_script.sh gb >> 1
Sep 28 15:24:30 john-host foo_main.sh[7921]: << looping foo_script.sh gc >> 1
Another solution is to use Type=oneshot + RemainAfterExit=yes in your /etc/systemd/system/food.service
Look at https://www.freedesktop.org/software/systemd/man/systemd.service.html to refer onshot type of service.
The service file like following should solve your issue too.
[Unit]
Description = Foo Daemon
After = network.target
[Service]
Type = oneshot
RemainAfterExit=yes
# User = <<USER>>
# PIDFile=/var/food.pid
WorkingDirectory = /home/john/bin
ExecStart = /home/john/bin/foo_main.sh
# ExecStop = killall loop.sh
# ExecReload = killall loop.sh && /home/john/bin/foo_main.sh
# Restart = on-abort
[Install]
WantedBy = multi-user.target
Solved... the service was stopped simply because its execution flow ended with foo_main.sh. It was enough to add something like
# ...
./loop.sh "foo_script.sh" "endless_dummy_loop"
Without background ampersand, at the end of foo_main.sh.
Clearly real services are far different from this, but I got the point now.

Wrong exit status from expect script

I developed this expect script, TELNET_TEST.expect to test a TELNET connection on a remote machine.
This script should connect via telnet on a target machine, wait for the login prompt, send the password and then exit.
This script does work and you can see in example 1 that the script does successfully login via telnet then exit, but something very confusing is going on, (to me).
Why do I get an exit status 1? I believe I should be getting an exit of status 0...
Please let me know why I am getting an exit of status 1? Also, what would I need to change in my script in order to get the exit code I am anticipating?
My expect script:
more TELNET_TEST.expect
#!/usr/bin/expect --
set LOGIN [lindex $argv 0]
set PASSWORD [lindex $argv 1]
set IP [lindex $argv 2]
set timeout 20
spawn telnet -l $LOGIN $IP
expect -re "(Password:|word:)"
send $PASSWORD\r
expect -re "(#|>)"
send exit\r
expect {
timeout {error "incorrect password"; exit 1}
eof
}
catch wait result
set STATUS [ lindex $result 3 ]
exit $STATUS
EXAMPLE1
Running the expect script from my Linux machine I get an exit status 1 even though the telnet login is ok.
./var/TELNET_TEST.expect root pass123 198.23.234.12
.
spawn telnet -l root pass123
Trying 198.23.234.12...
Connected to 198.23.234.12.
Escape character is '^]'.
Digital UNIX (machine1001) (ttyp0)
login: root
Password:
Last login: Mon Jul 14 16:40:15 from 198.23.234.12
Digital UNIX V4.0F (Rev. 1229); Wed Nov 23 15:08:48 IST 2005
****************************************************************************
Wide Area Networking Support V3.0-2 (ECO 3) for Digital UNIX is installed.
You have new mail.
machine1001> Connection closed by foreign host.
[root#LINUX_XOR]# echo $?
1
I see that in the transcript of you session:
machine1001> Connection closed by foreign host.
Exit code 1 is the exit code for "Connection closed by foreign host". That is the "correct" code when the connection is closed by the "other side" (in that case, in response to your exit command).
As far as I can tell, if you want an exit code of 0, you need to enter command mode in your telnet client and send the quit command. That way, the connection is closed by the client not by the foreign host. But is this really more "normal" than the other way?
From the sources of GNU telnet (inetutils-1.9), in the file commands.c:
int
tn (int argc, char *argv[])
{
....
.... many many lines of code here
....
close (net);
ExitString ("Connection closed by foreign host.\n", 1);
return 0;
}
and (utilities.c):
void
ExitString (char *string, int returnCode)
{
SetForExit ();
fwrite (string, 1, strlen (string), stderr);
exit (returnCode);
}

Cron generated by ISPConfig

I have a problem with crontab generated by ISPConfig.
MAILTO=''
* * * * * web9 /usr/bin/wget -q -O /dev/null 'http://inz.isedo.pl/test/cron.php' >/dev/null 2>&1 #inz.isedo.pl
In log, I have a errors:
Feb 16 21:11:01 s /usr/sbin/cron[21697]: (*system*ispc_web9) RELOAD (/etc/cron.d/ispc_web9)
Feb 16 21:11:01 s /USR/SBIN/CRON[23817]: (web9) CMD (/usr/bin/wget -q -O /dev/null 'http://inz.isedo.pl/test/cron.php' >/dev/null 2>&1^I#inz.isedo.pl)
Feb 16 21:11:01 s /USR/SBIN/CRON[23816]: (CRON) error (grandchild #23817 failed with exit status 1)
Does it work from the command line ?
Can you redirect the stdout and stderr to a file (as opposed to null) and pass on the output ?

procmail disregards /etc/group?

sample procmailrc:
SHELL=/bin/bash
LOGFILE=$HOME/procmail.log
VERBOSE=yes
:0
* ^Subject: envdump please$
{
LOG="`id`"
:0
/dev/null
}
/etc/group file contains (note the other usernames are vain attempts to make this work):
someuser:x:504:
s3:x:505:someuser,someotheruser,postfix,postdrop,mail,root
If I run as "someuser" the command id:
[someuser#lixyz-pqr ~]$ id
uid=504(someuser) gid=504(someuser) groups=504(someuser),505(s3)
However when I run procmail by sending an email with the subject "envdump please", the 505/s3 group disappears (this is in procmail.log):
procmail: [17618] Mon Dec 19 17:39:50 2011
procmail: Match on "^Subject: envdump please$"
procmail: Executing "id"
procmail: Assigning "LOG=uid=504(someuser) gid=504(someuser) groups=504(someuser)"
uid=504(someuser) gid=504(someuser) groups=504(someuser)procmail: Assigning "LASTFOLDER=/dev/null"
this server is running Fedora 14 with Postfix 2.7.5
Procmail wasn't installed setuid.
for background, it should look like:
[root#li321-238 postfix]# ls -l /usr/bin/procmail
-rwsr-sr-x. 1 root mail 92816 Jul 28 2009 /usr/bin/procmail
which you can set up via:
chmod ug+s /usr/bin/procmail

Resources