]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
python: datamodel: added permissions_default to global validation context docs-develop-data-nk5iee/deployments/5243
authorAleš Mrázek <ales.mrazek@nic.cz>
Tue, 24 Sep 2024 08:40:45 +0000 (10:40 +0200)
committerAleš Mrázek <ales.mrazek@nic.cz>
Mon, 30 Sep 2024 09:35:56 +0000 (11:35 +0200)
It is used to change the check of dirs/files permissions against the default constant user:group or the current user the process is running as.

python/knot_resolver/datamodel/globals.py
python/knot_resolver/datamodel/types/files.py
python/knot_resolver/manager/server.py

index 88f95c2a4d3cf677371505e727729b003c9f94d2..044cf475b1881c5ceab829f6fe49222832233fd7 100644 (file)
@@ -24,10 +24,14 @@ from typing import Optional
 class Context:
     resolve_root: Optional[Path]
     strict_validation: bool
+    permissions_default: bool
 
-    def __init__(self, resolve_root: Optional[Path], strict_validation: bool = True) -> None:
+    def __init__(
+        self, resolve_root: Optional[Path], strict_validation: bool = True, permissions_default: bool = True
+    ) -> None:
         self.resolve_root = resolve_root
         self.strict_validation = strict_validation
+        self.permissions_default = permissions_default
 
 
 _global_context: Context = Context(None)
@@ -59,3 +63,7 @@ def get_resolve_root() -> Path:
 
 def get_strict_validation() -> bool:
     return _global_context.strict_validation
+
+
+def get_permissions_default() -> bool:
+    return _global_context.permissions_default
index 21f6d3ad886068649ad437e074a814c1e153496f..2d22d075a2da9e073f9462f645e2fa4a6d963327 100644 (file)
@@ -1,4 +1,3 @@
-import logging
 import os
 import stat
 from enum import Flag, auto
@@ -8,11 +7,9 @@ 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.datamodel.globals import get_permissions_default, get_resolve_root, get_strict_validation
 from knot_resolver.utils.modeling.base_value_type import BaseValueType
 
-logger = logging.Logger(__name__)
-
 
 class UncheckedPath(BaseValueType):
     """
@@ -160,23 +157,14 @@ 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
+    if get_permissions_default():
+        user_uid = getpwnam(USER).pw_uid
+        user_gid = getgrnam(GROUP).gr_gid
+        username = USER
+    else:
+        user_uid = os.getuid()
+        user_gid = os.getgid()
+        username = getpwuid(user_uid).pw_name
 
     dest_stat = os.stat(dest_path)
     dest_uid = dest_stat.st_uid
@@ -186,7 +174,7 @@ 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(getpwuid(pwuid).pw_name, user_gid)
+        b_groups = os.getgrouplist(username, 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])
index 059e45de07e184740be24124229df8325d375f38..18a2aebc247d241c2c5d533a4fc05e189d469d9f 100644 (file)
@@ -536,8 +536,10 @@ async def start_server(config: Path = CONFIG_FILE) -> int:
         config_raw = await _load_raw_config(config)
 
         # before processing any configuration, set validation context
-        #  - resolve_root = root against which all relative paths will be resolved
-        set_global_validation_context(Context(config.parent, True))
+        #  - resolve_root: root against which all relative paths will be resolved
+        #  - strict_validation: check for path existence during configuration validation
+        #  - permissions_default: validate dirs/files rwx permissions against default user:group in constants
+        set_global_validation_context(Context(config.parent, True, False))
 
         # We want to change cwd as soon as possible. Some parts of the codebase are using os.getcwd() to get the
         # working directory.