I need to be able to login into a remote server, switch user and then, do whatever it is required.
I played with ansible and found the "become" tool, so I tried it, after all... it allows dzdo.
My playbook became something like this:
- name: Create empty file
file: path=touchedFile.txt state=touch
become: true
become_method: dzdo
become_user: userid
I ran it and got: "Sorry, user someuser is not allowed to execute '/bin/sh -c echo BECOME-SUCCESS-xklihidlmxpfvxxnbquvsqrgfjlyrsah; /usr/bin/python /tmp/ansible-tmp-1513185770.1-52571838933499/command.py'
Mmm... I thought that maybe it is trying to execute something like this:
dzdo touch touchedFile.txt
Unfortunately, it doesn't work like that in my company. The policy forces us to log in as ourselves and then switch to the required user like this:
dzdo su - userid
I did a bit of research and tried running several commands in a single block, my logic thought that if I switched users first, then everything else would be executed as the other user. My playbook was updated to look like this:
- name: Create empty file
shell: |
dzdo su - userid
touch touchedFile.txt
It failed and I tried this then:
- name: Create empty file
command: "{{ item }}"
with_items:
- dzdo su - userid
- touch touchedFile.txt
And failed again... both approaches create touchedFile.txt but as my user and not the one they should...
Is there a way to do what I need directly with Ansible? Or do I need to start looking for more complex alternatives? In the past I achieved what I'm trying to do now with a script that mainly used "expect", but it was prone to errors... that's why I'm looking for better alternatives.
EDIT 2018-01-08:
I can now use "sudo su - userid
" without the need of a password; but somehow Ansible always expect input from the user, a timeout occurs and my play fails:
fatal: [240]: FAILED! => {
"failed": true,
"msg": "Timeout (12s) waiting for privilege escalation prompt: "
}
One thing I noticed is that Ansible is doing the following:
EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
-o 'IdentityFile="./.ssh/fatCamel"' -o KbdInteractiveAuthentication=no
-o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey
-o PasswordAuthentication=no -o User=login_userid -o ConnectTimeout=10
-o ControlPath=/Users/local_userid/.ansible/cp/446eee77f4
-tt server_url '/bin/sh -c '"'"'sudo su - sudo_userid -u root /bin/sh
-c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-hsyxhtaoxiepyjexaffecfiblmjezopu;
/usr/bin/python /u/users/login_userid/.ansible/tmp/ansible-tmp-1515438271.05-219108659465262/command.py;
rm -rf "/u/users/login_userid/.ansible/tmp/ansible-tmp-1515438271.05-219108659465262/"
> /dev/null 2>&1'"'"'"'"'"'"'"'"' && sleep 0'"'"''
This part is what I caught my attention sudo su - sudo_userid -u root
If I try to run it in the server (copy&paste) it also fails... Why is Ansible adding the "-u root" and is there a way to prevent it from doing so? I will never be granted ROOT access to any server.
Also, I am setting the ansible_become_pass variable to the correct value... but it still fails.
By the way, I check several bugs reported to Ansible (like https://github.com/ansible/ansible/issues/23921), and my error is similar, but their work-arounds don't work with my case.
Any help will be much appreciated!!
I have finally found a work-around for my problem, and I'm sharing this answer in case someone finds it useful.
Ansible become module is great, but for my company it is not working. As I explained in the question, it is adding a "-u root" at the end of the sudo, which makes the whole command to fail.
I was able to make it work with the following snippet:
- name: Create empty file as sudo_userid
command: "sudo su - sudo_userid -c 'touch touchedFile.txt'"
I did several tests, and all of them worked! I didn't even got an Ansible warning!
So, cheers everyone!