sudo as user within a python program - python-3.x

I am trying to sudo as another user which is generic account in shell , however userid is still same after su , any idea on how to fix it ?
import os,glob,pwd,subprocess,pexpect,getpass
print(getpass.getuser())
try:
var_command = "su user"
var_child = pexpect.spawn(var_command)
i = var_child.expect(["Password:", pexpect.EOF])
if i==0: # send password
print('Login SusccessFul' )
var_child.sendline("password")
var_child.expect(pexpect.EOF)
elif i==1:
print("Got the key or connection timeout")
pass
except Exception as e:
print("Oops Something went wrong buddy")
print(e)
print(getpass.getuser())

Related

authenticate a user from local linux host using python script

I want to authenticate a user from a local linux host using subprocess. I have used this code and i doubt login is the perfect command to do because login command prompts for password and I want to provide the password upfront. login man
If not login then is there any other linux command through which I can authenticate a local user ?
#!/usr/bin/python3
import subprocess
import cgi
print()
cred = cgi.FieldStorage()
username = cred.getvalue("user")
password = cred.getvalue("password")
# print(username)
# print(password)
cmd = f"echo {password} | sudo /usr/bin/login {username}"
# cmd = "ls -la"
print(cmd)
output = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, text=True)
print(output)
This is the output I am getting as of now.
CompletedProcess(args='echo ashu234 | sudo /usr/bin/login ashu', returncode=1, stdout='')
You can use pexpect. Unless you are running your script as root you will need to supply a password to sudo (as you will have to for any answer that uses sudo). To make the script more portable also supply a sudo user name but you could hard code this if using root. This code was written for Ubuntu 21.10 and may need the strings updating for other distributions. I think the code is self-explanatory, you spawn a process, interact with it and expect certain responses during exection.
import pexpect
sudo_user = 'whatever your sudo user name is'
sudo_password = "whatever your sudo user password is"
user_name = "whatever local user name is"
password = "whatever local user password is"
child = pexpect.spawn(f'/usr/bin/sudo /usr/bin/login {user_name}', encoding='utf-8')
child.expect_exact(f'[sudo] password for {sudo_user}: ')
child.sendline(sudo_password)
return_code = child.expect(['Sorry, try again', 'Password: '])
if return_code == 0:
print('Can\'t sudo')
print(child.after) # debug
child.kill(0)
else:
child.sendline(password)
return_code = child.expect(['Login incorrect', '[#\\$] '])
if return_code == 0:
print('Can\'t login')
print(child.after) # debug
child.kill(0)
elif return_code == 1:
print('Login OK.')
print('Shell command prompt', child.after)
For more detail see the docs https://pexpect.readthedocs.io/en/stable/overview.html

LDAP Query in Python3

I have an LDAP Query which is running perfectly fine in my terminal
ldapsearch -h ldap.mygreatcompany.com -D user#mygreatcompany.COM -w "$ldappassword" -b "DC=abc,DC=mygreatcompany,DC=com" -s sub "(mail=user1#mygreatcompany.COM)" sAMAccountName
I want to run this command in python3, I followed other answers from StackOverflow and wrote something like this,
import ldap
l = ldap.initialize('ldap://ldap.mygreatcompany.com')
binddn = "user#mygreatcompany.COM"
pw = #ldappassword
basedn = "DC=abc,DC=mygreatcompany,DC=com"
searchAttribute = ["sAMAccountName"]
searchFilter = "(&(mail=user1#mygreatcompany.COM')(objectClass=*))"
searchScope = ldap.SCOPE_SUBTREE
l.simple_bind_s(binddn, pw)
ldap_result_id = l.search_s(basedn, searchScope, searchFilter, searchAttribute)
#Get result
l.unbind_s()
But Here I am not getting the result from ldap_result_id. Can anybody help what is the correct way to do this query?
Thanks
It turns out that I was not using connection.set_option(ldap.OPT_REFERRALS, 0) in the code and there is some issue in LDAP which automatically chases the referrals internally with anonymous access which fails.
Here is the working code:
def get_user_id(email):
# Seach fiter for user mail
searchFilter = "mail={}".format(email)
try:
# binding to ldap server
connection = ldap.initialize('ldap://yourcompanyhost')
connection.set_option(ldap.OPT_REFERRALS, 0)
connection.protocol_version = ldap.VERSION3
connection.simple_bind_s(binddn, pwd)
# get result
ldap_result_id = connection.search_s(basedn, searchScope, searchFilter, searchAttribute)
# extract the id
saMAccount = ldap_result_id[0][1]["sAMAccountName"][0].decode('utf-8')
except ldap.INVALID_CREDENTIALS:
print("Your username or password is incorrect.")
except ldap.LDAPError as e:
print(e)
except:
print("Data doesn't exist for this user")
connection.unbind_s()
print(get_user_id("user1#mygreatcompany.COM"))

How to execute commands in a remote server using python?

This question is related to this other one: How to use sockets to send user and password to a devboard using ssh
I want to connect to the devboard in order to execute a script. All the outputs of that script I want to send to a Elasticsearch machine.
I can connect to the devboard (see IMAGE below) using my laptop which happens to have Elasticsearch installed. But, when I want to send data to the devboard, the script shows nothing.
What I am doing is:
As soon as you find mendel#undefined-eft:~$ , send the command: cd coral/tflite/python/examples/classification/Auto_benchmark\n
What am I doing wrong?
import paramiko
import os
#Server's data
IP = '172.16.2.47'
PORT = 22
USER = 'mendel'
PASSWORD = 'mendel'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname = IP, port=PORT, username = USER, password = PASSWORD)
channel = ssh.invoke_shell() #to get a dedicated channel
channel_data = str()
host = str()
while True:
if channel.recv_ready(): #is there data to be read?
channel_data += channel.recv(9999).decode("utf-8")
os.system('clear')
print(channel_data)
#ONLY WORKS UNTIL HERE!!!
else:
continue
if channel_data.endswith('mendel#undefined-eft:~$'):
channel.send('cd coral/tflite/python/examples/classification/Auto_benchmark\n')
channel_data += channel.recv(9999).decode("utf-8")
print(channel_data)
IMAGE
EDIT
channel = ssh.invoke_shell() #to get a dedicated channel
channel_data = str()
host = str()
while True:
if channel.recv_ready(): #is there data to be read?
channel_data += channel.recv(9999).decode("utf-8")
os.system('clear')
print(channel_data)
else:
continue
if channel_data.endswith('mendel#undefined-eft:~$ '):#it is good to send commands
channel.send('cd coral/tflite/python/examples/classification/Auto_benchmark\n')
#channel_data += channel.recv(9999).decode("utf-8")
#print(channel_data)
elif channel_data.endswith('mendel#undefined-eft:~/coral/tflite/python/examples/classification/Auto_benchmark$ '):
channel.send('ls -l\n') #python3 auto_benchmark.py')
channel_data += channel.recv(9999).decode("utf-8")
print(channel_data)
I guess you have to change the
if channel_data.endswith('mendel#undefined-eft:~$'):
to
if channel_data.endswith('mendel#undefined-eft:~$ '):
according to your prompt. Please note the space after :~$

wait till command completed in paramiko invoke_shell() [duplicate]

This question already has answers here:
Execute multiple dependent commands individually with Paramiko and find out when each command finishes
(1 answer)
Executing command using "su -l" in SSH using Python
(1 answer)
Closed 5 days ago.
I wanted to wait the given command execution has been completed on remote machines. this case it just executed and return and not waiting till its completed.
import paramiko
import re
import time
def scp_switch(host, username, PasswdValue):
ssh = paramiko.SSHClient()
try:
# Logging into remote host as my credentials
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=username, password=PasswdValue ,timeout=30)
try:
# switcing to powerbroker/root mode
command = "pbrun xyz -u root\n"
channel = ssh.invoke_shell()
channel.send(command)
time.sleep(3)
while not re.search('Password',str(channel.recv(9999), 'utf-8')):
time.sleep(1)
print('Waiting...')
channel.send("%s\n" % PasswdValue)
time.sleep(3)
#Executing the command on remote host with root (post logged as root)
# I dont have any specific keyword to search in given output hence I am not using while loop here.
cmd = "/tmp/slp.sh cool >/tmp/slp_log.txt \n"
print('Executing %s' %cmd)
channel.send(cmd) # its not waiting here till the process completed,
time.sleep(3)
res = str(channel.recv(1024), 'utf-8')
print(res)
print('process completed')
except Exception as e:
print('Error while switching:', str(e))
except Exception as e:
print('Error while SSH : %s' % (str(e)))
ssh.close()
""" Provide the host and credentials here """
HOST = 'abcd.us.domain.com'
username = 'heyboy'
password = 'passcode'
scp_switch(HOST, username, password)
As per my research, it will not return any status code, is there any logic to get the return code and wait till the process completed?
I know this is an old post, but leaving this here in case someone has the same problem.
You can use an echo that will run in case your command executes successfully, for example if you are doing an scp ... && echo 'transfer complete', then you can catch this output with a loop
while True:
s = chan.recv(4096)
s = s.decode()
if 'transfer done' in s:
break
time.sleep(1)

Python code for telnetting DUT needs further optimization

I need to further optimize my code in Python.
I was earlier executing commands on the Device Under Test step by step which was a lot as I also required sleep timers. However I was able to minimize it through a list and calling elements of the list in a for loop:
I need your inputs to further optimize this code:
ConfigListBFD = ['conf t' , 'int Fa1/0' , 'ip address 10.10.10.1 255.255.255.0', 'no shut']
for i in ConfigListBFD:
tn.write(i.encode('ascii') + b"\n")
print (i, "command entered successfully")
time.sleep(2)
Please note: I am telnetting the DUT as ssh is not supported.
i am using this optimized common code for telnet. we can create a common file where you can add this method
import telnetlib
import time
def telnet(host):
user = <username>
password = <password>
try :
tn = telnetlib.Telnet(host)
except :
print("Unable to connect")
sys.exit()
tn.read_until(b"Username:") # read until username prompt
tn.write(user.encode('ascii') + b"\n")
if password:
tn.read_until(b"password:") #read until password prompt
tn.write(password.encode('ascii') + b"\n")
tn.read_until(b"#")
return tn #return telnetlib handle
than import this method to another file, where we write our script

Resources