diff options
| author | Christian Breunig <christian@breunig.cc> | 2025-10-09 16:02:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-09 16:02:40 +0200 |
| commit | c8759c0f89f36b9a4b603fb9587f9c2f6709edd6 (patch) | |
| tree | 47fdcb56c70dc9f5c5845b18876bb849617df613 /python | |
| parent | 1c181499a3af4b6c170d3fea2b96af58bb0a34a7 (diff) | |
| parent | 6b6f75e1fc85139e131b86117a53be1766db5fbb (diff) | |
| download | vyos-1x-c8759c0f89f36b9a4b603fb9587f9c2f6709edd6.tar.gz vyos-1x-c8759c0f89f36b9a4b603fb9587f9c2f6709edd6.zip | |
Merge pull request #4678 from alexandr-san4ez/T5455-current
image: T5455: Add migration of SSH `known_hosts` files during upgrade
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/utils/auth.py | 49 | ||||
| -rw-r--r-- | python/vyos/utils/file.py | 44 |
2 files changed, 92 insertions, 1 deletions
diff --git a/python/vyos/utils/auth.py b/python/vyos/utils/auth.py index c6803fae4..462332332 100644 --- a/python/vyos/utils/auth.py +++ b/python/vyos/utils/auth.py @@ -20,9 +20,35 @@ import string from enum import StrEnum from decimal import Decimal +from pwd import getpwall +from pwd import getpwnam from vyos.utils.process import cmd - +# Minimum UID used when adding system users +MIN_USER_UID: int = 1000 +# Maximim UID used when adding system users +MAX_USER_UID: int = 59999 +# List of local user accounts that must be preserved +SYSTEM_USER_SKIP_LIST: frozenset = { + 'radius_user', + 'radius_priv_user', + 'tacacs0', + 'tacacs1', + 'tacacs2', + 'tacacs3', + 'tacacs4', + 'tacacs5', + 'tacacs6', + 'tacacs7', + 'tacacs8', + 'tacacs9', + 'tacacs10', + 'tacacs11', + 'tacacs12', + 'tacacs13', + 'tacacs14', + 'tacacs15', +} DEFAULT_PASSWORD: str = 'vyos' LOW_ENTROPY_MSG: str = 'should be at least 8 characters long;' WEAK_PASSWORD_MSG: str = 'The password complexity is too low - @MSG@' @@ -119,3 +145,24 @@ def get_current_user() -> str: elif 'USER' in os.environ: current_user = os.environ['USER'] return current_user + + +def get_local_users(min_uid=MIN_USER_UID, max_uid=MAX_USER_UID) -> list: + """Return list of dynamically allocated users (see Debian Policy Manual)""" + local_users = [] + + for s_user in getpwall(): + if s_user.pw_uid < min_uid: + continue + if s_user.pw_uid > max_uid: + continue + if s_user.pw_name in SYSTEM_USER_SKIP_LIST: + continue + local_users.append(s_user.pw_name) + + return local_users + + +def get_user_home_dir(user: str) -> str: + """Return user's home directory""" + return getpwnam(user).pw_dir diff --git a/python/vyos/utils/file.py b/python/vyos/utils/file.py index 491cc6547..98d88d9e4 100644 --- a/python/vyos/utils/file.py +++ b/python/vyos/utils/file.py @@ -15,6 +15,7 @@ import os import tempfile +import shutil from vyos.utils.permission import chown @@ -268,3 +269,46 @@ def write_file_atomic(file_path, data: str, mode='w'): except OSError as e: cleanup() raise OSError(f'rename {e}') + +def copy_recursive(src: str, dst: str, overwrite: bool = False): + """ + Recursively copy files from `src` to `dst`. + + :param src: Source directory + :param dst: Destination directory + :param overwrite: If True, overwrite existing files. If False, skip them. + """ + + if not os.path.exists(src): + raise FileNotFoundError(f"Source path does not exist: {src}") + + os.makedirs(dst, exist_ok=True) # Create destination directory if not exists + + for root, _, files in os.walk(src): + # Find relative path to maintain directory structure + rel_path = os.path.relpath(root, src) + target_dir = os.path.join(dst, rel_path) if rel_path != "." else dst + + os.makedirs(target_dir, exist_ok=True) + + for file in files: + src_file = os.path.join(root, file) + dst_file = os.path.join(target_dir, file) + + if not os.path.exists(dst_file) or overwrite: + shutil.copy2(src_file, dst_file) + + +def move_recursive(src: str, dst: str, overwrite=False): + """ + Recursively move files from `src` to `dst` and removing the source. + + :param src: Source directory + :param dst: Destination directory + :param overwrite: If True, overwrite existing files. If False, skip them. + """ + if not os.path.exists(src): + raise FileNotFoundError(f"Source path does not exist: {src}") + + copy_recursive(src, dst, overwrite=overwrite) + shutil.rmtree(src) |
