how to use posix_setuid to do commands as root

Posted on 2005-04-08
Last Modified: 2008-02-01
I'm trying to make a shell script in php that'll allow me to do setuid behavior to run some commands as root. before you say it, I'm aware of the security risks associated with this. Thats not what I need right now.

What I need is to figure out why this isn't allowing me to posix_setuid. What happens when I run this script as root, is that it works fine. If I run it as a non-root user though, it fails, giving the error "Operation not permitted".

I have my file permissions like so:

-rwsr-xr-x    1 root     wheel        1264 Apr  8 13:57 privsep.php

I'm running command like:


and using php version 4.2.2 on SuSE Linux 8.2

Any help MUCH appreciated.


$argv = $_SERVER['argv'];
$argc = $_SERVER['argc'];

// privsep.php

// Don't allow this script to be run from the web
if (isset($_SERVER['REQUEST_METHOD']))
   print "<br>This program is not intended to be run directly from the WWW.\n";
   return 1;

   // Original user ID
   $original_uid = posix_getuid();

   // Set our real user ID to root
   $success = posix_setuid(0);
   if (!$success)
       print "Error: Cannot setuid().\n";
       print posix_strerror(posix_get_last_error());
       return 1;


  // Drop the real UID back to the calling user ID
   $success = posix_setuid($original_uid);
   if (!$success)
       print "Error: Cannot setuid().\n";
       return 1;

   // Drop the effective UID as well
   $success = posix_seteuid($original_uid);
   if (!$success)
       print "Error: Cannot seteuid().\n";
       return 1;

   print "Success!\n";
   return 0;
Question by:umbrae
    LVL 7

    Accepted Solution

    Hi umbrae, before I answer allow me to say: there are some serious security risks here with what you're trying to do!   ;)

    The problem is, that you're logged in as a regular user when you're running the script and forcing a change to root without providing credentials.  Obviously, linux has to reject this - imagine if I had an account on your system, I could run this PHP script on your machine and use poxis_setuid(0) to hijack the box!  So for security reasons, only root has the authority to poxis_setuid(0)...

    The best solution would be to add executable group privileges for each command you're trying to envoke and then add the user trying to run the script to that group...  This way you are also watching out for your security by explicity specifying which users may run certain commands.
    LVL 7

    Expert Comment

    IE, your problem lies not within PHP but with permission levels of linux :_)
    LVL 5

    Author Comment

    I was under the impression that if the file was owned by root, had the setuid bit (whichshould be set by root only ever), it was fully intended to do restricted root behavior with a normal user.

    But I'll check out things further and if nobody else comes up with a better solution, I'll give you the points.
    LVL 25

    Assisted Solution

    This isn't quite what you're doing, but it may be helpful anyway. I use a daemon script that forks a new process, detaches from a terminal, and switches IDs from a root account to one with lower privs:

    //Fork a child process
    $pid = pcntl_fork();
    if ($pid == -1)
          die('Could not fork');
    else if ($pid)
          exit(); //we are the parent, so exit
    //Detach child from terminal
    if (!posix_setsid())
          die('Could not detach from terminal.');
    $pid = posix_getpid(); //get our new process ID
    //Write out our PID somewhere for other processes to see (before we setuid)
    if ($pidfile = fopen('/var/run/', 'w')) {
          fwrite($pidfile, "$pid");
    //Get user and group IDs we want
    $groupinfo = posix_getgrnam("myuser");
    $userinfo = posix_getpwnam("mygroup");
    if ($userinfo == FALSE or $groupinfo == FALSE)
          die('Target user and/or group don\'t exist.');
    //Set GID and UID (in that order)
    $g = posix_setgid($groupid = $groupinfo["gid"]);
    $u = posix_setuid($userinfo["uid"]);
    if (!($u and $g))
          die('Problem switching uid/gid.');

    setuid does do what you say, so just make sure you're doing it right:

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
    Part of the Global Positioning System A geocode ( is the major subset of a GPS coordinate (, the other parts being the altitude and t…
    Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

    759 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    9 Experts available now in Live!

    Get 1:1 Help Now