Add a 'machinectl shell' become_method (#39826)

* Add a 'machinectl shell' become_method

* docs: add explanations for the machinectl become_method

* docs: machinectl become_method: specify this part is specific to Linux+systemd setups
pull/40720/head
Antoine Pietri 7 years ago committed by Adam Miller
parent 174d7f8ea2
commit 313a46744d

@ -11,7 +11,7 @@ Ansible can use existing privilege escalation systems to allow a user to execute
Become Become
====== ======
Ansible allows you to 'become' another user, different from the user that logged into the machine (remote user). This is done using existing privilege escalation tools such as `sudo`, `su`, `pfexec`, `doas`, `pbrun`, `dzdo`, `ksu`, `runas` and others. Ansible allows you to 'become' another user, different from the user that logged into the machine (remote user). This is done using existing privilege escalation tools such as `sudo`, `su`, `pfexec`, `doas`, `pbrun`, `dzdo`, `ksu`, `runas`, `machinectl` and others.
.. note:: Prior to version 1.9, Ansible mostly allowed the use of `sudo` and a limited use of `su` to allow a login/remote user to become a different user and execute tasks and create resources with the second user's permissions. As of Ansible version 1.9, `become` supersedes the old sudo/su, while still being backwards compatible. This new implementation also makes it easier to add other privilege escalation tools, including `pbrun` (Powerbroker), `pfexec`, `dzdo` (Centrify), and others. .. note:: Prior to version 1.9, Ansible mostly allowed the use of `sudo` and a limited use of `su` to allow a login/remote user to become a different user and execute tasks and create resources with the second user's permissions. As of Ansible version 1.9, `become` supersedes the old sudo/su, while still being backwards compatible. This new implementation also makes it easier to add other privilege escalation tools, including `pbrun` (Powerbroker), `pfexec`, `dzdo` (Centrify), and others.
@ -31,7 +31,7 @@ become_user
set to user with desired privileges — the user you `become`, NOT the user you login as. Does NOT imply ``become: yes``, to allow it to be set at host level. set to user with desired privileges — the user you `become`, NOT the user you login as. Does NOT imply ``become: yes``, to allow it to be set at host level.
become_method become_method
(at play or task level) overrides the default method set in ansible.cfg, set to `sudo`/`su`/`pbrun`/`pfexec`/`doas`/`dzdo`/`ksu`/`runas` (at play or task level) overrides the default method set in ansible.cfg, set to `sudo`/`su`/`pbrun`/`pfexec`/`doas`/`dzdo`/`ksu`/`runas`/`machinectl`
become_flags become_flags
(at play or task level) permit the use of specific flags for the tasks or role. One common use is to change the user to nobody when the shell is set to no login. Added in Ansible 2.2. (at play or task level) permit the use of specific flags for the tasks or role. One common use is to change the user to nobody when the shell is set to no login. Added in Ansible 2.2.
@ -91,7 +91,7 @@ Command line options
--become-method=BECOME_METHOD --become-method=BECOME_METHOD
privilege escalation method to use (default=sudo), privilege escalation method to use (default=sudo),
valid choices: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas ] valid choices: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | machinectl ]
--become-user=BECOME_USER --become-user=BECOME_USER
run operations as this user (default=root), does not imply --become/-b run operations as this user (default=root), does not imply --become/-b
@ -208,6 +208,33 @@ or '/bin/chmod' as the allowed commands this will fail with ansible as those
paths won't match with the temporary file that ansible creates to run the paths won't match with the temporary file that ansible creates to run the
module. module.
Environment variables populated by pam_systemd
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For most Linux distributions using ``systemd`` as their init, the default
methods used by ``become`` do not open a new "session", in the sense of
systemd. Because the ``pam_systemd`` module will not fully initialize a new
session, you might have surprises compared to a normal session opened through
ssh: some environment variables set by ``pam_systemd``, most notably
``XDG_RUNTIME_DIR``, are not populated for the new user and instead inherited
or just emptied.
This might cause trouble when trying to invoke systemd commands that depend on
``XDG_RUNTIME_DIR`` to access the bus:
.. code-block:: console
$ echo $XDG_RUNTIME_DIR
$ systemctl --user status
Failed to connect to bus: Permission denied
To force ``become`` to open a new systemd session that goes through
``pam_systemd``, you can use ``become_method: machinectl``.
For more information, see `this systemd issue
<https://github.com/systemd/systemd/issues/825#issuecomment-127917622>`_.
.. _become-network: .. _become-network:
Become and Networks Become and Networks

@ -59,7 +59,7 @@ def set_constant(name, value, export=vars()):
# CONSTANTS ### yes, actual ones # CONSTANTS ### yes, actual ones
BECOME_METHODS = ['sudo', 'su', 'pbrun', 'pfexec', 'doas', 'dzdo', 'ksu', 'runas', 'pmrun', 'enable'] BECOME_METHODS = ['sudo', 'su', 'pbrun', 'pfexec', 'doas', 'dzdo', 'ksu', 'runas', 'pmrun', 'enable', 'machinectl']
BECOME_ERROR_STRINGS = { BECOME_ERROR_STRINGS = {
'sudo': 'Sorry, try again.', 'sudo': 'Sorry, try again.',
'su': 'Authentication failure', 'su': 'Authentication failure',
@ -70,6 +70,7 @@ BECOME_ERROR_STRINGS = {
'ksu': 'Password incorrect', 'ksu': 'Password incorrect',
'pmrun': 'You are not permitted to run this command', 'pmrun': 'You are not permitted to run this command',
'enable': '', 'enable': '',
'machinectl': '',
} # FIXME: deal with i18n } # FIXME: deal with i18n
BECOME_MISSING_STRINGS = { BECOME_MISSING_STRINGS = {
'sudo': 'sorry, a password is required to run sudo', 'sudo': 'sorry, a password is required to run sudo',
@ -81,6 +82,7 @@ BECOME_MISSING_STRINGS = {
'ksu': 'No password given', 'ksu': 'No password given',
'pmrun': '', 'pmrun': '',
'enable': '', 'enable': '',
'machinectl': '',
} # FIXME: deal with i18n } # FIXME: deal with i18n
BLACKLIST_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt') BLACKLIST_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt')
BOOL_TRUE = BOOLEANS_TRUE BOOL_TRUE = BOOLEANS_TRUE

@ -142,7 +142,7 @@ def check_command(module, commandline):
'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt', 'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt',
'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'replace, lineinfile or template', 'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'replace, lineinfile or template',
'dnf': 'dnf', 'zypper': 'zypper'} 'dnf': 'dnf', 'zypper': 'zypper'}
become = ['sudo', 'su', 'pbrun', 'pfexec', 'runas', 'pmrun'] become = ['sudo', 'su', 'pbrun', 'pfexec', 'runas', 'pmrun', 'machinectl']
if isinstance(commandline, list): if isinstance(commandline, list):
command = commandline[0] command = commandline[0]
else: else:

@ -557,6 +557,11 @@ class PlayContext(Base):
prompt = 'Enter UPM user password:' prompt = 'Enter UPM user password:'
becomecmd = '%s %s %s' % (exe, flags, shlex_quote(command)) becomecmd = '%s %s %s' % (exe, flags, shlex_quote(command))
elif self.become_method == 'machinectl':
exe = self.become_exe or 'machinectl'
becomecmd = '%s shell -q %s %s@ %s' % (exe, flags, self.become_user, command)
else: else:
raise AnsibleError("Privilege escalation method not found: %s" % self.become_method) raise AnsibleError("Privilege escalation method not found: %s" % self.become_method)

Loading…
Cancel
Save