Add ksu privilege escalation (#17340)

Allow ksu privilege escalation to be used
as a standard become_method

https://web.mit.edu/kerberos/krb5-1.12/doc/user/user_commands/ksu.html
This commit is contained in:
Will Thames 2016-09-02 06:54:31 +10:00 committed by Brian Coca
parent d99c58ee55
commit d54f5277d5
6 changed files with 21 additions and 7 deletions

View file

@ -19,6 +19,7 @@ Ansible Changes By Release
* Added a new `meta` option: `end_play`, which can be used to skip to the end of a play.
* `meta` tasks can now use conditionals.
* `raw` now returns `changed: true` to be consistent with shell/command/script modules. Add `changed_when: false` to `raw` tasks to restore the pre-2.2 behavior if necessary.
* New privilege escalation become method `ksu`
####New Modules:
- archive

View file

@ -8,7 +8,7 @@ Ansible can use existing privilege escalation systems to allow a user to execute
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, which you probably already use or have configured, like `sudo`, `su`, `pfexec`, `doas`, `pbrun`, `dzdo`, and others.
privilege escalation tools, which you probably already use or have configured, like `sudo`, `su`, `pfexec`, `doas`, `pbrun`, `dzdo`, `ksu` and others.
.. note:: Before 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
@ -29,7 +29,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.
become_method
(at play or task level) overrides the default method set in ansible.cfg, set to `sudo`/`su`/`pbrun`/`pfexec`/`doas`/`dzdo`
(at play or task level) overrides the default method set in ansible.cfg, set to `sudo`/`su`/`pbrun`/`pfexec`/`doas`/`dzdo`/`ksu`
become_flags
(at play or task level) permit to use specific flags for the tasks or role. One common use is to change user to nobody when the shell is set to no login
@ -89,7 +89,7 @@ New command line options
--become-method=BECOME_METHOD
privilege escalation method to use (default=sudo),
valid choices: [ sudo | su | pbrun | pfexec | doas | dzdo ]
valid choices: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu ]
--become-user=BECOME_USER
run operations as this user (default=root), does not imply --become/-b

View file

@ -824,7 +824,7 @@ The equivalent of adding sudo: or su: to a play or task, set to true/yes to acti
become_method
=============
Set the privilege escalation method. The default is ``sudo``, other options are ``su``, ``pbrun``, ``pfexec``, ``doas``::
Set the privilege escalation method. The default is ``sudo``, other options are ``su``, ``pbrun``, ``pfexec``, ``doas``, ``ksu``::
become_method=su

View file

@ -213,9 +213,9 @@ DEFAULT_SUDO_FLAGS = get_config(p, DEFAULTS, 'sudo_flags', 'ANSIBLE_SUDO_
DEFAULT_ASK_SUDO_PASS = get_config(p, DEFAULTS, 'ask_sudo_pass', 'ANSIBLE_ASK_SUDO_PASS', False, boolean=True)
# Become
BECOME_ERROR_STRINGS = {'sudo': 'Sorry, try again.', 'su': 'Authentication failure', 'pbrun': '', 'pfexec': '', 'runas': '', 'doas': 'Permission denied', 'dzdo': ''} #FIXME: deal with i18n
BECOME_MISSING_STRINGS = {'sudo': 'sorry, a password is required to run sudo', 'su': '', 'pbrun': '', 'pfexec': '', 'runas': '', 'doas': 'Authorization required', 'dzdo': ''} #FIXME: deal with i18n
BECOME_METHODS = ['sudo','su','pbrun','pfexec','runas','doas','dzdo']
BECOME_ERROR_STRINGS = {'sudo': 'Sorry, try again.', 'su': 'Authentication failure', 'pbrun': '', 'pfexec': '', 'runas': '', 'doas': 'Permission denied', 'dzdo': '', 'ksu': 'Password incorrect'} #FIXME: deal with i18n
BECOME_MISSING_STRINGS = {'sudo': 'sorry, a password is required to run sudo', 'su': '', 'pbrun': '', 'pfexec': '', 'runas': '', 'doas': 'Authorization required', 'dzdo': '', 'ksu': 'No password given'} #FIXME: deal with i18n
BECOME_METHODS = ['sudo','su','pbrun','pfexec','runas','doas','dzdo','ksu']
BECOME_ALLOW_SAME_USER = get_config(p, 'privilege_escalation', 'become_allow_same_user', 'ANSIBLE_BECOME_ALLOW_SAME_USER', False, boolean=True)
DEFAULT_BECOME_METHOD = get_config(p, 'privilege_escalation', 'become_method', 'ANSIBLE_BECOME_METHOD','sudo' if DEFAULT_SUDO else 'su' if DEFAULT_SU else 'sudo' ).lower()
DEFAULT_BECOME = get_config(p, 'privilege_escalation', 'become', 'ANSIBLE_BECOME',False, boolean=True)

View file

@ -522,6 +522,13 @@ class PlayContext(Base):
prompt='assword:'
becomecmd = '%s -b %s -u %s %s' % (exe, flags, self.become_user, success_cmd)
elif self.become_method == 'ksu':
def detect_ksu_prompt(data):
return re.match("Kerberos password for .*@.*:", data)
prompt = detect_ksu_prompt
becomecmd = '%s %s %s -e %s' % (exe, self.become_user, flags, command)
elif self.become_method == 'pfexec':
# No user as it uses it's own exec_attr to figure it out

View file

@ -131,6 +131,8 @@ class TestPlayContext(unittest.TestCase):
pfexec_flags = ''
doas_exe = 'doas'
doas_flags = ' -n -u foo '
ksu_exe = 'ksu'
ksu_flags = ''
dzdo_exe = 'dzdo'
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe)
@ -164,6 +166,10 @@ class TestPlayContext(unittest.TestCase):
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
self.assertEqual(cmd, """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context.success_key, doas_exe, doas_flags, default_cmd))
play_context.become_method = 'ksu'
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
self.assertEqual(cmd, """%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, default_exe, play_context.success_key, default_cmd))
play_context.become_method = 'bad'
self.assertRaises(AnsibleError, play_context.make_become_cmd, cmd=default_cmd, executable="/bin/bash")