56 lines
1.5 KiB
Python
56 lines
1.5 KiB
Python
|
|
import os
|
||
|
|
import pwd
|
||
|
|
import sys
|
||
|
|
import functools
|
||
|
|
|
||
|
|
|
||
|
|
def check_root():
|
||
|
|
"""Vérifie si on est root, sinon quitte."""
|
||
|
|
if os.geteuid() != 0:
|
||
|
|
print("[SECURITY] Ce programme doit être exécuté en tant que root.")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
|
||
|
|
def check_user_exists(username):
|
||
|
|
"""Vérifie si l'utilisateur spécifié existe."""
|
||
|
|
try:
|
||
|
|
pwd.getpwnam(username)
|
||
|
|
return True
|
||
|
|
except KeyError:
|
||
|
|
print(f"[SECURITY] Utilisateur '{username}' introuvable.")
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
def run_as_user(username):
|
||
|
|
"""Décorateur : Fork et drop privileges pour exécuter une fonction sous un autre utilisateur."""
|
||
|
|
|
||
|
|
def decorator(func):
|
||
|
|
@functools.wraps(func)
|
||
|
|
def wrapper(*args, **kwargs):
|
||
|
|
try:
|
||
|
|
pid = os.fork()
|
||
|
|
if pid > 0:
|
||
|
|
# Parent
|
||
|
|
_, status = os.waitpid(pid, 0)
|
||
|
|
return os.WEXITSTATUS(status)
|
||
|
|
|
||
|
|
# Child
|
||
|
|
pw_record = pwd.getpwnam(username)
|
||
|
|
user_uid = pw_record.pw_uid
|
||
|
|
user_gid = pw_record.pw_gid
|
||
|
|
|
||
|
|
os.setgid(user_gid)
|
||
|
|
os.setuid(user_uid)
|
||
|
|
|
||
|
|
# Exécuter la fonction sous l'utilisateur demandé
|
||
|
|
result = func(*args, **kwargs)
|
||
|
|
sys.exit(0 if result is None else int(bool(result)))
|
||
|
|
|
||
|
|
except OSError as e:
|
||
|
|
print(f"[SECURITY] Fork échoué : {e}")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
return wrapper
|
||
|
|
|
||
|
|
return decorator
|