Created
February 14, 2014 20:20
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sudo -k; sudo -S -p “[sudo via ansible, key=randbits]” -u root /bin/bash “echo SUDO-SUCCESS-randbits; cmd” |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-S | |
-S (stdin) オプションを指定すると、 sudo はパスワードをターミナルデバイスからではなく、 標準入力から読み込む。パスワードは末尾に改行を付けなければならない。 | |
-k [command] | |
-k (kill) オプションを単独で使うと、 sudo はユーザの保存された認証情報を無効にする。 次回 sudo を実行するとき、パスワードが要求されることになるわけだ。 このオプション自体はパスワードを必要としない。 | |
-p prompt | |
-p (prompt) オプションを使うと、 デフォルトのパスワードプロンプトを変更して、好きな文句にすることができる。 sudoers ポリシーでは以下のパーセント (` % | |
') エスケープが使用できる。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-S | |
-S (stdin) オプションを指定すると、 sudo はパスワードをターミナルデバイスからではなく、 標準入力から読み込む。パスワードは末尾に改行を付けなければならない。 | |
-k [command] | |
-k (kill) オプションを単独で使うと、 sudo はユーザの保存された認証情報を無効にする。 次回 sudo を実行するとき、パスワードが要求されることになるわけだ。 このオプション自体はパスワードを必要としない。 | |
-p prompt | |
-p (prompt) オプションを使うと、 デフォルトのパスワードプロンプトを変更して、好きな文句にすることができる。 sudoers ポリシーでは以下のパーセント (` % | |
') エスケープが使用できる。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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