From: Tim Vaughan Date: Fri, 23 Aug 2019 22:07:25 +0000 (+0200) Subject: Drops privs after starting listener. X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=commitdiff_plain;h=e0ad9e48e55d6f46293f2e043ebd527be802bcac;p=lambdamail.git Drops privs after starting listener. --- diff --git a/lambdamail.scm b/lambdamail.scm index f1d8c46..d185d89 100644 --- a/lambdamail.scm +++ b/lambdamail.scm @@ -10,7 +10,9 @@ (chicken file) (chicken time) (chicken time posix) + (chicken process) (chicken process-context) + (chicken process-context posix) (chicken condition) srfi-1 srfi-13 matchable) @@ -18,7 +20,7 @@ (define-record config - host port spool-dir) + host port spool-dir user group) (define-record message to from text helo) (define (make-empty-message) (make-message "" "" "" "")) @@ -43,6 +45,14 @@ ;;; Server initialization ;; +(define (drop-privs config) + (let ((uid (config-user config)) + (gid (config-group config))) + (if (not (null? gid)) ; Group first, since only root can switch groups. + (set! (current-group-id) gid)) + (if (not (null? uid)) + (set! (current-user-id) uid)))) + (define (run-server config) (set-buffering-mode! (current-output-port) #:line) (let ((listener (tcp-listen (config-port config) 10 "::"))) @@ -50,6 +60,7 @@ " listening on port " (config-port config) " ...") (print "(Host name: " (config-host config) ", Spool dir: " (config-spool-dir config) ")") + (drop-privs config) (server-loop listener config))) @@ -162,21 +173,44 @@ ;; (define (print-usage progname) - (print "Usage: " progname " hostname [port [spooldir]]")) + (print "Usage:\n" + progname " -h/--help\n" + progname " [-u/--user UID] [-g/--group GID] hostname [[port [spooldir]]\n" + "\n" + "The -u and -g options can be used to set the UID and GID of the process\n" + "following the creation of the TCP port listener (which often requires root).")) (define (main) (let ((progname (pathname-file (car (argv)))) - (args (cdr (argv))) - (config (make-config "" 25 "/var/spool/mail"))) - (if (null? args) + (config (make-config "" 25 "/var/spool/mail" '() '()))) + (if (null? (cdr (argv))) (print-usage progname) - (begin - (config-host-set! config (car args)) - (unless (null? (cdr args)) - (config-port-set! config (string->number (cadr args))) - (unless (null? (cddr args)) - (config-spool-dir-set! (caddr args)))) - (run-server config))))) + (let loop ((args (cdr (argv)))) + (let ((this-arg (car args)) + (rest-args (cdr args))) + (if (string-prefix? "-" this-arg) + (cond + ((or (equal? this-arg "-u") + (equal? this-arg "--user")) + (config-user-set! config (string->number (car rest-args))) + (loop (cdr rest-args))) + ((or (equal? this-arg "-g") + (equal? this-arg "--group")) + (config-group-set! config (string->number (car rest-args))) + (loop (cdr rest-args))) + ((or (equal? this-arg "-h") + (equal? this-arg "--help")) + (print-usage progname)) + (else + (print "Unknown option " this-arg "\n") + (print-usage progname))) + (begin + (config-host-set! config this-arg) + (unless (null? rest-args) + (config-port-set! config (string->number (car rest-args))) + (unless (null? (cdr rest-args)) + (config-spool-dir-set! (cadr rest-args)))) + (run-server config)))))))) (main)