Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 99552061a84cefba8d3fd44c3df667b911978d43 Mon Sep 17 00:00:00 2001
- From: Sebastien Bocahu <sebastien@ispfr.net>
- Date: Wed, 25 Jul 2012 16:47:23 +0200
- Subject: [PATCH] Support of gradm to elevate privileges using a role in a Grsecurity RBAC environment
- ---
- bin/ansible | 10 +++++++++-
- bin/ansible-playbook | 10 ++++++++++
- lib/ansible/constants.py | 2 ++
- lib/ansible/playbook/__init__.py | 9 +++++++++
- lib/ansible/runner/__init__.py | 9 ++++++++-
- lib/ansible/runner/connection/local.py | 3 +++
- lib/ansible/runner/connection/paramiko_ssh.py | 22 +++++++++++++++++++++-
- lib/ansible/runner/connection/ssh.py | 4 ++++
- lib/ansible/utils.py | 4 ++++
- 9 files changed, 70 insertions(+), 3 deletions(-)
- diff --git a/bin/ansible b/bin/ansible
- index fd87a40..8c7bba5 100755
- --- a/bin/ansible
- +++ b/bin/ansible
- @@ -75,6 +75,7 @@ class Cli(object):
- sshpass = None
- sudopass = None
- + gradmpass = None
- if options.ask_pass:
- sshpass = getpass.getpass(prompt="SSH password: ")
- if options.ask_sudo_pass:
- @@ -83,6 +84,11 @@ class Cli(object):
- if options.sudo_user:
- options.sudo = True
- options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
- + if options.gradm_role:
- + options.gradm = True
- + if options.gradm:
- + gradmpass = getpass.getpass(prompt="Gradm password: ")
- + options.gradm_role = options.gradm_role or C.DEFAULT_GRADM_ROLE
- if options.tree:
- utils.prepare_writeable_dir(options.tree)
- @@ -96,7 +102,9 @@ class Cli(object):
- pattern=pattern,
- callbacks=self.callbacks, sudo=options.sudo,
- sudo_pass=sudopass,sudo_user=options.sudo_user,
- - transport=options.connection, verbose=options.verbose
- + gradm=options.gradm, gradm_role=options.gradm_role,
- + gradm_pass=gradmpass, transport=options.connection,
- + verbose=options.verbose
- )
- if options.seconds:
- diff --git a/bin/ansible-playbook b/bin/ansible-playbook
- index cce371e..1eacf54 100755
- --- a/bin/ansible-playbook
- +++ b/bin/ansible-playbook
- @@ -68,6 +68,7 @@ def main(args):
- sshpass = None
- sudopass = None
- + gradmpass = None
- if options.ask_pass:
- sshpass = getpass.getpass(prompt="SSH password: ")
- if options.ask_sudo_pass:
- @@ -76,6 +77,12 @@ def main(args):
- if options.sudo_user:
- options.sudo = True
- options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
- + if options.gradm_role:
- + options.gradm = True
- + if options.gradm:
- + gradmpass = getpass.getpass(prompt="Gradm password: ")
- + options.gradm_role = options.gradm_role or C.DEFAULT_GRADM_ROLE
- +
- extra_vars = utils.parse_kv(options.extra_vars)
- only_tags = options.tags.split(",")
- @@ -102,6 +109,9 @@ def main(args):
- sudo=options.sudo,
- sudo_user=options.sudo_user,
- sudo_pass=sudopass,
- + gradm=options.gradm,
- + gradm_role=options.gradm_role,
- + gradm_pass=gradmpass,
- extra_vars=extra_vars,
- private_key_file=options.private_key_file,
- only_tags=only_tags,
- diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py
- index e723cf1..c30ee52 100644
- --- a/lib/ansible/constants.py
- +++ b/lib/ansible/constants.py
- @@ -32,6 +32,8 @@ DEFAULT_REMOTE_PASS = None
- DEFAULT_PRIVATE_KEY_FILE = os.environ.get('ANSIBLE_PRIVATE_KEY_FILE',None)
- DEFAULT_SUDO_PASS = None
- DEFAULT_SUDO_USER = os.environ.get('ANSIBLE_SUDO_USER','root')
- +DEFAULT_GRADM_PASS = None
- +DEFAULT_GRADM_ROLE = os.environ.get('ANSIBLE_GRADM_ROLE','admin')
- DEFAULT_REMOTE_PORT = 22
- DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko')
- DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh']
- diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py
- index 796a570..618398c 100644
- --- a/lib/ansible/playbook/__init__.py
- +++ b/lib/ansible/playbook/__init__.py
- @@ -46,6 +46,7 @@ class PlayBook(object):
- remote_user = C.DEFAULT_REMOTE_USER,
- remote_pass = C.DEFAULT_REMOTE_PASS,
- sudo_pass = C.DEFAULT_SUDO_PASS,
- + gradm_pass = C.DEFAULT_GRADM_PASS,
- remote_port = C.DEFAULT_REMOTE_PORT,
- transport = C.DEFAULT_TRANSPORT,
- private_key_file = C.DEFAULT_PRIVATE_KEY_FILE,
- @@ -55,6 +56,8 @@ class PlayBook(object):
- stats = None,
- sudo = False,
- sudo_user = C.DEFAULT_SUDO_USER,
- + gradm = False,
- + gradm_role = C.DEFAULT_GRADM_ROLE,
- extra_vars = None,
- only_tags = None):
- @@ -67,6 +70,7 @@ class PlayBook(object):
- remote_user: run as this user if not specified in a particular play
- remote_pass: use this remote password (for all plays) vs using SSH keys
- sudo_pass: if sudo==True, and a password is required, this is the sudo password
- + gradm_pass: if gradm==True this is the grsec password
- remote_port: default remote port to use if not specified with the host or play
- transport: how to connect to hosts that don't specify a transport (local, paramiko, etc)
- callbacks output callbacks for the playbook
- @@ -99,6 +103,9 @@ class PlayBook(object):
- self.sudo = sudo
- self.sudo_pass = sudo_pass
- self.sudo_user = sudo_user
- + self.gradm = gradm
- + self.gradm_pass = gradm_pass
- + self.gradm_role = gradm_role
- self.extra_vars = extra_vars
- self.global_vars = {}
- self.private_key_file = private_key_file
- @@ -191,6 +198,7 @@ class PlayBook(object):
- setup_cache=self.SETUP_CACHE, basedir=self.basedir,
- conditional=task.only_if, callbacks=self.runner_callbacks,
- verbose=self.verbose, sudo=task.play.sudo, sudo_user=task.play.sudo_user,
- + gradm=task.play.gradm, gradm_role=task.play.gradm_role, gradm_pass=self.gradm_pass,
- transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True
- )
- @@ -271,6 +279,7 @@ class PlayBook(object):
- forks=self.forks, module_path=self.module_path, timeout=self.timeout, remote_user=play.remote_user,
- remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file,
- setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user,
- + gradm=task.play.gradm, gradm_role=task.play.gradm_role, gradm_pass=self.gradm_pass,
- verbose=self.verbose, transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True
- ).run()
- self.stats.compute(setup_results, setup=True)
- diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
- index 39f4c68..b8162a5 100644
- --- a/lib/ansible/runner/__init__.py
- +++ b/lib/ansible/runner/__init__.py
- @@ -125,6 +125,9 @@ class Runner(object):
- verbose=False, # whether to show more or less
- sudo=False, # whether to run sudo or not
- sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root'
- + gradm=False, # whether to elevate privileges using gradm or not
- + gradm_role=C.DEFAULT_GRADM_ROLE, # ex: 'admin'
- + gradm_pass=C.DEFAULT_GRADM_PASS, # ex: 'password123'
- module_vars=None, # a playbooks internals thing
- is_playbook=False, # running from playbook or not?
- inventory=None # reference to Inventory object
- @@ -155,6 +158,9 @@ class Runner(object):
- self.background = background
- self.sudo = sudo
- self.sudo_pass = sudo_pass
- + self.gradm = gradm
- + self.gradm_role = gradm_role
- + self.gradm_pass = gradm_pass
- self.is_playbook = is_playbook
- # misc housekeeping
- @@ -609,7 +615,8 @@ class Runner(object):
- ''' execute a command string over SSH, return the output '''
- sudo_user = self.sudo_user
- - stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable)
- + gradm_role = self.gradm_role
- + stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, gradm_role, sudoable=sudoable)
- if type(stdout) != str:
- return "\n".join(stdout.readlines())
- diff --git a/lib/ansible/runner/connection/local.py b/lib/ansible/runner/connection/local.py
- index 1779ffb..06a133f 100644
- --- a/lib/ansible/runner/connection/local.py
- +++ b/lib/ansible/runner/connection/local.py
- @@ -36,6 +36,9 @@ class LocalConnection(object):
- def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False):
- ''' run a command on the local host '''
- + if self.runner.gradm:
- + raise errors.AnsibleError("Gradm is presently only supported on the paramiko (SSH) connection type")
- +
- if self.runner.sudo and sudoable:
- if self.runner.sudo_pass:
- # NOTE: if someone wants to add sudo w/ password to the local connection type, they are welcome
- diff --git a/lib/ansible/runner/connection/paramiko_ssh.py b/lib/ansible/runner/connection/paramiko_ssh.py
- index 40aca90..8692e19 100644
- --- a/lib/ansible/runner/connection/paramiko_ssh.py
- +++ b/lib/ansible/runner/connection/paramiko_ssh.py
- @@ -75,13 +75,33 @@ class ParamikoConnection(object):
- self.ssh = ssh
- return self
- - def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False):
- + def exec_command(self, cmd, tmp_path, sudo_user, gradm_role, sudoable=False):
- ''' run a command on the remote host '''
- bufsize = 4096
- chan = self.ssh.get_transport().open_session()
- chan.get_pty()
- +
- + if self.runner.gradm:
- + gradmcmd = 'gradm -a "%s"' % gradm_role
- + gradm_output = ''
- + try:
- + chan.exec_command(gradmcmd)
- + if self.runner.gradm_pass:
- + while not gradm_output.endswith('Password: '):
- + chunk = chan.recv(bufsize)
- + if not chunk:
- + raise errors.AnsibleError('ssh connection closed waiting for gradm password prompt')
- + gradm_output += chunk
- + chan.sendall(self.runner.gradm_pass + '\n')
- + except socket.timeout:
- + raise errors.AnsibleError('ssh timed out waiting for gradm.\n' + gradm_output)
- +
- + chan = self.ssh.get_transport().open_session()
- + chan.get_pty()
- +
- +
- if not self.runner.sudo or not sudoable:
- quoted_command = '"$SHELL" -c ' + pipes.quote(cmd)
- chan.exec_command(quoted_command)
- diff --git a/lib/ansible/runner/connection/ssh.py b/lib/ansible/runner/connection/ssh.py
- index c1acd71..1259244 100644
- --- a/lib/ansible/runner/connection/ssh.py
- +++ b/lib/ansible/runner/connection/ssh.py
- @@ -56,6 +56,10 @@ class SSHConnection(object):
- def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False):
- ''' run a command on the remote host '''
- + if self.runner.grsec:
- + raise errors.AnsibleError('Gradm is presently only implemented with paramiko transport')
- +
- +
- ssh_cmd = ["ssh", "-tt", "-q"] + self.common_args + [self.host]
- if self.runner.sudo and sudoable:
- # Rather than detect if sudo wants a password this time, -k makes
- diff --git a/lib/ansible/utils.py b/lib/ansible/utils.py
- index c8bab97..db6fad7 100644
- --- a/lib/ansible/utils.py
- +++ b/lib/ansible/utils.py
- @@ -293,6 +293,10 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, asyn
- help='use this file to authenticate the connection')
- parser.add_option('-K', '--ask-sudo-pass', default=False, dest='ask_sudo_pass', action='store_true',
- help='ask for sudo password')
- + parser.add_option('-g', '--gradm', default=False, dest='gradm', action='store_true',
- + help='Elevate privileges with a Grsecurity/gradm role')
- + parser.add_option('-R', '--gradm-role', dest='gradm_role',
- + help='Grsecurity/gradm role (default=admin)', default=None)
- parser.add_option('-M', '--module-path', dest='module_path',
- help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
- default=constants.DEFAULT_MODULE_PATH)
- --
- 1.7.2.5
Add Comment
Please, Sign In to add comment