How to pass username/password into ambari-server sync-ldap command - shell

I am trying to run a playbook with sync ldap command :
ambari-server sync-ldap --all
The thing is, after the executing of the command, it asks for username and then password.
Is there anyway to pass the username and password automatically from echo or using a script shell, without having to pass it manually ?

Check out expect.
An simple example is to use the following script.
#!/usr/bin/expect -f
ambari-server sync-ldap --all
# wait until the prompt shows "enter username". Change this to adapt to your application.
expect "enter username"
send "your_username\r"
# wait until the prompt shows "password: ". Change this to adapt to your application.
expect "password: "
send "yourPAssWoRD\r"
interact
Disclaimer: I have never used ambari-server command before.

try with below script
# cat /tmp/ambari-server-sync-ldap-unattended.sh
#!/usr/bin/expect
set timeout 20
spawn /usr/sbin/ambari-server sync-ldap --groups=/etc/ambari-server/ambari-groups.csv
expect "Enter Ambari Admin login:" { send "admin\n" }
expect "Enter Ambari Admin password:" { send "notTheRealPasswordOfCourse\n" }
interact

Related

Enter sudo password while in expect script

I have an expect code inside bash script, something like this
env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
set timeout -1
spawn ./another_script.sh
expect {
"Input 1" { send -- "$env(input1)\r";exp_continue }
"Input 2" { send -- "$env(input2)\r";exp_continue }
eof
}
EOS
During the execution of another_script.sh I am prompted to enter sudo password, but I'm not able since I'm stil in expect.
What can I do in order for me to be able to enter the sudo password and for the script to continue running after that?
I don't want to save the password in the script and then pass it to expect, but I want to be able to type it in.
The answer from Donal Fellows is the right way to go, but for completeness here is the interact solution you were trying for. The command to use is
expect {
"Input 1" { send -- "$env(input1)\r"; exp_continue }
"Input 2" { send -- "$env(input2)\r"; exp_continue }
"password for" { stty -echo
interact -u tty_spawn_id -o "\r" return
stty echo
exp_continue }
eof
}
The problem you have is that you are running expect with the script on stdin, so interact has trouble unless you use -u tty_spawn_id to get it to work with /dev/tty and the user. You need to set the echo on/off on this tty explicitly, as sudo will only have done it on the pty between the spawned command and expect.
The standard way of handling an event like this is to watch for a prompt for the sudo password, supply it, and then continue. But with a long-running script, you'll want to cache the password within the expect script so that you don't have to go back to the user for it several times over a few hours. Indeed, for usability you probably need to ask for the password up front rather than waiting until the underlying system needs it.
Fortunately, expect includes support for stty so it's an easy thing to add.
env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
# Prompt for password, cribbed/converted from example on expect(1) manpage
stty -echo
send_tty "sudo password: "
expect_tty -re "(.*)\n"
send_tty "\n"
set password $expect_out(1,string)
stty echo
# Rest of the script, with clause for sending the password at the right time
set timeout -1
spawn ./another_script.sh
expect {
"Input 1" { send -- "$env(input1)\r"; exp_continue }
"Input 2" { send -- "$env(input2)\r"; exp_continue }
"assword: " { send -- "$password\r"; exp_continue }
eof
}
EOS
From man sudo: The sudoers policy caches credentials for 15 minutes, unless overridden in sudoers(5).
With that, call sudo -v before calling expect. It checks for the credentials, and if they aren't cached, it will ask for the root password. That way you can enter them before expect and later sudo commands don't need to ask again.
for what you comment I think you have it in cron. In that case you would neeed to run the script as sudo. you can just call it in the sudo crontab. you can access it by running sudo crontab -e

Why does my expect script exit prematurely?

Here is my except script:
#!/usr/bin/expect
spawn openvpn --config peter.ovpn
expect -exact "Enter Private Key Password: "
send -- "mypassword\r"
I run it and see OpenVPN ask for my client password. But the script exits, apparently without ever sending the password. When I try with an incorrect password it is the same (no incorrect password message). It is also exactly the same result if I delete the send -- "mypassword\r" line from the end of the expect script.
It's my first expect script so probably my syntax is wrong. Or could it be that OpenVPN is kicking me off for using an expect script to connect?
Your syntax is fine. The problem is the script has no more commands to run after you send the password, so the expect script exits and that kills openvpn.
What do you need to do after you send the password?
If you just need to keep openvpn running, then do this:
#!/usr/bin/expect
spawn openvpn --config peter.ovpn
expect -exact "Enter Private Key Password: "
send -- "mypassword\r"
set timeout -1
expect eof
-1 means "infinite", and expect eof means you are waiting for the spawned process to exit before the expect script can exit.

forticlientssl-vpn_cli end before verification token is passed using expect

I would like to automate login to my VPN with forticlient. I automatically pass password with expect command. After right password I receive verification token but before I write it to console, the script ends. This is my script:
#!/bin/bash
/usr/bin/expect << EOF
spawn /opt/forticlient-sslvpn/64bit/forticlientsslvpn_cli --server server.com:443 --vpnuser user --keepalive
expect "Password for VPN:"
send "MyPaSsWoRd\r"
expect "Would you like to connect to this server? (Y/N)"
send "Y\r"
expect "A FortiToken code is required for SSL-VPN login authentication."
expect EOF
How can I read Token from stdin, or is there better way how to solve this issue? Is there a way how to create some configuration file where will be server address, user, password, etc and insert it to forticlient_cli?
When you say "the script ends", I assume it times out after about 20 seconds
This is what I think you're asking:
expect "A FortiToken code is required for SSL-VPN login authentication."
send_user "Enter the token: "
gets stdin token
send -- "$token\r"
# then, you interact with the connection ...
I could not to solve my porblem with expect so I used python3 lib pexpect. This is my result which works fine:
import pexpect
child = pexpect.spawn('/opt/forticlient-sslvpn/64bit/forticlientsslvpn_cli --server server.com:443 --vpnuser user --keepalive', encoding='utf-8')
child.expect('Password for VPN:')
child.sendline('PaSsWoRd')
child.expect('Would you like to connect to this server\? \(Y\/N\)')
child.sendline('Y')
child.interact()
child.kill(1)
print('is alive:', child.isalive())

Sending password with expect in shell script

I have a small problem. I'm trying to scp to a remote server and have the script enter my password for me. In short, I'm trying to automate the password entry process in the prompt. However, every time I run my code I keep receiving the prompt to enter my password. Please help. Thank you.
#!bin/expect
for dest in $(<destinations.txt); do
set pass "password"
scp -r ${dest}:/home/car02fv/QATest.txt /home/car02fv/
expect "car02fv#goxsd1703's password:"
send pass
interact
done

Handle multiple statements in an Expect script

I am new to Expect scripting.
I wrote an Expect script for ssh in a Linux machine, where I am facing a problem in ssh'ing to different Linux machines. Below I have copied the script.
!/usr/local/bin/expect
set LinuxMachine [lindex $argv 0]
spawn ssh root#$LinuxMachine
expect "root#$LinuxMachine's password:"
send "root123\n"
expect "[root#Client_FC12_172_85 ~]#"
send "ls"
interact
When I supply 10.213.172.85 from command line the expect in the 4th line, it reads as "root#10.213.172.85's password:" and logs in successfully
But some Linux will expect
The authenticity of host '10.213.172.108 (10.213.172.108)' can't be established.
RSA key fingerprint is da:d0:a0:e1:d8:7a:23:8b:c7:d8:40:8c:b2:b2:9b:95.
Are you sure you want to continue connecting (yes/no)
In this case the script will not work.
How can I have two Expect statements in one Expect command?
You can use exp_continue in such a case:
expect {
"Are you sure you want to continue connecting (yes/no)" {
send "yes\r"
exp_continue
}
"root#$LinuxMachine's password:" {
send "root123\r"
expect "[root#Client_FC12_172_85 ~]#"
send "ls\r"
interact
}
}
In the above, the Expect block waits for either the yes/no question OR the prompt for password. If the latter, it moves on with providing password, expecting prompt, sending ls command and giving control back.
If the former, it will answer 'yes' and repeat the expect block, ready to find the prompt for a password (or even the yes/no question again, for that matter - not that you will need that).
I would also include some timeouts with meaningful messages in case some expect option does not match as expected, but the above should work.
As a side comment, you don't want to set a root password in a script... I recommend using ssh key authentication.
We like to call it "long log in". There are ssh options that don't check the host keys:
send -- "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no username#host\n"
expect {
"Password" {
send -- "$passwd\n"
}
Part of the Bash script that calls on the expect sets the password:
echo -n "Enter LDAP password: "
read -s passwd
echo

Resources