Просмотр исходного кода

more attempts to fix euid permissions issues on ubuntu

Nick Sweeting 1 год назад
Родитель
Сommit
a33da44492
5 измененных файлов с 39 добавлено и 11 удалено
  1. 33 5
      archivebox/config/permissions.py
  2. 2 2
      archivebox/main.py
  3. 1 1
      archivebox/vendor/pydantic-pkgr
  4. 2 2
      pyproject.toml
  5. 1 1
      uv.lock

+ 33 - 5
archivebox/config/permissions.py

@@ -1,6 +1,11 @@
 __package__ = 'archivebox.config'
 
 import os
+import pwd
+import sys
+
+from rich import print
+
 from pathlib import Path
 from contextlib import contextmanager
 
@@ -27,16 +32,29 @@ USER: str               = Path('~').expanduser().resolve().name
 IS_ROOT = RUNNING_AS_UID == 0
 IN_DOCKER = os.environ.get('IN_DOCKER', False) in ('1', 'true', 'True', 'TRUE', 'yes')
 
-os.environ.setdefault('PUID', str(DATA_DIR_UID or RUNNING_AS_UID or DEFAULT_PUID))
-os.environ.setdefault('PGID', str(DATA_DIR_GID or RUNNING_AS_GID or DEFAULT_PGID))
+FALLBACK_UID = RUNNING_AS_UID
+FALLBACK_GID = RUNNING_AS_GID
+if RUNNING_AS_UID == 0:
+    try:
+        # if we are running as root it's really hard to figure out what the correct archivebox user should be
+        # as a last resort instead of setting DATA_DIR ownership to 0:0 (which breaks it for non-root users)
+        # check if 911:911 archivebox user exists on host system, and use it instead of 0
+        import pwd
+        if pwd.getpwuid(DEFAULT_PUID).pw_name == 'archivebox':
+            FALLBACK_UID = DEFAULT_PUID
+            FALLBACK_GID = DEFAULT_PGID
+    except Exception:
+        pass
+
+
+os.environ.setdefault('PUID', str(DATA_DIR_UID or EUID or RUNNING_AS_UID or FALLBACK_UID))
+os.environ.setdefault('PGID', str(DATA_DIR_GID or EGID or RUNNING_AS_GID or FALLBACK_GID))
 
 ARCHIVEBOX_USER = int(os.environ['PUID'])
 ARCHIVEBOX_GROUP = int(os.environ['PGID'])
-
 if not USER:
     try:
         # alternative method 1 to get username
-        import pwd
         USER = pwd.getpwuid(ARCHIVEBOX_USER).pw_name
     except Exception:
         pass
@@ -55,6 +73,14 @@ if not USER:
         USER = os.getlogin() or 'archivebox'
     except Exception:
         USER = 'archivebox'
+        
+ARCHIVEBOX_USER_EXISTS = False
+try:
+    pwd.getpwuid(ARCHIVEBOX_USER)
+    ARCHIVEBOX_USER_EXISTS = True
+except Exception:
+    ARCHIVEBOX_USER_EXISTS = False
+    
 
 #############################################################################################
 
@@ -64,7 +90,7 @@ def drop_privileges():
     # always run archivebox as the user that owns the data dir, never as root
     if os.getuid() == 0:
         # drop permissions to the user that owns the data dir / provided PUID
-        if os.geteuid() != ARCHIVEBOX_USER:
+        if os.geteuid() != ARCHIVEBOX_USER and ARCHIVEBOX_USER != 0 and ARCHIVEBOX_USER_EXISTS:
             os.seteuid(ARCHIVEBOX_USER)
             
             # try:
@@ -77,6 +103,8 @@ def drop_privileges():
             #     with SudoPermission(uid=0, fallback=True):
             #         os.system(f'chown -R :{ARCHIVEBOX_GROUP} "{PACKAGE_DIR}"')
         # if we need sudo (e.g. for installing dependencies) code should use SudoPermissions() context manager to regain root
+    if ARCHIVEBOX_USER == 0 or not ARCHIVEBOX_USER_EXISTS:
+        print('[yellow]:warning:  Running as root is not recommended and may make your [blue]DATA_DIR[/blue] inaccessible to other users on your system.[/yellow]', file=sys.stderr)
 
 
 @contextmanager

+ 2 - 2
archivebox/main.py

@@ -219,8 +219,8 @@ def version(quiet: bool=False,
     OUTPUT_IS_REMOTE_FS = CONSTANTS.DATA_LOCATIONS.DATA_DIR.is_mount or CONSTANTS.DATA_LOCATIONS.ARCHIVE_DIR.is_mount
     DATA_DIR_STAT = CONSTANTS.DATA_DIR.stat()
     prnt(
-        f'EUID={os.geteuid()} UID={RUNNING_AS_UID} PUID={ARCHIVEBOX_USER} FS_UID={DATA_DIR_STAT.st_uid}',
-        f'EGID={os.getegid()} GID={RUNNING_AS_GID} PGID={ARCHIVEBOX_GROUP} FS_GID={DATA_DIR_STAT.st_gid}',
+        f'EUID={os.geteuid()}:{os.getegid()} UID={RUNNING_AS_UID}:{RUNNING_AS_GID} PUID={ARCHIVEBOX_USER}:{ARCHIVEBOX_GROUP}',
+        f'FS_UID={DATA_DIR_STAT.st_uid}:{DATA_DIR_STAT.st_gid}',
         f'FS_PERMS={STORAGE_CONFIG.OUTPUT_PERMISSIONS}',
         f'FS_ATOMIC={STORAGE_CONFIG.ENFORCE_ATOMIC_WRITES}',
         f'FS_REMOTE={OUTPUT_IS_REMOTE_FS}',

+ 1 - 1
archivebox/vendor/pydantic-pkgr

@@ -1 +1 @@
-Subproject commit 88892cc7b8d8a6424d712b424ebbc1a1be9ce4dc
+Subproject commit b1c4fcb349e6d8fa2772e96c80549648cce3d9a9

+ 2 - 2
pyproject.toml

@@ -1,6 +1,6 @@
 [project]
 name = "archivebox"
-version = "0.8.5rc9"
+version = "0.8.5rc10"
 requires-python = ">=3.10"
 description = "Self-hosted internet archiving solution."
 authors = [{name = "Nick Sweeting", email = "[email protected]"}]
@@ -79,7 +79,7 @@ dependencies = [
     "base32-crockford==0.3.0",
     "platformdirs>=4.3.6",
     # "pocket@git+https://github.com/tapanpandita/[email protected]",
-    "pydantic-pkgr>=0.4.8",
+    "pydantic-pkgr>=0.4.9",
     ############# Plugin Dependencies ################
     "sonic-client>=1.0.0",
     "yt-dlp>=2024.8.6",               # for: media"

+ 1 - 1
uv.lock

@@ -41,7 +41,7 @@ wheels = [
 
 [[package]]
 name = "archivebox"
-version = "0.8.5rc9"
+version = "0.8.5rc10"
 source = { editable = "." }
 dependencies = [
     { name = "atomicwrites" },