2598: drop privs better r=mergify[bot] a=nextgens

## What type of PR?

bug-fix

## What does this PR do?

Without this we may see the following:
```
Initializing database
PHP Deprecated:  Return type of zipdownload_mbox_filter::filter($in, $out, &$consumed, $closing) should either be compatible with php_user_filter::filter($in, $out, &$consumed, bool $closing): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/roundcube/plugins/zipdownload/zipdownload.php on line 405
PHP Fatal error:  [snuffleupagus][0.0.0.0][readonly_exec][drop] Attempted execution of a writable file (/var/www/roundcube/plugins/mailu/mailu.php) in /var/www/roundcube/program/lib/Roundcube/rcube_plugin_api.php on line 204
Fatal error: Please check the Roundcube error log and/or server error logs for more information.
```

This has been confirmed to fix it.

### Related issue(s)

## Prerequisites
Before we can consider review and merge, please make sure the following list is done and checked.
If an entry in not applicable, you can check it or remove it from the list.

- [ ] In case of feature or enhancement: documentation updated accordingly
- [ ] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file.


Co-authored-by: Florent Daigniere <nextgens@freenetproject.org>
main
bors[bot] 2 years ago committed by GitHub
commit e9175da586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,15 +2,12 @@
import os import os
import logging as log import logging as log
from pwd import getpwnam
import sys import sys
from socrate import system from socrate import system
os.system("chown mailu:mailu -R /dkim") os.system("chown mailu:mailu -R /dkim")
os.system("find /data | grep -v /fetchmail | xargs -n1 chown mailu:mailu") os.system("find /data | grep -v /fetchmail | xargs -n1 chown mailu:mailu")
mailu_id = getpwnam('mailu') system.drop_privs_to('mailu')
os.setgid(mailu_id.pw_gid)
os.setuid(mailu_id.pw_uid)
log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "INFO")) log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "INFO"))
system.set_env(['SECRET']) system.set_env(['SECRET'])

@ -1,6 +1,7 @@
import hmac import hmac
import logging as log import logging as log
import os import os
from pwd import getpwnam
import socket import socket
import tenacity import tenacity
@ -45,3 +46,10 @@ def set_env(required_secrets=[]):
def clean_env(): def clean_env():
""" remove all secret keys """ """ remove all secret keys """
[os.environ.pop(key, None) for key in os.environ.keys() if key.endswith("_KEY")] [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

@ -5,7 +5,6 @@ import glob
import multiprocessing import multiprocessing
import logging as log import logging as log
import sys import sys
from pwd import getpwnam
from podop import run_server from podop import run_server
from socrate import system, conf from socrate import system, conf
@ -14,9 +13,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
system.set_env() system.set_env()
def start_podop(): def start_podop():
id_mail = getpwnam('mail') system.drop_privs_to('mail')
os.setgid(id_mail.pw_gid)
os.setuid(id_mail.pw_uid)
url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/dovecot/§" url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/dovecot/§"
run_server(0, "dovecot", "/tmp/podop.socket", [ run_server(0, "dovecot", "/tmp/podop.socket", [
("quota", "url", url ), ("quota", "url", url ),

@ -9,7 +9,6 @@ import sys
import re import re
from podop import run_server from podop import run_server
from pwd import getpwnam
from socrate import system, conf from socrate import system, conf
log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) 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") os.system("flock -n /queue/pid/master.pid rm /queue/pid/master.pid")
def start_podop(): def start_podop():
os.setuid(getpwnam('postfix').pw_uid) system.drop_privs_to('postfix')
os.makedirs('/dev/shm/postfix',mode=0o700, exist_ok=True) os.makedirs('/dev/shm/postfix',mode=0o700, exist_ok=True)
url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/" url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/"
# TODO: Remove verbosity setting from Podop? # TODO: Remove verbosity setting from Podop?
@ -36,7 +35,7 @@ def start_podop():
def start_mta_sts_daemon(): def start_mta_sts_daemon():
os.chmod("/root/", 0o755) # read access to /root/.netrc required 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 from postfix_mta_sts_resolver import daemon
daemon.main() daemon.main()

@ -97,8 +97,7 @@ if __name__ == "__main__":
os.chown("/data/fetchids", id_fetchmail.pw_uid, id_fetchmail.pw_gid) os.chown("/data/fetchids", id_fetchmail.pw_uid, id_fetchmail.pw_gid)
os.chown("/data/", 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.chmod("/data/fetchids", 0o700)
os.setgid(id_fetchmail.pw_gid) system.drop_privs_to('fetchmail')
os.setuid(id_fetchmail.pw_uid)
config = system.set_env() config = system.set_env()
while True: while True:
delay = int(os.environ.get('FETCHMAIL_DELAY', 60)) delay = int(os.environ.get('FETCHMAIL_DELAY', 60))

@ -2,7 +2,6 @@
import os import os
import logging import logging
from pwd import getpwnam
import sys import sys
import subprocess import subprocess
import shutil import shutil
@ -78,17 +77,15 @@ conf.jinja("/defaults/php.ini", context, "/etc/php81/php.ini")
# setup permissions # setup permissions
os.system("chown -R mailu:mailu /data") os.system("chown -R mailu:mailu /data")
def demote(user_uid, user_gid): def demote(username='mailu'):
def result(): def result():
os.setgid(user_gid) system.drop_privs_to(username)
os.setuid(user_uid)
return result return result
id_mailu = getpwnam('mailu')
print("Initializing database") print("Initializing database")
try: try:
result = subprocess.check_output(["/var/www/roundcube/bin/initdb.sh", "--dir", "/var/www/roundcube/SQL"], 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()) print(result.decode())
except subprocess.CalledProcessError as exc: except subprocess.CalledProcessError as exc:
err = exc.stdout.decode() err = exc.stdout.decode()
@ -100,13 +97,13 @@ except subprocess.CalledProcessError as exc:
print("Upgrading database") print("Upgrading database")
try: 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: except subprocess.CalledProcessError as exc:
exit(4) exit(4)
else: else:
print("Cleaning database") print("Cleaning database")
try: 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: except subprocess.CalledProcessError as exc:
exit(5) exit(5)

Loading…
Cancel
Save