Skip to content

Instantly share code, notes, and snippets.

@masahide
Created February 14, 2014 20:20
Show Gist options
  • Save masahide/9008470 to your computer and use it in GitHub Desktop.
Save masahide/9008470 to your computer and use it in GitHub Desktop.
Ansibleのsudo ask-sudo-pass はどう実装されているか ref: http://qiita.com/yamasaki-masahide/items/454d81be6ca632f39758
def make_sudo_cmd(sudo_user, executable, cmd):
"""
helper function for connection plugins to create sudo commands
"""
# Rather than detect if sudo wants a password this time, -k makes
# sudo always ask for a password if one is required.
# Passing a quoted compound command to sudo (or sudo -s)
# directly doesn't work, so we shellquote it with pipes.quote()
# and pass the quoted string to the user's shell. We loop reading
# output until we see the randomly-generated sudo prompt set with
# the -p option.
randbits = ''.join(chr(random.randint(ord('a'), ord('z'))) for x in xrange(32))
prompt = '[sudo via ansible, key=%s] password: ' % randbits
success_key = 'SUDO-SUCCESS-%s' % randbits
sudocmd = '%s -k && %s %s -S -p "%s" -u %s %s -c %s' % (
C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_FLAGS,
prompt, sudo_user, executable or '$SHELL', pipes.quote('echo %s; %s' % (success_key, cmd)))
return ('/bin/sh -c ' + pipes.quote(sudocmd), prompt, success_key)
sudo -k; sudo -S -p “[sudo via ansible, key=randbits]” -u root /bin/bash “echo SUDO-SUCCESS-randbits; cmd”
-S
-S (stdin) オプションを指定すると、 sudo はパスワードをターミナルデバイスからではなく、 標準入力から読み込む。パスワードは末尾に改行を付けなければならない。
-k [command]
-k (kill) オプションを単独で使うと、 sudo はユーザの保存された認証情報を無効にする。 次回 sudo を実行するとき、パスワードが要求されることになるわけだ。 このオプション自体はパスワードを必要としない。
-p prompt
-p (prompt) オプションを使うと、 デフォルトのパスワードプロンプトを変更して、好きな文句にすることができる。 sudoers ポリシーでは以下のパーセント (` %
') エスケープが使用できる。
-S
-S (stdin) オプションを指定すると、 sudo はパスワードをターミナルデバイスからではなく、 標準入力から読み込む。パスワードは末尾に改行を付けなければならない。
-k [command]
-k (kill) オプションを単独で使うと、 sudo はユーザの保存された認証情報を無効にする。 次回 sudo を実行するとき、パスワードが要求されることになるわけだ。 このオプション自体はパスワードを必要としない。
-p prompt
-p (prompt) オプションを使うと、 デフォルトのパスワードプロンプトを変更して、好きな文句にすることができる。 sudoers ポリシーでは以下のパーセント (` %
') エスケープが使用できる。
if self.runner.sudo or sudoable:
shcmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)
elif self.runner.su or su:
shcmd, prompt, success_key = utils.make_su_cmd(su_user, executable, cmd)
vvv("EXEC %s" % shcmd, host=self.host)
sudo_output = ''
try:
chan.exec_command(shcmd)
if self.runner.sudo_pass or self.runner.su_pass:
while not sudo_output.endswith(prompt) and success_key not in sudo_output:
chunk = chan.recv(bufsize)
if not chunk:
if 'unknown user' in sudo_output:
raise errors.AnsibleError(
'user %s does not exist' % sudo_user)
else:
raise errors.AnsibleError('ssh connection ' +
'closed waiting for password prompt')
sudo_output += chunk
if success_key not in sudo_output:
if sudoable:
chan.sendall(self.runner.sudo_pass + '\n')
elif su:
chan.sendall(self.runner.su_pass + '\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment