summaryrefslogtreecommitdiff
path: root/linuxnamespaces/idmap.py
diff options
context:
space:
mode:
Diffstat (limited to 'linuxnamespaces/idmap.py')
-rw-r--r--linuxnamespaces/idmap.py34
1 files changed, 28 insertions, 6 deletions
diff --git a/linuxnamespaces/idmap.py b/linuxnamespaces/idmap.py
index d9cf0eb..f66456d 100644
--- a/linuxnamespaces/idmap.py
+++ b/linuxnamespaces/idmap.py
@@ -7,7 +7,7 @@ namespace.
import bisect
import dataclasses
-import getpass
+import pwd
import os
import subprocess
import typing
@@ -16,17 +16,36 @@ from .atlocation import AtLocation, AtLocationLike
def subidranges(
- kind: typing.Literal["uid", "gid"], login: str | None = None
+ kind: typing.Literal["uid", "gid"],
+ login: str | None = None,
+ uid: int | None = None,
) -> typing.Iterator[tuple[int, int]]:
"""Parse a `/etc/sub?id` file for ranges allocated to the given or current
user. Return all ranges as (start, count) pairs.
"""
+ if uid is None:
+ if login is None:
+ uid = os.getuid()
+ else:
+ try:
+ uid = pwd.getpwnam(login).pw_uid
+ except KeyError:
+ pass
if login is None:
- login = getpass.getuser()
+ try:
+ login = pwd.getpwuid(uid).pw_name
+ except KeyError:
+ pass
with open(f"/etc/sub{kind}") as filelike:
for line in filelike:
parts = line.strip().split(":")
- if parts[0] == login:
+ try:
+ curuid = int(parts[0])
+ except ValueError:
+ curuid = None
+ if (login is not None and parts[0] == login) or (
+ curuid is not None and uid is not None and curuid == uid
+ ):
yield (int(parts[1]), int(parts[2]))
@@ -95,13 +114,16 @@ class IDAllocation:
@classmethod
def loadsubid(
- cls, kind: typing.Literal["uid", "gid"], login: str | None = None,
+ cls,
+ kind: typing.Literal["uid", "gid"],
+ login: str | None = None,
+ uid: int | None = None,
) -> "IDAllocation":
"""Load a `/etc/sub?id` file and return ids allocated to the given
login or current user.
"""
self = cls()
- for start, count in subidranges(kind, login):
+ for start, count in subidranges(kind, login, uid):
self.add_range(start, count)
return self