From 7e34e266e7bb8678c720e73ceb661d339f9dfd15 Mon Sep 17 00:00:00 2001 From: themylogin Date: Tue, 17 Dec 2024 21:55:48 +0100 Subject: [PATCH] Allow `cron` to call private methods --- .../api/base/server/ws_handler/rpc.py | 10 +++++++ src/middlewared/middlewared/utils/origin.py | 26 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/middlewared/middlewared/api/base/server/ws_handler/rpc.py b/src/middlewared/middlewared/api/base/server/ws_handler/rpc.py index f7c18d82dcec..c5104319f191 100644 --- a/src/middlewared/middlewared/api/base/server/ws_handler/rpc.py +++ b/src/middlewared/middlewared/api/base/server/ws_handler/rpc.py @@ -289,6 +289,16 @@ def _can_call_private_methods(self, app: RpcWebSocketApp): # System-initiated calls to `midclt` return True + if ppids := app.origin.ppids(): + try: + with open("/run/crond.pid") as f: + cron_pid = int(f.read()) + except (FileNotFoundError, ValueError): + return False + + if cron_pid in ppids: + return True + return False async def process_method_call(self, app: RpcWebSocketApp, id_: Any, method: Method, params: list): diff --git a/src/middlewared/middlewared/utils/origin.py b/src/middlewared/middlewared/utils/origin.py index 8ccaeb7eb91e..5cccceacd6b7 100644 --- a/src/middlewared/middlewared/utils/origin.py +++ b/src/middlewared/middlewared/utils/origin.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from functools import cached_property +import re from socket import AF_INET, AF_INET6, AF_UNIX, SO_PEERCRED, SOL_SOCKET from struct import calcsize, unpack @@ -113,6 +113,30 @@ def loginuid(self) -> int | None: return loginuid + def ppids(self) -> set[int]: + if self.pid is None: + return set() + + pid = self.pid + ppids = set() + while True: + try: + with open(f"/proc/{pid}/status") as f: + status = f.read() + except FileNotFoundError: + break + + if m := re.search(r"PPid:\t([0-9]+)", status): + pid = int(m.group(1)) + if pid <= 1: + break + + ppids.add(pid) + else: + break + + return ppids + def get_tcp_ip_info(sock, request) -> tuple: # All API connections are terminated by nginx reverse