From 8437e4458742e7d9392041fa1e528df17af1acab Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Sun, 2 Aug 2026 05:22:43 -0700 Subject: [PATCH] Repair copied collection ownership boundaries --- archivebox/config/permissions.py | 9 ++++++++- archivebox/tests/test_permissions.py | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/archivebox/config/permissions.py b/archivebox/config/permissions.py index f188dad2..7ff901eb 100644 --- a/archivebox/config/permissions.py +++ b/archivebox/config/permissions.py @@ -186,8 +186,15 @@ def root_data_dir_handoff_paths(data_dir: Path, argv: list[str]) -> tuple[Path, return (data_dir, *(data_dir / name for name in ROOT_HANDOFF_NAMES if (data_dir / name).exists())) +def root_should_handoff_data_dir(*, is_root: bool, data_dir_uid: int, account_uid: int | None) -> bool: + """Allow bounded handoff only for root or archivebox-owned collection roots.""" + + return is_root and account_uid is not None and data_dir_uid in (0, account_uid) + + def handoff_root_owned_data_dir() -> None: - if not (IS_ROOT and DATA_DIR_UID == 0 and ARCHIVEBOX_ACCOUNT is not None): + account_uid = ARCHIVEBOX_ACCOUNT.pw_uid if ARCHIVEBOX_ACCOUNT is not None else None + if not root_should_handoff_data_dir(is_root=IS_ROOT, data_dir_uid=DATA_DIR_UID, account_uid=account_uid): return for path in root_data_dir_handoff_paths(DATA_DIR, sys.argv): diff --git a/archivebox/tests/test_permissions.py b/archivebox/tests/test_permissions.py index ee5ac402..d10e96d4 100644 --- a/archivebox/tests/test_permissions.py +++ b/archivebox/tests/test_permissions.py @@ -1,6 +1,6 @@ from pathlib import Path -from archivebox.config.permissions import is_root_identity, select_archivebox_user +from archivebox.config.permissions import is_root_identity, root_should_handoff_data_dir, select_archivebox_user def test_root_identity_includes_real_or_effective_root(): @@ -70,6 +70,14 @@ def test_effective_root_drops_back_to_real_user(): ) == (1001, 1002) +def test_root_hands_off_root_or_archivebox_owned_collection_boundaries(): + assert root_should_handoff_data_dir(is_root=True, data_dir_uid=0, account_uid=911) + assert root_should_handoff_data_dir(is_root=True, data_dir_uid=911, account_uid=911) + assert not root_should_handoff_data_dir(is_root=True, data_dir_uid=1001, account_uid=911) + assert not root_should_handoff_data_dir(is_root=False, data_dir_uid=911, account_uid=911) + assert not root_should_handoff_data_dir(is_root=True, data_dir_uid=911, account_uid=None) + + def test_root_init_hands_off_only_an_empty_data_dir(tmp_path): from archivebox.config.permissions import root_data_dir_handoff_paths