views:

49

answers:

1

Hi,

I'm trying to use setfsuid() with python 2.5.4 and RHEL 5.4. Since it's not included in the os module, I wrapped it in a C module of my own and installed it as a python extension module using distutils.

However when I try to use it I don't get the expected result. setfsuid() returns value indicating success (changing from a superuser), but I can't access files to which only the newly set user should have user access (using open()), indicating that fsuid was not truely changed.

I tried to verify setfsuid() worked, by running it consecutively twice with the same user input The result was as if nothing had changed, and on every call the returned value was of old user id different from the new one. I also called getpid() from the module, and from the python script, both returned the same id. so this is not the problem.

Just in case it's significant, I should note that I'm doing all of this from within an Apache daemon process (WSGI).

Anyone can provide an explanation to that? Thank you

+2  A: 

The ability to change the FSUID is limited to either root or non-root processes with the CAP_SETFCAP capability. These days it's usually considered bad practice to run a webserver with root permissions so, most likely, you'll need to set the capability on the file server (see man capabilities for details). Please note that doing this could severly affect your overall system's security. I'd recommend considering spawning a small backend process that runs as root and converses with your WSGI app via a local UNIX socket prior to mucking with the security of a high-profile target like Apache.

Rakis
From what I see it's impossible to use mod_wsgi with root permissions. So it seems that I can't setfsuid anyway, and my options are:1. Do what you suggested2. Run a root process that changes the capabilities of the daemon processes before they handle requests.
That sounds about right, yeah. Depending on your app's environment, it might also be possible to use a different web server. Cherrypy is pretty simple and includes WSGI support. I haven't checked this issue in particular but it'd probably have no problems running either as root or with the CAP_SETFCAP capability.
Rakis
Thanks for the advice, but I need to use Apache, so Cherrypy is out of the question.Tried to follow my own suggestion, and quickly learnt that I need to run as kernel thread to be able to set capabilities for other processes. Kernel fiddling is really a last resort for me.I tried bypassing this by exec-ing apache startup from a program in a root process, which sets its own INHERITABLE capacilities for SETUID. That did not work -the httpd daemons all have SETUID set in INHERITABLE set, and 0 in all flags of PERMITTED AND EFFECTIVE sets.Any idea to what did I do wrong?Thank you
Kernel mode should not be necessary for the result you're looking for. Rather than trying a multi-process approach, I'd suggest trying to attach the capabilities to the Apache process with the `setcap` command. I believe this command sets some xattr properties of the executable that the kernel checks each time the program is launched. It should allow you to permanantly set the SETFCAP capability for Apache (kinda like the an enhanced sticky bit).
Rakis