From owner-freebsd-hackers Sun Sep 22 7:15: 4 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 391D537B401 for ; Sun, 22 Sep 2002 07:15:02 -0700 (PDT) Received: from pop3.psconsult.nl (ps226.psconsult.nl [193.67.147.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id AAFF243E42 for ; Sun, 22 Sep 2002 07:14:55 -0700 (PDT) (envelope-from paul@pop3.psconsult.nl) Received: (from paul@localhost) by pop3.psconsult.nl (8.9.2/8.9.2) id QAA13571 for freebsd-hackers@freebsd.org; Sun, 22 Sep 2002 16:14:53 +0200 (CEST) (envelope-from paul) Date: Sun, 22 Sep 2002 16:14:53 +0200 From: Paul Schenkeveld To: FreeBSD Hackers Subject: Just a wild idea Message-ID: <20020922161453.A13323@psconsult.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hi All, I've been playing with jails for over 2 years now. I really like them but we often use them to run a process as root with reduced power only to get access to TCP and UDP ports below 1024. For many applications however, for example lpd, named, sendmail, tac_plus and others, it would be more than good enough to run that program as a normal, non-root user provided there is a way to bind to that single low TCP and/or UDP port that the program needs access to. So I was wondering if we couldn't come up with a method to allow the startup of a normal non-root process with the only increased power of being able to bind to a specific port. This would be the opposite of jail which allows the startup of a program as root and then tries to revoke many powers. I envision a system call (only accessible to root) that will grant bind access to a single TCP or UDP port, which will persist even after set*[ug]id calls and will be inherited by child processes and a very small setuid root wrapper program to exercise that system call, become a non-root user and then exec the real program. The synopsis for the system call could be something like this: int portaccess(int version, int protocol, const struct sockaddr *addr); where version works like with jail, protocol is either IPPROTO_TCP or IPPROTO_UDP and the addr structure holds the port number (1 .. 1023) and either INADDR_ANY or the ip address of one of the interfaces. Multiple calls should accumulate access rights so programs like bind could get access to both a UDP and TCP port. The wrapper program then should be something like: portaccess [-i user:group] -{u|t} [address:]port ... cmd args Where -i selects the identity obtained after all portaccess system calls have been made (nobody/nogroup if omitted) and -u and -t add access to a single port. Finally if all portaccess and set*[ug]id calls have been made an no error occured, execv is called with the remaining arguments starting at cmd. I understand that implementing this has quite some impact as we would have to carry around all accumulated access rights in or near the proc structure, the fork and exec calls need to be aware of this extra data and the bind system call needs to do additional checking before refusing access to a low TCP or UDP port but I think it's worth the efford. I still like jail(2) and jail(8) very much for bigger purposes like virtual hosts for shell logins or web hosting but I feel they are too heavy for small problems like named which only needs access to UDP and TCP ports 53 but can do everything else as a normal user. Any thoughts? Am I inventing something nobody is waiting for? Is something going on already that I am not aware of? Please let me know. Paul Schenkeveld, Consultant PSconsult ICT Services BV To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message