Return-Path: Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: (qmail 78775 invoked from network); 5 Dec 2007 15:12:54 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 5 Dec 2007 15:12:54 -0000 Received: (qmail 75646 invoked by uid 500); 5 Dec 2007 15:12:36 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 75587 invoked by uid 500); 5 Dec 2007 15:12:35 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 75576 invoked by uid 99); 5 Dec 2007 15:12:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 05 Dec 2007 07:12:35 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of michael@metaparadigm.com designates 203.117.131.43 as permitted sender) Received: from [203.117.131.43] (HELO metamail-vm.metaparadigm.com) (203.117.131.43) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 05 Dec 2007 15:12:34 +0000 Received: from [192.168.133.111] (cm15.gamma103.maxonline.com.sg [202.156.103.15]) (authenticated bits=0) by metamail-vm.metaparadigm.com (8.13.8/8.13.8/Debian-3) with ESMTP id lB5FBpIN024240 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 5 Dec 2007 23:12:04 +0800 Message-ID: <4756BFB2.9050308@metaparadigm.com> Date: Wed, 05 Dec 2007 23:11:46 +0800 From: Michael Clark Organization: Metaparadigm Pte Ltd User-Agent: Mozilla-Thunderbird 2.0.0.6 (X11/20071009) MIME-Version: 1.0 To: dev@httpd.apache.org Subject: [RFC] Apache Privilege Separation for WebDAV (against 2.3.0-dev) Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV 0.90.1/5011/Wed Dec 5 17:42:23 2007 on metamail-vm X-Virus-Status: Clean X-Virus-Checked: Checked by ClamAV on apache.org Hi Folks, I have been maintaining a patch against 1.3.x for privilege separation support (for WebDAV with UNIX quotas and permissions) that has been used in a production environment for quite some time (for remote access to files that are served on an internal network by samba/netatalk). http://oss.metaparadigm.com/apache-privsep/ I have finally got around to porting it to Apache 2.3.0 trunk. Below is a link to *experimental* patches for those who are interested. Also it is now working on both Linux and FreeBSD (other unices should be relatively easy, see notes below on portability issues and potential possibility for a Windows implementation). I was thinking of sending the patches to the list for some wider review. Shall I go ahead and post them here? Do let us know if any of you are interested in helping me out with this. It has some interesting applications (like the potential for implementing an iDisk type service with working quotas support). Feedback of any sort much appreciated. ~mc Apache Privilege Separation for WebDAV http://oss.metaparadigm.com/apache-privsep/2.3.0-dev/ SYNOPSIS The Privilege Separation module addresses the problem of a WebDAV virtual server only being able to write files as a single user id (usually something like 'nobody' or 'www'). The Privilege Separation module addresses this problem in a secure way by adding privilege separation to the Apache web server (conceptually similar to ssh privilege separation). A privilege separated Apache can be used to allow WebDAV write access to users home directories while both preserving and honouring unix permissions and allowing the use of unix quotas and PAM authentication. ARCHITECTURE In Privilege Separation mode Apache continues to run as an unprivileged user although an additional secure process runs as 'root'. The apache worker processes communicate with the 'root' privileged separated process via unix sockets to carry out system authentication and privileged file system operations. Namely: * Responding to PAM authentication requests pam_unix authentication is not normally possible in apache due to the unprivileged process not being able to access the shadow file. Due to the privilege separated design this is now possible. Authentication responses include a cryptographic token which encodes the users credentials and is verified in successive privileged filesystem requests made to the privsep process. * Performing privileged filesystem operations on behalf of the unprivileged apache worker processes with the privileges of the authenticated user. The cryptographic token is verified and then the effective userid is set and the filesystem operation is performed. Certain auditable points in the apache core code (core.c, request.c), mod_autoindex and mod_dav code have been changed to use the privilege separated file io calls which communicate via unix sockets to the privileged daemon. File descriptors are passed back over unix sockets for open calls. INTERFACES APR file IO calls are modified to use the privsep versions which take an additional context argument (request_rec* r): ap_privsep_stat ap_privsep_special_stat ap_privsep_file_perms_set ap_privsep_file_open ap_privsep_dir_open ap_privsep_dir_read ap_privsep_dir_make ap_privsep_dir_remove ap_privsep_file_remove ap_privsep_file_rename The privsep versions of the function fetch a token from r->notes. If the privsep token exists then the request is dispatched to the privilege separated daemon, otherwise the file io method is executed directly in the regular way. One special case exists for the stat and lstat calls made from ap_directory_walk. This is called before map_to_storage has been done and any authentication hooks. This special case needs the stat and lstat calls to be executed as root to know if the path actually exists. The security leak potential is minimised by making stat the only call that is able to be made as uid 0 and ap_directory_walk is the only routine that calls ap_privsep_special_stat. NOTE: This experimental version of privsep has modified private copies of the associated apr file io routines. It is envisioned that these additional privsep interfaces could be added to apr with an additional void *priv_context argument and a hook callback linkage with a default behaviour of passing through to the regular functions. e.g. Regular stat interface: apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool); Privsep interface: apr_status_t apr_privsep_stat(void *priv_context, apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool); PORTABILITY mod_privsep has been tested on Linux and FreeBSD. apr interfaces have been used where possible but mod_privsep relies on unix sockets (socketpair,sendmsg,recvmsg) and the ability to send file descriptors over unix sockets. It also currently depends on PAM. It should be relatively easily ported to other unix-like OS. NOTE: the opendir implementation relies on platform specific details. Specifically, that directories can be opened as file descriptors and also that the file descriptor is the first structure member of the private DIR* structure. It is potentially possible to implement this feature for Windows as a preliminary investigation shows that it is possible to pass file handles between processes. More investigation is needed. BUILDING # apply patch # run buildconf to pick up configure.in change ./buildconf LIBS=-lpam ./configure \ --enable-dav \ --enable-privsep \ --enable-authn-privsep The experimental patch-set requires the modules to be compiled in and will not link if the patch is applied and the options are not enabled. A future patch will address the issue of proper modularity. CONFIGURATION Example configuration: # Enable WebDAV and privilege separation for this directory Dav On PrivilegeSeparation On # System authentication through privilege separated PAM AuthType Basic AuthName DAV-upload AuthBasicProvider privsep Options Indexes AllowOverride None Require valid-user # Workaround for WebDAV PROPFIND bug on dirs with index files DirectoryIndex /no_directory_index DESIGN ISSUES * Single privileged separated process seriliazes stat/lstat/open * Potential solution: change to a pool of privsep processes * Overhead of PAM authentication for each request * Potential solution: cache authentication * Overhead of setgroups in each privileged operation * Route requests to a pooled process that is already switched to the required user