1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
DOCUMENTATION = """
name: su
short_description: Substitute User
description:
- This become plugin allows your remote/login user to execute commands as another user via the su utility.
author: ansible (@core)
version_added: "2.8"
options:
become_user:
description: User you 'become' to execute the task
default: root
ini:
- section: privilege_escalation
key: become_user
- section: su_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_su_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SU_USER
keyword:
- name: become_user
become_exe:
description: Su executable
default: su
ini:
- section: privilege_escalation
key: become_exe
- section: su_become_plugin
key: executable
vars:
- name: ansible_become_exe
- name: ansible_su_exe
env:
- name: ANSIBLE_BECOME_EXE
- name: ANSIBLE_SU_EXE
keyword:
- name: become_exe
become_flags:
description: Options to pass to su
default: ''
ini:
- section: privilege_escalation
key: become_flags
- section: su_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_su_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SU_FLAGS
keyword:
- name: become_flags
become_pass:
description: Password to pass to su
required: False
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_su_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SU_PASS
ini:
- section: su_become_plugin
key: password
prompt_l10n:
description:
- List of localized strings to match for prompt detection
- If empty we'll use the built in one
- Do NOT add a colon (:) to your custom entries. Ansible adds a colon at the end of each prompt;
if you add another one in your string, your prompt will fail with a "Timeout" error.
default: []
type: list
elements: string
ini:
- section: su_become_plugin
key: localized_prompts
vars:
- name: ansible_su_prompt_l10n
env:
- name: ANSIBLE_SU_PROMPT_L10N
"""
import re
import shlex
from ansible.module_utils.common.text.converters import to_text
from ansible.plugins.become import BecomeBase
class BecomeModule(BecomeBase):
name = 'su'
pipelining = False
# messages for detecting prompted password issues
fail = ('Authentication failure',)
SU_PROMPT_LOCALIZATIONS = [
'Password',
'암호',
'パスワード',
'Adgangskode',
'Contraseña',
'Contrasenya',
'Hasło',
'Heslo',
'Jelszó',
'Lösenord',
'Mật khẩu',
'Mot de passe',
'Parola',
'Parool',
'Pasahitza',
'Passord',
'Passwort',
'Salasana',
'Sandi',
'Senha',
'Wachtwoord',
'ססמה',
'Лозинка',
'Парола',
'Пароль',
'गुप्तशब्द',
'शब्दकूट',
'సంకేతపదము',
'හස්පදය',
'密码',
'密碼',
'口令',
]
def check_password_prompt(self, b_output: bytes) -> bool:
""" checks if the expected password prompt exists in b_output """
prompts = self.get_option('prompt_l10n') or self.SU_PROMPT_LOCALIZATIONS
password_prompt_strings = "|".join(re.escape(p) for p in prompts)
# Colon or unicode fullwidth colon
prompt_pattern = rf"(?:{password_prompt_strings})\s*[::]"
match = re.search(prompt_pattern, to_text(b_output), flags=re.IGNORECASE)
if match:
self.prompt = match.group(0) # preserve the actual matched string so we can scrub the output
return bool(match)
def build_become_command(self, cmd, shell):
super(BecomeModule, self).build_become_command(cmd, shell)
# Prompt handling for ``su`` is more complicated, this
# is used to satisfy the connection plugin
self.prompt = True
if not cmd:
return cmd
exe = self.get_option('become_exe') or self.name
flags = self.get_option('become_flags') or ''
user = self.get_option('become_user') or ''
success_cmd = self._build_success_command(cmd, shell)
return "%s %s %s -c %s" % (exe, flags, user, shlex.quote(success_cmd))
|