Guest User

Untitled

a guest
Nov 27th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.60 KB | None | 0 0
  1. From 99552061a84cefba8d3fd44c3df667b911978d43 Mon Sep 17 00:00:00 2001
  2. From: Sebastien Bocahu <sebastien@ispfr.net>
  3. Date: Wed, 25 Jul 2012 16:47:23 +0200
  4. Subject: [PATCH] Support of gradm to elevate privileges using a role in a Grsecurity RBAC environment
  5.  
  6. ---
  7. bin/ansible | 10 +++++++++-
  8. bin/ansible-playbook | 10 ++++++++++
  9. lib/ansible/constants.py | 2 ++
  10. lib/ansible/playbook/__init__.py | 9 +++++++++
  11. lib/ansible/runner/__init__.py | 9 ++++++++-
  12. lib/ansible/runner/connection/local.py | 3 +++
  13. lib/ansible/runner/connection/paramiko_ssh.py | 22 +++++++++++++++++++++-
  14. lib/ansible/runner/connection/ssh.py | 4 ++++
  15. lib/ansible/utils.py | 4 ++++
  16. 9 files changed, 70 insertions(+), 3 deletions(-)
  17.  
  18. diff --git a/bin/ansible b/bin/ansible
  19. index fd87a40..8c7bba5 100755
  20. --- a/bin/ansible
  21. +++ b/bin/ansible
  22. @@ -75,6 +75,7 @@ class Cli(object):
  23.  
  24. sshpass = None
  25. sudopass = None
  26. + gradmpass = None
  27. if options.ask_pass:
  28. sshpass = getpass.getpass(prompt="SSH password: ")
  29. if options.ask_sudo_pass:
  30. @@ -83,6 +84,11 @@ class Cli(object):
  31. if options.sudo_user:
  32. options.sudo = True
  33. options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
  34. + if options.gradm_role:
  35. + options.gradm = True
  36. + if options.gradm:
  37. + gradmpass = getpass.getpass(prompt="Gradm password: ")
  38. + options.gradm_role = options.gradm_role or C.DEFAULT_GRADM_ROLE
  39. if options.tree:
  40. utils.prepare_writeable_dir(options.tree)
  41.  
  42. @@ -96,7 +102,9 @@ class Cli(object):
  43. pattern=pattern,
  44. callbacks=self.callbacks, sudo=options.sudo,
  45. sudo_pass=sudopass,sudo_user=options.sudo_user,
  46. - transport=options.connection, verbose=options.verbose
  47. + gradm=options.gradm, gradm_role=options.gradm_role,
  48. + gradm_pass=gradmpass, transport=options.connection,
  49. + verbose=options.verbose
  50. )
  51.  
  52. if options.seconds:
  53. diff --git a/bin/ansible-playbook b/bin/ansible-playbook
  54. index cce371e..1eacf54 100755
  55. --- a/bin/ansible-playbook
  56. +++ b/bin/ansible-playbook
  57. @@ -68,6 +68,7 @@ def main(args):
  58.  
  59. sshpass = None
  60. sudopass = None
  61. + gradmpass = None
  62. if options.ask_pass:
  63. sshpass = getpass.getpass(prompt="SSH password: ")
  64. if options.ask_sudo_pass:
  65. @@ -76,6 +77,12 @@ def main(args):
  66. if options.sudo_user:
  67. options.sudo = True
  68. options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
  69. + if options.gradm_role:
  70. + options.gradm = True
  71. + if options.gradm:
  72. + gradmpass = getpass.getpass(prompt="Gradm password: ")
  73. + options.gradm_role = options.gradm_role or C.DEFAULT_GRADM_ROLE
  74. +
  75. extra_vars = utils.parse_kv(options.extra_vars)
  76. only_tags = options.tags.split(",")
  77.  
  78. @@ -102,6 +109,9 @@ def main(args):
  79. sudo=options.sudo,
  80. sudo_user=options.sudo_user,
  81. sudo_pass=sudopass,
  82. + gradm=options.gradm,
  83. + gradm_role=options.gradm_role,
  84. + gradm_pass=gradmpass,
  85. extra_vars=extra_vars,
  86. private_key_file=options.private_key_file,
  87. only_tags=only_tags,
  88. diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py
  89. index e723cf1..c30ee52 100644
  90. --- a/lib/ansible/constants.py
  91. +++ b/lib/ansible/constants.py
  92. @@ -32,6 +32,8 @@ DEFAULT_REMOTE_PASS = None
  93. DEFAULT_PRIVATE_KEY_FILE = os.environ.get('ANSIBLE_PRIVATE_KEY_FILE',None)
  94. DEFAULT_SUDO_PASS = None
  95. DEFAULT_SUDO_USER = os.environ.get('ANSIBLE_SUDO_USER','root')
  96. +DEFAULT_GRADM_PASS = None
  97. +DEFAULT_GRADM_ROLE = os.environ.get('ANSIBLE_GRADM_ROLE','admin')
  98. DEFAULT_REMOTE_PORT = 22
  99. DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko')
  100. DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh']
  101. diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py
  102. index 796a570..618398c 100644
  103. --- a/lib/ansible/playbook/__init__.py
  104. +++ b/lib/ansible/playbook/__init__.py
  105. @@ -46,6 +46,7 @@ class PlayBook(object):
  106. remote_user = C.DEFAULT_REMOTE_USER,
  107. remote_pass = C.DEFAULT_REMOTE_PASS,
  108. sudo_pass = C.DEFAULT_SUDO_PASS,
  109. + gradm_pass = C.DEFAULT_GRADM_PASS,
  110. remote_port = C.DEFAULT_REMOTE_PORT,
  111. transport = C.DEFAULT_TRANSPORT,
  112. private_key_file = C.DEFAULT_PRIVATE_KEY_FILE,
  113. @@ -55,6 +56,8 @@ class PlayBook(object):
  114. stats = None,
  115. sudo = False,
  116. sudo_user = C.DEFAULT_SUDO_USER,
  117. + gradm = False,
  118. + gradm_role = C.DEFAULT_GRADM_ROLE,
  119. extra_vars = None,
  120. only_tags = None):
  121.  
  122. @@ -67,6 +70,7 @@ class PlayBook(object):
  123. remote_user: run as this user if not specified in a particular play
  124. remote_pass: use this remote password (for all plays) vs using SSH keys
  125. sudo_pass: if sudo==True, and a password is required, this is the sudo password
  126. + gradm_pass: if gradm==True this is the grsec password
  127. remote_port: default remote port to use if not specified with the host or play
  128. transport: how to connect to hosts that don't specify a transport (local, paramiko, etc)
  129. callbacks output callbacks for the playbook
  130. @@ -99,6 +103,9 @@ class PlayBook(object):
  131. self.sudo = sudo
  132. self.sudo_pass = sudo_pass
  133. self.sudo_user = sudo_user
  134. + self.gradm = gradm
  135. + self.gradm_pass = gradm_pass
  136. + self.gradm_role = gradm_role
  137. self.extra_vars = extra_vars
  138. self.global_vars = {}
  139. self.private_key_file = private_key_file
  140. @@ -191,6 +198,7 @@ class PlayBook(object):
  141. setup_cache=self.SETUP_CACHE, basedir=self.basedir,
  142. conditional=task.only_if, callbacks=self.runner_callbacks,
  143. verbose=self.verbose, sudo=task.play.sudo, sudo_user=task.play.sudo_user,
  144. + gradm=task.play.gradm, gradm_role=task.play.gradm_role, gradm_pass=self.gradm_pass,
  145. transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True
  146. )
  147.  
  148. @@ -271,6 +279,7 @@ class PlayBook(object):
  149. forks=self.forks, module_path=self.module_path, timeout=self.timeout, remote_user=play.remote_user,
  150. remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file,
  151. setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user,
  152. + gradm=task.play.gradm, gradm_role=task.play.gradm_role, gradm_pass=self.gradm_pass,
  153. verbose=self.verbose, transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True
  154. ).run()
  155. self.stats.compute(setup_results, setup=True)
  156. diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
  157. index 39f4c68..b8162a5 100644
  158. --- a/lib/ansible/runner/__init__.py
  159. +++ b/lib/ansible/runner/__init__.py
  160. @@ -125,6 +125,9 @@ class Runner(object):
  161. verbose=False, # whether to show more or less
  162. sudo=False, # whether to run sudo or not
  163. sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root'
  164. + gradm=False, # whether to elevate privileges using gradm or not
  165. + gradm_role=C.DEFAULT_GRADM_ROLE, # ex: 'admin'
  166. + gradm_pass=C.DEFAULT_GRADM_PASS, # ex: 'password123'
  167. module_vars=None, # a playbooks internals thing
  168. is_playbook=False, # running from playbook or not?
  169. inventory=None # reference to Inventory object
  170. @@ -155,6 +158,9 @@ class Runner(object):
  171. self.background = background
  172. self.sudo = sudo
  173. self.sudo_pass = sudo_pass
  174. + self.gradm = gradm
  175. + self.gradm_role = gradm_role
  176. + self.gradm_pass = gradm_pass
  177. self.is_playbook = is_playbook
  178.  
  179. # misc housekeeping
  180. @@ -609,7 +615,8 @@ class Runner(object):
  181. ''' execute a command string over SSH, return the output '''
  182.  
  183. sudo_user = self.sudo_user
  184. - stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable)
  185. + gradm_role = self.gradm_role
  186. + stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, gradm_role, sudoable=sudoable)
  187.  
  188. if type(stdout) != str:
  189. return "\n".join(stdout.readlines())
  190. diff --git a/lib/ansible/runner/connection/local.py b/lib/ansible/runner/connection/local.py
  191. index 1779ffb..06a133f 100644
  192. --- a/lib/ansible/runner/connection/local.py
  193. +++ b/lib/ansible/runner/connection/local.py
  194. @@ -36,6 +36,9 @@ class LocalConnection(object):
  195. def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False):
  196. ''' run a command on the local host '''
  197.  
  198. + if self.runner.gradm:
  199. + raise errors.AnsibleError("Gradm is presently only supported on the paramiko (SSH) connection type")
  200. +
  201. if self.runner.sudo and sudoable:
  202. if self.runner.sudo_pass:
  203. # NOTE: if someone wants to add sudo w/ password to the local connection type, they are welcome
  204. diff --git a/lib/ansible/runner/connection/paramiko_ssh.py b/lib/ansible/runner/connection/paramiko_ssh.py
  205. index 40aca90..8692e19 100644
  206. --- a/lib/ansible/runner/connection/paramiko_ssh.py
  207. +++ b/lib/ansible/runner/connection/paramiko_ssh.py
  208. @@ -75,13 +75,33 @@ class ParamikoConnection(object):
  209. self.ssh = ssh
  210. return self
  211.  
  212. - def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False):
  213. + def exec_command(self, cmd, tmp_path, sudo_user, gradm_role, sudoable=False):
  214. ''' run a command on the remote host '''
  215.  
  216. bufsize = 4096
  217. chan = self.ssh.get_transport().open_session()
  218. chan.get_pty()
  219.  
  220. +
  221. + if self.runner.gradm:
  222. + gradmcmd = 'gradm -a "%s"' % gradm_role
  223. + gradm_output = ''
  224. + try:
  225. + chan.exec_command(gradmcmd)
  226. + if self.runner.gradm_pass:
  227. + while not gradm_output.endswith('Password: '):
  228. + chunk = chan.recv(bufsize)
  229. + if not chunk:
  230. + raise errors.AnsibleError('ssh connection closed waiting for gradm password prompt')
  231. + gradm_output += chunk
  232. + chan.sendall(self.runner.gradm_pass + '\n')
  233. + except socket.timeout:
  234. + raise errors.AnsibleError('ssh timed out waiting for gradm.\n' + gradm_output)
  235. +
  236. + chan = self.ssh.get_transport().open_session()
  237. + chan.get_pty()
  238. +
  239. +
  240. if not self.runner.sudo or not sudoable:
  241. quoted_command = '"$SHELL" -c ' + pipes.quote(cmd)
  242. chan.exec_command(quoted_command)
  243. diff --git a/lib/ansible/runner/connection/ssh.py b/lib/ansible/runner/connection/ssh.py
  244. index c1acd71..1259244 100644
  245. --- a/lib/ansible/runner/connection/ssh.py
  246. +++ b/lib/ansible/runner/connection/ssh.py
  247. @@ -56,6 +56,10 @@ class SSHConnection(object):
  248. def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False):
  249. ''' run a command on the remote host '''
  250.  
  251. + if self.runner.grsec:
  252. + raise errors.AnsibleError('Gradm is presently only implemented with paramiko transport')
  253. +
  254. +
  255. ssh_cmd = ["ssh", "-tt", "-q"] + self.common_args + [self.host]
  256. if self.runner.sudo and sudoable:
  257. # Rather than detect if sudo wants a password this time, -k makes
  258. diff --git a/lib/ansible/utils.py b/lib/ansible/utils.py
  259. index c8bab97..db6fad7 100644
  260. --- a/lib/ansible/utils.py
  261. +++ b/lib/ansible/utils.py
  262. @@ -293,6 +293,10 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, asyn
  263. help='use this file to authenticate the connection')
  264. parser.add_option('-K', '--ask-sudo-pass', default=False, dest='ask_sudo_pass', action='store_true',
  265. help='ask for sudo password')
  266. + parser.add_option('-g', '--gradm', default=False, dest='gradm', action='store_true',
  267. + help='Elevate privileges with a Grsecurity/gradm role')
  268. + parser.add_option('-R', '--gradm-role', dest='gradm_role',
  269. + help='Grsecurity/gradm role (default=admin)', default=None)
  270. parser.add_option('-M', '--module-path', dest='module_path',
  271. help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
  272. default=constants.DEFAULT_MODULE_PATH)
  273. --
  274. 1.7.2.5
Add Comment
Please, Sign In to add comment