From 6eaec885515fb62a05a8fc736c9beddd0e39301e Mon Sep 17 00:00:00 2001 From: Aleš Mrázek Date: Mon, 23 Sep 2024 17:57:26 +0200 Subject: datamodel: types: files: improvements - compare intended uid with current working uid - check permissions for current user and group - use os.getuid() and pwd.getpwuid() instead of os.getlogin() #919 --- python/knot_resolver/datamodel/types/files.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'python/knot_resolver') diff --git a/python/knot_resolver/datamodel/types/files.py b/python/knot_resolver/datamodel/types/files.py index c2962729..21f6d3ad 100644 --- a/python/knot_resolver/datamodel/types/files.py +++ b/python/knot_resolver/datamodel/types/files.py @@ -1,15 +1,18 @@ +import logging import os import stat from enum import Flag, auto from grp import getgrnam from pathlib import Path -from pwd import getpwnam +from pwd import getpwnam, getpwuid from typing import Any, Dict, Tuple, Type, TypeVar from knot_resolver.constants import GROUP, USER from knot_resolver.datamodel.globals import get_resolve_root, get_strict_validation from knot_resolver.utils.modeling.base_value_type import BaseValueType +logger = logging.Logger(__name__) + class UncheckedPath(BaseValueType): """ @@ -157,9 +160,24 @@ def _kres_accessible(dest_path: Path, perm_mode: _PermissionMode) -> bool: _PermissionMode.EXECUTE: [stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH], } + # process working user id + pwuid = os.getuid() + pwgid = os.getgid() + + # defaults user_uid = getpwnam(USER).pw_uid user_gid = getgrnam(GROUP).gr_gid + # if current user do not match intended user + # log warning message and check permissions for current user running the manager + if pwuid != user_uid: + logger.warning( + f"Knot Resolver does not run under the intended '{USER}' user, '{getpwuid(pwuid).pw_name}' instead." + " This may or may not affect the configuration validation and the proper functioning of the resolver." + ) + user_uid = pwuid + user_gid = pwgid + dest_stat = os.stat(dest_path) dest_uid = dest_stat.st_uid dest_gid = dest_stat.st_gid @@ -168,13 +186,13 @@ def _kres_accessible(dest_path: Path, perm_mode: _PermissionMode) -> bool: def accessible(perm: _PermissionMode) -> bool: if user_uid == dest_uid: return bool(dest_mode & chflags[perm][0]) - b_groups = os.getgrouplist(os.getlogin(), user_gid) + b_groups = os.getgrouplist(getpwuid(pwuid).pw_name, user_gid) if user_gid == dest_gid or dest_gid in b_groups: return bool(dest_mode & chflags[perm][1]) return bool(dest_mode & chflags[perm][2]) # __iter__ for class enum.Flag added in python3.11 - # 'for perm in perm_mode:' failes for <=python3.11 + # 'for perm in perm_mode:' fails for <=python3.11 for perm in _PermissionMode: if perm in perm_mode: if not accessible(perm): -- cgit v1.2.3