Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle condition going from privileged to non-privileged user in whic… #805

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

msaladna
Copy link

@msaladna msaladna commented Feb 2, 2021

…h the cwd disables descent.

Fall back to Mitogen's temporary directory. Related to #636.

Allows Mitogen to fallback to a safe temporary directory when become is used and become_user cannot use the cwd. For example, fixes the following code assuming directory of playbook_dir is owned by root with permission 0700.

- hosts: localhost
  gather_facts: no
  tasks:
    - stat: path="{{ playbook_dir }}"
    - command: cd {{ playbook_dir | quote }}
    - command: sudo -u nobody cd {{ playbook_dir | quote }}
      ignore_errors: True
      args:
        warn: False
    - stat: path="{{ playbook_dir }}"
      become: True
      become_user: nobody

Previously, os.chdir fails:

The full traceback is:
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/ansible/executor/task_executor.py", line 147, in run
    res = self._execute()
  File "/usr/lib/python3.6/site-packages/ansible/executor/task_executor.py", line 665, in _execute
    result = self._handler.run(task_vars=variables)
  File "/root/mitogen/build/lib/ansible_mitogen/mixins.py", line 142, in run
    return super(ActionModuleMixin, self).run(tmp, task_vars)
  File "/usr/lib/python3.6/site-packages/ansible/plugins/action/normal.py", line 47, in run
    result = merge_hash(result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))
  File "/root/mitogen/build/lib/ansible_mitogen/mixins.py", line 392, in _execute_module
    timeout_secs=self.get_task_timeout_secs(),
  File "/root/mitogen/build/lib/ansible_mitogen/planner.py", line 599, in invoke
    kwargs=planner.get_kwargs(),
  File "/root/mitogen/build/lib/ansible_mitogen/connection.py", line 451, in call
    return self._rethrow(recv)
  File "/root/mitogen/build/lib/ansible_mitogen/connection.py", line 437, in _rethrow
    return recv.get().unpickle()
  File "/root/mitogen/build/lib/mitogen/core.py", line 963, in unpickle
    raise obj
mitogen.core.CallError: builtins.PermissionError: [Errno 13] Permission denied: '/usr/local/apnscp/resources/playbooks'
  File "<stdin>", line 3676, in _dispatch_one
  File "master:/root/mitogen/build/lib/ansible_mitogen/target.py", line 422, in run_module
    return impl.run()
  File "master:/root/mitogen/build/lib/ansible_mitogen/runner.py", line 440, in run
    self.setup()
  File "master:/root/mitogen/build/lib/ansible_mitogen/runner.py", line 851, in setup
    super(NewStyleRunner, self).setup()
  File "master:/root/mitogen/build/lib/ansible_mitogen/runner.py", line 623, in setup
    super(ProgramRunner, self).setup()
  File "master:/root/mitogen/build/lib/ansible_mitogen/runner.py", line 374, in setup
    self._setup_cwd()
  File "master:/root/mitogen/build/lib/ansible_mitogen/runner.py", line 384, in _setup_cwd
    os.chdir(self.cwd)

fatal: [localhost]: FAILED! => 
  msg: Unexpected failure during module execution.
  stdout: ''

With this change it succeeds falling back to /var/tmp restoring normal Ansible operation.

The full traceback is:
  File "master:/usr/lib/python3.6/site-packages/ansible/modules/files/stat.py", line 464, in main
fatal: [localhost]: FAILED! => changed=false 
  invocation:
    module_args:
      checksum_algorithm: sha1
      follow: false
      get_attributes: true
      get_checksum: true
      get_md5: false
      get_mime: true
      path: /usr/local/apnscp/resources/playbooks
  msg: Permission denied

Debug log from the task.

[mux  3057890] 14:13:52.493340 D mitogen.[fork.3058008]: Parent is context 4 (parent); my ID is 1006
[mux  3057890] 14:13:52.493396 D mitogen.[fork.3058008]: pid:3058008 ppid:3057993 uid:65534/65534, gid:65534/65534 host:'c8-test'
[mux  3057890] 14:13:52.493452 D mitogen.[fork.3058008]: Recovered sys.executable: '/usr/bin/python3.6'
[mux  3057890] 14:13:52.498076 D mitogen.service.[local.3057927.sudo.nobody]: PushFileService().store_and_forward('/usr/lib/python3.6/site-packages/ansible/modules/files/stat.py', [blob: 19038 bytes], Context(4, 'sudo.nobody')) 'mitogen.Pool.5940.0'
[mux  3057890] 14:13:52.504938 D mitogen.service.[local.3057927.sudo.nobody]: Pool(5940, size=2, th='MainThread'): initialized
[mux  3057890] 14:13:52.505143 D mitogen.[local.3057927.sudo.nobody]: Dispatcher: dispatching ('c8-test-3057968-7f5a555b4b80-77a7276d47', 'ansible_mitogen.target', None, 'run_module', (), Kwargs({'kwargs': {'runner_name': 'NewStyleRunner', 'module': 'stat', 'path': '/usr/lib/python3.6/site-packages/ansible/modules/files/stat.py', 'json_args': '{"path": "/usr/local/apnscp/resources/playbooks", "_ansible_check_mode": false, "_ansible_no_log": false, "_ansible_debug": false, "_ansible_diff": false, "_ansible_verbosity": 3, "_ansible_version": "2.9.17", "_ansible_module_name": "stat", "_ansible_syslog_facility": "LOG_USER", "_ansible_selinux_special_fs": ["fuse", "nfs", "vboxsf", "ramfs", "9p", "vfat"], "_ansible_string_conversion_action": "warn", "_ansible_socket": null, "_ansible_shell_executable": "/bin/sh", "_ansible_keep_remote_files": false, "_ansible_tmpdir": null, "_ansible_remote_tmp": "/var/tmp"}', 'env': {}, 'interpreter_fragment': None, 'is_python': None, 'module_map': {'builtin': ['ansible.module_utils._text', 'ansible.module_utils.basic', 'ansible.module_utils.common', 'ansible.module_utils.common._collections_compat', 'ansible.module_utils.common._json_compat', 'ansible.module_utils.common._utils', 'ansible.module_utils.common.collections', 'ansible.module_utils.common.file', 'ansible.module_utils.common.parameters', 'ansible.module_utils.common.process', 'ansible.module_utils.common.sys_info', 'ansible.module_utils.common.text', 'ansible.module_utils.common.text.converters', 'ansible.module_utils.common.text.formatters', 'ansible.module_utils.common.validation', 'ansible.module_utils.compat', 'ansible.module_utils.compat._selectors2', 'ansible.module_utils.compat.selectors', 'ansible.module_utils.distro', 'ansible.module_utils.distro._distro', 'ansible.module_utils.parsing', 'ansible.module_utils.parsing.convert_bool', 'ansible.module_utils.pycompat24', 'ansible.module_utils.six'], 'custom': []}, 'py_module_name': 'ansible.modules.files.stat', 'good_temp_dir': '/var/tmp', 'cwd': '/usr/local/apnscp/resources/playbooks', 'extra_env': {}, 'emulate_tty': True, 'service_context': Context(0, None)}}))
[mux  3057890] 14:13:52.505239 D ansible_mitogen.runner.[local.3057927.sudo.nobody]: <ansible_mitogen.runner.NewStyleRunner object at 0x7f41cc4d5a58>: could not CHDIR to '/usr/local/apnscp/resources/playbooks' fallback to '/var/tmp'

I believe a test case wouldn't hurt; however, I'm not terribly great with Python and wouldn't know where to begin with creating a non-privileged user or skipping the test if "become" is unavailable.

…h the cwd disables descent.

Fall back to Mitogen's temporary directory. In relation to mitogen-hq#636.
@s1113950
Copy link
Collaborator

s1113950 commented Feb 7, 2021

This change looks ok to me, but I'm not sure why we didn't do this to begin with (the so don't even try part of the docstring). Deferring to @dw on this.

@dw
Copy link
Member

dw commented Feb 8, 2021

This looks harmless and reasonable. "Current working directory" logic has been a bit of a nightmare in the past, but I can't see how this change would break any situation that wasn't already broken (and is fixed by the chdir to tmpdir instead).

On the "change default semantics" thing, there are several old bugs that might reawaken if the non-error case is changed too, would err on the side of keeping existing behaviour here and just handling the error case.

@opoplawski
Copy link
Contributor

What's the status here? I'm starting to run into this issue as well.

@opoplawski
Copy link
Contributor

Ping? Just hit this again. This most recent bug that toggled the os.chdir() behavior was #591 so we want to make sure that still works with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants