#
# Erminig - Fonctions pour gérer les utilisateurs système.
# Copyright (C) 2025 L0m1g
# Sous licence DOUARN - Voir le fichier LICENCE pour les détails
#
# Ce fichier fait partie du projet Erminig.
# Libre comme l’air, stable comme un menhir, et salé comme le beurre.
#

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 : attendre le child, ne pas exit, juste return proprement
                    _, status = os.waitpid(pid, 0)
                    return (
                        status >> 8
                    )  # récupère le code retour du fils (comme exit code)

                # 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)

                result = func(*args, **kwargs)
                os._exit(0 if result is None else int(bool(result)))

            except OSError as e:
                print(f"[SECURITY] Fork échoué : {e}")
                os._exit(1)

        return wrapper

    return decorator
