diff options
author | Helmut Grohne <helmut@subdivi.de> | 2024-01-18 22:25:18 +0100 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2024-01-18 22:25:18 +0100 |
commit | 5e004a85dd660d41ae7c3519679d2cfae8919e77 (patch) | |
tree | b7f102bef104026c963812c38675129faa7cebf4 /examples | |
parent | 034f732a1af4ce295d993e6951decc4898967dd3 (diff) | |
download | python-linuxnamespaces-5e004a85dd660d41ae7c3519679d2cfae8919e77.tar.gz |
add withallsubuids.py example
Diffstat (limited to 'examples')
-rwxr-xr-x | examples/withallsubuids.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/examples/withallsubuids.py b/examples/withallsubuids.py new file mode 100755 index 0000000..8b90e9a --- /dev/null +++ b/examples/withallsubuids.py @@ -0,0 +1,65 @@ +#!/usr/bin/python3 +# Copyright 2024 Helmut Grohne <helmut@subdivi.de> +# SPDX-License-Identifier: GPL-3 + +"""Map all available ranges from /etc/subuid and /etc/subgid as identity and +run a given command with all capabilities (including CAP_DAC_OVERRIDE) +inherited. +""" + +import os +import sys + +if __file__.split("/")[-2:-1] == ["examples"]: + sys.path.insert(0, "/".join(__file__.split("/")[:-2])) + +import linuxnamespaces + + +def main() -> None: + # Construct an identity mapping of all available user/group ids + uidmap = [ + linuxnamespaces.IDMapping(os.getuid(), os.getuid(), 1), + *( + linuxnamespaces.IDMapping(start, start, count) + for start, count + in linuxnamespaces.IDAllocation.loadsubid("uid").ranges + ), + ] + gidmap = [ + linuxnamespaces.IDMapping(os.getgid(), os.getgid(), 1), + *( + linuxnamespaces.IDMapping(start, start, count) + for start, count + in linuxnamespaces.IDAllocation.loadsubid("gid").ranges + ), + ] + linuxnamespaces.unshare_user_idmap(uidmap, gidmap) + + # We haven't changed uid. We still are non-root, but the user namespace + # augmented our permitted and effective capabilities! Add them to the + # inheritable set. + capabilities = linuxnamespaces.CapabilitySets.get() + capabilities.inheritable = capabilities.permitted & capabilities.effective + capabilities.set() + # Add all inheritable capabilities to the ambient set. + caps = capabilities.inheritable + while caps: + cap = caps & (~caps + 1) + caps ^= cap + linuxnamespaces.call_libc( + "prctl", + 47, # PR_CAP_AMBIENT + 2, # PR_CAP_AMBIENT_RAISE + cap.bit_length() - 1, + 0, + 0, + ) + if len(sys.argv) > 1: + os.execvp(sys.argv[1], sys.argv[1:]) + else: + os.execvp(os.environ["SHELL"], [os.environ["SHELL"]]) + + +if __name__ == "__main__": + main() |