user management fix

This commit is contained in:
2026-09-17 16:14:19 +05:00
parent 298124c30f
commit 77c00c4ed5
3 changed files with 327 additions and 391 deletions
+60 -5
View File
@@ -1,6 +1,8 @@
import json
import os
import socket
import sqlite3
import struct
import subprocess
import threading
@@ -16,6 +18,10 @@ BUFFER_SIZE = 65536
POLKIT_ACTION = "org.sarlink.parentalcontrol.modify"
# ============================================================
# Peer credentials and authorization
# ============================================================
def get_peer_credentials(connection):
credentials = connection.getsockopt(
socket.SOL_SOCKET,
@@ -26,7 +32,19 @@ def get_peer_credentials(connection):
return struct.unpack("3i", credentials)
def authorize_write(pid: int) -> bool:
def authorize_write(pid: int, uid: int) -> bool:
"""
Authorize administrative operations.
Root is automatically authorized.
Non-root users must pass Polkit authorization.
"""
# Root is already an administrator.
if uid == 0:
return True
try:
os.kill(pid, 0)
except OSError:
@@ -53,6 +71,10 @@ def authorize_write(pid: int) -> bool:
return False
# ============================================================
# Database operations
# ============================================================
class IPCOperations:
@staticmethod
@@ -359,6 +381,10 @@ class IPCOperations:
)
# ============================================================
# Allowed IPC methods
# ============================================================
READ_METHODS = {
"get_users",
"get_user",
@@ -377,7 +403,15 @@ WRITE_METHODS = {
}
def handle_request(request, pid):
# ============================================================
# Request handling
# ============================================================
def handle_request(
request,
pid,
uid,
):
method = request.get("method")
arguments = request.get("args", {})
@@ -396,7 +430,7 @@ def handle_request(request, pid):
return operation(**arguments)
if method in WRITE_METHODS:
if not authorize_write(pid):
if not authorize_write(pid, uid):
raise PermissionError(
"Administrative authorization required"
)
@@ -419,6 +453,10 @@ def handle_request(request, pid):
)
# ============================================================
# Client handling
# ============================================================
def handle_client(connection):
try:
pid, uid, gid = get_peer_credentials(
@@ -456,6 +494,7 @@ def handle_client(connection):
result = handle_request(
request,
pid,
uid,
)
response = {
@@ -470,6 +509,13 @@ def handle_client(connection):
"error_type": "authorization",
}
except sqlite3.IntegrityError as exc:
response = {
"ok": False,
"error": str(exc),
"error_type": "database",
}
except Exception as exc:
response = {
"ok": False,
@@ -500,6 +546,10 @@ def handle_client(connection):
connection.close()
# ============================================================
# IPC server
# ============================================================
class IPCServer:
def __init__(
@@ -515,7 +565,10 @@ class IPCServer:
self._stop_event = threading.Event()
def start(self):
if self._thread is not None:
if (
self._thread is not None
and self._thread.is_alive()
):
return
self.socket_path.parent.mkdir(
@@ -564,7 +617,9 @@ class IPCServer:
pass
if self._thread is not None:
self._thread.join(timeout=2)
self._thread.join(
timeout=2
)
self._thread = None
self.server_socket = None