Red Hat Satellite engineering is moving the tracking of its product development work on Satellite to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "Satellite project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs will be migrated starting at the end of May. If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "Satellite project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/SAT-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1955385 - Privilege escalation defined inside ansible playbook tasks is not working when executing the playbook via Remote Execution in Satellite 6
Summary: Privilege escalation defined inside ansible playbook tasks is not working whe...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Satellite
Classification: Red Hat
Component: Ansible - Configuration Management
Version: 6.9.0
Hardware: x86_64
OS: All
high
high
Target Milestone: 6.11.0
Assignee: Adam Ruzicka
QA Contact: Sam Bible
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-04-30 02:22 UTC by Sayan Das
Modified: 2024-12-20 19:59 UTC (History)
7 users (show)

Fixed In Version: tfm-rubygem-foreman_ansible-7.0.0
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-07-05 14:28:51 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Foreman Issue Tracker 33602 0 Normal New Foreman ansible always sets ansible_effective_user var 2021-09-30 10:14:10 UTC
Red Hat Knowledge Base (Solution) 6307031 0 None None None 2021-09-03 14:39:22 UTC
Red Hat Product Errata RHSA-2022:5498 0 None None None 2022-07-05 14:29:21 UTC

Description Sayan Das 2021-04-30 02:22:43 UTC
Description of problem:

Privilege escalation defined inside ansible playbook tasks is not working when executing the playbook via Remote Execution in Satellite 6


Version-Release number of selected component (if applicable):

Satellite 6.9 and Satellite 6.7.5 [ The customer has tested on Satellite 6.8 ]


How reproducible:
Always


Steps to reproduce:


1. Register host.example.com with satellite.example.com

2. On the host.example.com as root user,

   # useradd rexuser
   # echo password@123 | passwd rexuser --stdin
   # echo "rexuser   ALL=NOPASSWD:   ALL" | tee -a /etc/sudoers.d/rexuser
   # useradd testing
   # echo password@123 | passwd testing --stdin
   # su - testing -c "whoami" 


3. From Satellite CLI,

   # ssh-copy-id -i ~foreman-proxy/.ssh/id_rsa_foreman_proxy.pub rexuser.com


4. From Satellite UI,

--> Administer --> Settings --> RemoteExecution --> Set "SSH User" as rexuser and "Effective User" as root

--> Hosts --> Job Templates --> Create --> Here create a template by name "Verify_user" with following content and save it under "Ansible Playbook" category

###
---
- name: Test Play
  hosts: all
  gather_facts: false
  tasks:
  
    - name: Check current user
      command: bash -c "whoami"
      register: def_user
      
    - debug: var=def_user.stdout
    
    - name: Check become user
      command: bash -c "whoami"
      become: true
      become_user: testing
      register: bec_user
      
    - debug: var=bec_user.stdout
###


--> Monitor --> Jobs --> New Job --> Select "Ansible Playbooks" --> Select "Verify_user" template --> in search query "host.example.com" and resolv --> Run the job


Actual Results:

The bec_user var should store "testing" as its output but it will store "root" only i.e. I wanted to execute the command for the second task as "testing" user but it keeps on executing as "root"


   4:
TASK [Check current user] ******************************************************
   5:
changed: [host.example.com]
   6:

   7:
TASK [debug] *******************************************************************
   8:
ok: [host.example.com] => {
   9:
    "def_user.stdout": "root"
  10:
}
  11:

  12:
TASK [Check become user] *******************************************************
  13:
changed: [host.example.com]
  14:

  15:
TASK [debug] *******************************************************************
  16:
ok: [host.example.com] => {
  17:
    "bec_user.stdout": "root"
  18:
}



Expected results:


   4:
TASK [Check current user] ******************************************************
   5:
changed: [host.example.com]
   6:

   7:
TASK [debug] *******************************************************************
   8:
ok: [host.example.com] => {
   9:
    "def_user.stdout": "root"
  10:
}
  11:

  12:
TASK [Check become user] *******************************************************
  13:
changed: [host.example.com]
  14:

  15:
TASK [debug] *******************************************************************
  16:
ok: [host.example.com] => {
  17:
    "bec_user.stdout": "testing"
  18:
}



Additional Information:

None

Comment 3 Aslak 2021-08-26 11:11:02 UTC
Hi. We are experiencing this bug with Satellite 6.9.2.1.

A simple playbook that connects to a client and runs a whoami with become: yes and become_user: <username> returns the correct value (username) if we run it in terminal with ansible-playbook.

The same playbook when we run it in satellite returns "root".

Support case has been submitted (03019829).

Comment 4 Adam Ruzicka 2021-08-27 06:56:30 UTC
This is an ansible thing. If you set effective user, that user gets set as ansible_effective_user host variable. This variable (if set) takes precedence over all local become_user stanzas.

Either you can use different connection and effective user and live with the fact that you can't then override the effective user locally inside the playbook.
Alternatively you most likely could connect with effective user unset and then handle all user switching yourself inside the playbook.

Comment 5 Aslak 2021-08-27 07:03:55 UTC
So I should be able to "fix" this by setting (in Satellite) Effective User under remote execution in Settings to Empty? As long as I keep root as SSH-user, my existing playbooks that need to run as root will still run ok?



Effective User	Empty	Default user to use for executing the script. If the user differs from the SSH user, su or sudo is used to switch the user.
SSH User	root	Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user.

Comment 6 Aslak 2021-08-27 07:49:48 UTC
I tried removing the value for Effective user in Satellite and rerun the playbook, but it still insists on running everything as root.

Here is my playbook, the whoami check returns "root".

- name: Kill and restart x0vncserver
  gather_facts: true
  hosts: all
  become: yes
  become_user: foo
  
  tasks:
    - name: Kill any running vnc process
      command: killall x0vncserver
      ignore_errors: yes
    
    - name: Who am I?
      command: whoami
      register: username
    - debug: var=username
      
    - name: Restart x0vncserver
      shell: x0vncserver -display :0 -SecurityTypes None -SendCutText=false -AcceptCutText=false -AcceptPointerEvents=false -AcceptKeyEvents=false -AlwaysShared=1 </dev/null >/dev/null 2>&1 &

Comment 7 Adam Ruzicka 2021-08-27 13:23:40 UTC
Ok, turns out we are always setting the ansible_become_user host variable, even if the effective user is the same as the connection user. This one is on us, hopefully it should be a simple fix. 

However it won't address the original issue for this bz (different connection and effective user, then changing the user once more with stanza in the playbook).

Comment 9 Sayan Das 2021-08-29 15:20:38 UTC
(In reply to Adam Ruzicka from comment #7)
> Ok, turns out we are always setting the ansible_become_user host variable,
> even if the effective user is the same as the connection user. This one is
> on us, hopefully it should be a simple fix. 
> 
> However it won't address the original issue for this bz (different
> connection and effective user, then changing the user once more with stanza
> in the playbook).

Hello Adam,

Thanks for your prompt responses here.

Would you need a different BZ for this one ?

And Would fixing above, allow us to proceed with this part?
~~
Alternatively, you most likely could connect with effective user unset and then handle all user switching yourself inside the playbook.
~~


-- Sayan

Comment 10 Adam Ruzicka 2021-08-31 12:42:09 UTC
Hi, i did a little bit more digging around this and it looks like we may have a way out.

# inventory
localhost ansible_become=true ansible_become_user=aruzicka

This is in line with what satellite does. It sets ansible_become_user variable for each of the hosts, no matter if it is different from the connection user or not.

# playbook.yml
---
- hosts: all
  tasks:
    - command: whoami
      become: yes
      become_user: root

Run with ansible-playbook -c local -i inventory. In this case, the ansible_become_user from the inventory takes precedence over the one set as become_user in the task. However, we can work around this by using a slightly different syntax in the playbook.

# playbook.yml
---
- hosts: all
  tasks:
    - command: whoami
      become: yes
      vars:
        ansible_become_user: root

Here the variable definition takes precedence over the one defined in host variables. This should work even now without any code changes. After code changes for #7, this will still be needed when connection user is different from effective user and another user switch needs to happen inside the playbook. 

> Would you need a different BZ for this one ?

We could reword this BZ, but it would be cleaner if we had a new bz just for the behaviour when connection_user is the same as effective user.

> And Would fixing above allow us to proceed with this part?

Yes, it should. It should cover the cases when the effective user is either unset or the same as the connection user. In those scenarios, in-playbook user switching should work after that bit is fixed.

Comment 11 Sayan Das 2021-09-02 09:05:00 UTC
Hello,

I have tested with following code and that works.

---
- name: Test Play
  hosts: all
  gather_facts: false
  tasks:
  
    - name: Check current user
      command: whoami
      register: def_user
      
    - debug: var=def_user.stdout
    
    - name: Check current user
      command: whoami
      register: def_user2
      vars:
        ansible_become_user: rexuser
      
    - debug: var=def_user2.stdout


The second var displayed the output rexuser which means the privilege escalation for that task worked. This seems to be a very valid solution from ansible point of view and reduces the complexity of what we were trying to earlier.


Now come back to the other problem which you had identified for the behavior when connection_user is the same as effective user, I will test something real quick and then get back to you with a confirmation whether to re-word this BZ or maybe I will open a new BZ and let you know.


Thanks again for finding out the solution.

Comment 12 Aslak 2021-09-02 10:25:38 UTC
Thanks Adam, I can confirm that this workaround seems to do the trick. I've tried it in two playbooks with good results.

Comment 13 Sayan Das 2021-09-02 15:00:16 UTC
So I am on satellite 6.9.4-1 now.


# hammer settings list --search "effective_user or ssh_user"
-----------------------------------------|-------------------------|---------|---------------------------------------------------------------------------------
NAME                                     | FULL NAME               | VALUE   | DESCRIPTION                                                                     
-----------------------------------------|-------------------------|---------|---------------------------------------------------------------------------------
remote_execution_effective_user          | Effective User          |         | Default user to use for executing the script. If the user differs from the SS...
remote_execution_effective_user_method   | Effective User Method   | sudo    | What command should be used to switch to the effective user. One of ["sudo", ...
remote_execution_effective_user_password | Effective user password | *****   | Effective user password                                                         
remote_execution_ssh_user                | SSH User                | ansible | Default user to use for SSH.  You may override per host by setting a paramete...
-----------------------------------------|-------------------------|---------|---------------------------------------------------------------------------------


The playbook executed as Job template:

###
---
- name: Test Play
  hosts: all
  gather_facts: false
  become: true
  become_user: root
  tasks:
  
    - name: Check current user
      command: bash -c "whoami"
      register: def_user
      
    - debug: var=def_user.stdout
    
    - name: Check become user
      command: bash -c "whoami"
      become: true
      become_user: rexuser
      register: bec_user
      
    - debug: var=bec_user.stdout
###

Results:


   1:

   2:
PLAY [Test Play] ***************************************************************
   3:

   4:
TASK [Check current user] ******************************************************
   5:
changed: [clienthost.example.com]
   6:

   7:
TASK [debug] *******************************************************************
   8:
ok: [clienthost.example.com] => {
   9:
    "def_user.stdout": "root"
  10:
}
  11:

  12:
TASK [Check become user] *******************************************************
  13:
changed: [clienthost.example.com]
  14:

  15:
TASK [debug] *******************************************************************
  16:
ok: [clienthost.example.com] => {
  17:
    "def_user.stdout": "rexuser"
  18:
}
  19:
PLAY RECAP *********************************************************************
  20:
clienthost.example.com : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  21:
Exit status: 0



As you can see, without doing anything unnecessary, I only changed two things and the privilege escalation works fine inside playbook.

* Unset the value of effective user --> hammer settings set --name remote_execution_effective_user --value ''

* Control the entire become_user part inside playbook itself.


I also checked the job task and I can confirm that ansible_become_user cannot be seen there. These are the stuff that I can see there.

        ansible_connection: ssh
        ansible_ssh_private_key_file: "~/.ssh/id_rsa_foreman_proxy"
        ansible_winrm_server_cert_validation: validate
        ansible_user: rexuser
        ansible_become_method: sudo
        ansible_port: '22'
        ansible_host: clienthost.example.com
        ansible_ssh_port: '22'
        ansible_ssh_user: ansible
        remote_execution_ssh_user: rexuser
        remote_execution_effective_user_method: sudo



And as soon as I set back the "Effective User" I get back my original behavior. So I guess, I will not be needing to file a Bug here and probably go for a KCS. Anyway, Do you know if something related to this was fixed on Sat 6.9.4 already ?

I am yet to check on 6.10 but, What's your opinion here on my latest observation ?

Comment 14 Sayan Das 2021-09-02 15:02:49 UTC
@Adam, c#13 was for you. 

Let me know what do you think about that behavior. I guess that is what you were trying to suggest initially.

Comment 15 Adam Ruzicka 2021-09-03 06:51:34 UTC
> Do you know if something related to this was fixed on Sat 6.9.4 already ?

I don't think there were any changes in this area and it looks like it works the same way on 6.10. Could you confirm when you get your hands on a 6.10 machine? Not sure why it didn't work for Aslak in #5 and #6.

@Aslak In #5 you described your settings, however those can be overriden as parameters on global/per-organization/per-hostgroup/per-host level. Is it possible that there was a parameter which was intervening?

> I guess that is what you were trying to suggest initially.

Yes, although I admit I could have worded it better.

Anyway, the point from #7 still holds. If I as a user set a connection user and effective user to the value, I'd expect to be free to do what I please in the playbook and more importantly I'd expect this to work out of the box without having to fiddle with settings.

Comment 16 Sayan Das 2021-09-03 07:14:46 UTC
@Adam, 

Tested on satellite-6.10.0-0.8.beta.el7sat.noarch and exact same results as c#13 .. Works great with effective_user unset. 

I would have to assume the same thing i.e. for Aslak, the variable or parameter remote_execution_effective_user is probably set somewhere as Host\Hostgroup or as Global Parameter I guess.

Comment 17 Aslak 2021-09-04 12:45:47 UTC
THere's no host or global parameter set, however, I "unset" the effective user by clearing the field in Satellite GUI and saving, not by a hammer command, so that could explain it.

Comment 18 Bryan Kearney 2021-11-04 13:50:30 UTC
Moving this bug to POST for triage into Satellite since the upstream issue https://projects.theforeman.org/issues/33602 has been resolved.

Comment 21 Sam Bible 2022-04-13 19:20:16 UTC
Tested on: 6.11 - 3

Following the same reproduction steps as in the original BZ, I end up with the same output - 
TASK [Check current user] ******************************************************
   7:
changed: [dhcp-3-152.vms.sat.rdu2.redhat.com]
   8:

   9:
TASK [debug] *******************************************************************
  10:
ok: [dhcp-3-152.vms.sat.rdu2.redhat.com] => {
  11:
    "def_user.stdout": "root"
  12:
}
  13:

  14:
TASK [Check become user] *******************************************************
  15:
changed: [dhcp-3-152.vms.sat.rdu2.redhat.com]
  16:

  17:
TASK [debug] *******************************************************************
  18:
ok: [dhcp-3-152.vms.sat.rdu2.redhat.com] => {
  19:
    "bec_user.stdout": "root"
  20:
}

6.11 snap 3 is running rubygem-foreman_ansible-7.0.3-1.el8sat.noarch, so the fix should be in.

Comment 22 Adam Ruzicka 2022-04-19 07:38:35 UTC
I inspected Sam's machine. In the test jobs, there seemed to be both connection user and effective user set, but they were different. In that case, the effective user takes precedence over anything that is set in the playbook itself. See #4. With that in mind, I'd say #21 is expected given the environment it was run in.

Comment 23 Sam Bible 2022-05-05 15:48:36 UTC
Verified on:
Sat 6.11 - 18

Steps to Verify:
1) Create a host
2) Setup a user on that host as described in comment 1
3) Create a playbook as described in comment 1
4) Set the SSH user to the created user, and unset the Effective user
5) Run the playbook

Expected results:
In the playbook, becomeuser functions as expected.

Actual results:
Expected results:
In the playbook, becomeuser functions as expected.

Comment 26 errata-xmlrpc 2022-07-05 14:28:51 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Moderate: Satellite 6.11 Release), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2022:5498


Note You need to log in before you can comment on or make changes to this bug.