From 108958cabb1bea71955100b84a7def87c94ebca4 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 23 Dec 2022 10:58:06 +0100 Subject: [PATCH] drop privs better --- core/admin/start.py | 5 +---- core/base/libs/socrate/socrate/system.py | 8 ++++++++ core/dovecot/start.py | 5 +---- core/postfix/start.py | 5 ++--- optional/fetchmail/fetchmail.py | 3 +-- webmails/start.py | 13 +++++-------- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/core/admin/start.py b/core/admin/start.py index 6aa0d1a4..9b1ef530 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -2,15 +2,12 @@ import os import logging as log -from pwd import getpwnam import sys from socrate import system os.system("chown mailu:mailu -R /dkim") os.system("find /data | grep -v /fetchmail | xargs -n1 chown mailu:mailu") -mailu_id = getpwnam('mailu') -os.setgid(mailu_id.pw_gid) -os.setuid(mailu_id.pw_uid) +system.drop_privs_to('mailu') log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "INFO")) system.set_env(['SECRET']) diff --git a/core/base/libs/socrate/socrate/system.py b/core/base/libs/socrate/socrate/system.py index 96247158..1e64c5b9 100644 --- a/core/base/libs/socrate/socrate/system.py +++ b/core/base/libs/socrate/socrate/system.py @@ -1,6 +1,7 @@ import hmac import logging as log import os +from pwd import getpwnam import socket import tenacity @@ -45,3 +46,10 @@ def set_env(required_secrets=[]): def clean_env(): """ remove all secret keys """ [os.environ.pop(key, None) for key in os.environ.keys() if key.endswith("_KEY")] + +def drop_privs_to(username='mailu'): + pwnam = getpwnam(username) + os.setgroups([]) + os.setgid(pwnam.pw_gid) + os.setuid(pwnam.pw_uid) + os.environ['HOME'] = pwnam.pw_dir diff --git a/core/dovecot/start.py b/core/dovecot/start.py index 4da7a09c..fcdc9559 100755 --- a/core/dovecot/start.py +++ b/core/dovecot/start.py @@ -5,7 +5,6 @@ import glob import multiprocessing import logging as log import sys -from pwd import getpwnam from podop import run_server from socrate import system, conf @@ -14,9 +13,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) system.set_env() def start_podop(): - id_mail = getpwnam('mail') - os.setgid(id_mail.pw_gid) - os.setuid(id_mail.pw_uid) + system.drop_privs_to('mail') url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/dovecot/ยง" run_server(0, "dovecot", "/tmp/podop.socket", [ ("quota", "url", url ), diff --git a/core/postfix/start.py b/core/postfix/start.py index b9a058f7..8d8c545f 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -9,7 +9,6 @@ import sys import re from podop import run_server -from pwd import getpwnam from socrate import system, conf log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) @@ -18,7 +17,7 @@ system.set_env() os.system("flock -n /queue/pid/master.pid rm /queue/pid/master.pid") def start_podop(): - os.setuid(getpwnam('postfix').pw_uid) + system.drop_privs_to('postfix') os.makedirs('/dev/shm/postfix',mode=0o700, exist_ok=True) url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/" # TODO: Remove verbosity setting from Podop? @@ -36,7 +35,7 @@ def start_podop(): def start_mta_sts_daemon(): os.chmod("/root/", 0o755) # read access to /root/.netrc required - os.setuid(getpwnam('postfix').pw_uid) + system.drop_privs_to('postfix') from postfix_mta_sts_resolver import daemon daemon.main() diff --git a/optional/fetchmail/fetchmail.py b/optional/fetchmail/fetchmail.py index 97622feb..af569440 100755 --- a/optional/fetchmail/fetchmail.py +++ b/optional/fetchmail/fetchmail.py @@ -97,8 +97,7 @@ if __name__ == "__main__": os.chown("/data/fetchids", id_fetchmail.pw_uid, id_fetchmail.pw_gid) os.chown("/data/", id_fetchmail.pw_uid, id_fetchmail.pw_gid) os.chmod("/data/fetchids", 0o700) - os.setgid(id_fetchmail.pw_gid) - os.setuid(id_fetchmail.pw_uid) + system.drop_privs_to('fetchmail') config = system.set_env() while True: delay = int(os.environ.get('FETCHMAIL_DELAY', 60)) diff --git a/webmails/start.py b/webmails/start.py index 954c8407..84d05654 100755 --- a/webmails/start.py +++ b/webmails/start.py @@ -2,7 +2,6 @@ import os import logging -from pwd import getpwnam import sys import subprocess import shutil @@ -78,17 +77,15 @@ conf.jinja("/defaults/php.ini", context, "/etc/php81/php.ini") # setup permissions os.system("chown -R mailu:mailu /data") -def demote(user_uid, user_gid): +def demote(username='mailu'): def result(): - os.setgid(user_gid) - os.setuid(user_uid) + system.drop_privs_to(username) return result -id_mailu = getpwnam('mailu') print("Initializing database") try: result = subprocess.check_output(["/var/www/roundcube/bin/initdb.sh", "--dir", "/var/www/roundcube/SQL"], - stderr=subprocess.STDOUT, preexec_fn=demote(id_mailu.pw_uid,id_mailu.pw_gid)) + stderr=subprocess.STDOUT, preexec_fn=demote()) print(result.decode()) except subprocess.CalledProcessError as exc: err = exc.stdout.decode() @@ -100,13 +97,13 @@ except subprocess.CalledProcessError as exc: print("Upgrading database") try: - subprocess.check_call(["/var/www/roundcube/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT, preexec_fn=demote(id_mailu.pw_uid,id_mailu.pw_gid)) + subprocess.check_call(["/var/www/roundcube/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT, preexec_fn=demote()) except subprocess.CalledProcessError as exc: exit(4) else: print("Cleaning database") try: - subprocess.check_call(["/var/www/roundcube/bin/cleandb.sh"], stderr=subprocess.STDOUT, preexec_fn=demote(id_mailu.pw_uid,id_mailu.pw_gid)) + subprocess.check_call(["/var/www/roundcube/bin/cleandb.sh"], stderr=subprocess.STDOUT, preexec_fn=demote()) except subprocess.CalledProcessError as exc: exit(5)