{"id":10016,"library":"oslo-rootwrap","title":"Oslo Rootwrap","description":"Oslo Rootwrap is an OpenStack library providing a highly configurable privilege escalation mechanism, akin to `sudo`. It enables non-root users to execute specific commands as root, governed by filters defined in configuration files, and is crucial for secure privileged operations in OpenStack services. The current version is 7.9.0, and it is actively maintained as part of the OpenStack Oslo common libraries, following OpenStack's release cadence.","status":"active","version":"7.9.0","language":"en","source_language":"en","source_url":"https://github.com/openstack/oslo.rootwrap","tags":["OpenStack","security","privilege escalation","sudo","oslo"],"install":[{"cmd":"pip install oslo-rootwrap","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for inter-process communication and locking primitives.","package":"oslo.concurrency"},{"reason":"Required for configuration management, including parsing rootwrap.conf and filter files.","package":"oslo.config"},{"reason":"Required for internationalization support.","package":"oslo.i18n"},{"reason":"Provides common utility functions and helper classes.","package":"oslo.utils"},{"reason":"Optional: Used for monitoring configuration file changes for live reloading.","package":"pyinotify","optional":true},{"reason":"Optional: Required if using YAML-formatted filter files.","package":"PyYAML","optional":true}],"imports":[{"symbol":"RootwrapClient","correct":"from oslo_rootwrap.client import RootwrapClient"},{"note":"oslo.rootwrap extensively uses oslo.config for its settings.","symbol":"cfg","correct":"from oslo_config import cfg"}],"quickstart":{"code":"import os\nfrom oslo_config import cfg\nfrom oslo_rootwrap import client\n\n# Define oslo-rootwrap specific configuration options\nrootwrap_group = cfg.OptGroup(\n    name='rootwrap',\n    title='Rootwrap Options for privilege escalation'\n)\ncfg.CONF.register_group(rootwrap_group)\n\ncfg.CONF.register_opts([\n    cfg.StrOpt('rootwrap_config',\n               default='/etc/rootwrap.conf',\n               help='Path to the rootwrap configuration file.'),\n    cfg.StrOpt('filters_path',\n               default='/etc/rootwrap.d',\n               help='Path to the directory containing rootwrap filter files.'),\n    cfg.StrOpt('daemon_pid_dir',\n               default='/var/run/oslo-rootwrap',\n               help='Directory for rootwrap daemon PID files. Used only if in daemon mode.'),\n    cfg.StrOpt('daemon_wrapper',\n               default='/usr/bin/sudo',\n               help='Path to the sudo wrapper binary that executes the rootwrap daemon.'),\n], group=rootwrap_group)\n\n# Initialize oslo_config. In a real application, you'd usually load from files:\n# cfg.CONF(project='my_app', default_config_files=['/etc/my_app/my_app.conf'])\n# For this quickstart, we use registered defaults.\nprint(\"Initializing oslo_config and setting up rootwrap options...\")\ncfg.CONF() # This parses any command-line arguments and loads default config values\n\n# Instantiate the RootwrapClient\ntry:\n    # The client uses the global cfg.CONF object\n    rootwrap_client = client.RootwrapClient(cfg.CONF)\n    print(\"RootwrapClient instantiated successfully using oslo_config.\")\n\n    # Display some configured paths\n    print(f\"Configured rootwrap config file: {cfg.CONF.rootwrap.rootwrap_config}\")\n    print(f\"Configured rootwrap filters path: {cfg.CONF.rootwrap.filters_path}\")\n    print(f\"Configured daemon wrapper (sudo path): {rootwrap_client.get_daemon_wrapper()}\")\n\n    print(\"\\n--- Important Note for Execution ---\")\n    print(\"The oslo-rootwrap library requires extensive system-level setup to function:\")\n    print(\"1. A 'rootwrap.conf' file (e.g., at /etc/rootwrap.conf) defining general rules.\")\n    print(\"2. Filter files (e.g., in /etc/rootwrap.d/) specifying allowed commands and parameters.\")\n    print(\"3. 'sudo' configured to execute the 'oslo-rootwrap' binary with SUID permissions.\")\n    print(\"\\nTo execute a command, you would typically use:\")\n    print(\"  stdout, stderr, returncode = rootwrap_client.execute(['command', 'arg1', 'arg2'])\")\n    print(\"Attempting to run `execute` without this setup will likely result in errors.\")\n\nexcept Exception as e:\n    print(f\"Error during RootwrapClient instantiation: {e}\")\n    print(\"Ensure oslo_config options are correctly registered and paths are valid for your setup.\")\n","lang":"python","description":"This quickstart demonstrates how to initialize `oslo_config` and instantiate the `RootwrapClient`. While the client can be created, actual privilege escalation via `rootwrap_client.execute()` requires a fully configured `sudo` setup, `rootwrap.conf`, and filter files on the system, which are beyond a simple runnable code snippet."},"warnings":[{"fix":"Upgrade to Python 3.6+ (or specified minimum for your oslo-rootwrap version) and ensure all dependencies are compatible.","message":"Python 2.x support was dropped in `oslo-rootwrap` version 5.0.0. Projects migrating from older OpenStack versions using Python 2 must upgrade their environment to Python 3.x.","severity":"breaking","affected_versions":"<5.0.0"},{"fix":"Thoroughly review `rootwrap.conf` and all filter files. Ensure that the paths to these files are correctly configured in `oslo.config` and that all commands to be executed are explicitly defined with their full path and arguments.","message":"Incorrect or missing rootwrap configuration files (`rootwrap.conf` and filter files in `rootwrap.d`) are the most common source of issues. `oslo-rootwrap` will deny commands that are not explicitly permitted by a filter.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Verify that `/usr/bin/oslo-rootwrap` (or equivalent path) is owned by `root:root` and has permissions like `rwsr-xr-x` (`chmod 4755`). Ensure the `/etc/sudoers` file contains an entry allowing the calling user/group to execute `oslo-rootwrap` with appropriate privileges.","message":"Improper file permissions or `sudo` configuration for the `oslo-rootwrap` binary can prevent it from escalating privileges. The `oslo-rootwrap` binary must be owned by root, have SUID permissions, and be invoked via `sudo` correctly.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Add a new filter rule to one of your `rootwrap.d` files (e.g., `command.filters`) that explicitly allows the full command path and its arguments. Ensure the filter file is correctly parsed and accessible.","cause":"The command you are attempting to execute is not permitted by any of the configured filter files in `rootwrap.d`.","error":"oslo_rootwrap.exceptions.FileFilterNotFound: Filter not found for command: ['/usr/bin/some_script', 'arg1']"},{"fix":"Check the system logs for messages from `sudo` or `oslo-rootwrap`. Verify that `/usr/bin/oslo-rootwrap` exists, has correct SUID permissions, and your `sudoers` file is configured to allow its execution. Ensure `oslo_config` points to the correct `daemon_wrapper` (usually `sudo`).","cause":"The `oslo-rootwrap` daemon could not be started or communicated with, often due to incorrect `sudo` setup, missing `rootwrap` binary, or permission issues.","error":"oslo_rootwrap.exceptions.DaemonConnectionError: Error communicating with rootwrap daemon."},{"fix":"First, check the SUID bit and ownership of the `oslo-rootwrap` binary (`chmod 4755 /usr/bin/oslo-rootwrap`, `chown root:root /usr/bin/oslo-rootwrap`). Next, verify that `rootwrap.conf` and all `rootwrap.d` filter files have appropriate read permissions for the user `oslo-rootwrap` will run as.","cause":"This usually indicates that the `oslo-rootwrap` binary itself cannot be executed with the necessary root privileges, or that the command it tries to run is not permitted due to incorrect filesystem permissions.","error":"E.g., `(13, 'Permission denied')` in `execute` traceback or a generic permission error."}]}