2013-05-24

How to shutdown a linux system from within a PHP script

If you run a linux system with the Apache web server and PHP, you may want to shutdown the system from within a PHP script.

The obvious idea is to call system("shutdown -h now") from PHP, but it will not work if Apache is run by an unprivileged user (actually, it should).

Here is my solution, merging various sources from the Internet. I find it the cleanest one.

  1. Find out where shutdown is located by typing which shutdown on a shell with root privileges. On my Debian box, it is on /sbin/shutdown.
  2. Ensure you have gcc. On Debian you can get it by installing the build-essential package.
  3. Write the following C program on a text file named shutdown_suid.c:
    #include <stdlib.h>
    #include <unistd.h>
    
    int main() {
        setuid(0);
        system("/sbin/shutdown -h now"); /* change this to the actual location of shutdown */
        return 0;
    }
    
    and compile it via gcc -o shutdown_suid shutdown_suid.c.
  4. By using a shell with root privileges (or by prefixing sudo before each command), do the following.

    Move the created executable (shutdown_suid) wherever you want. I recommend the directory /usr/local/bin:
    mv shutdown_suid /usr/local/bin

    Change its owner to root:
    chown root:root /usr/local/bin/shutdown_suid

    and change its permissions to 4755:
    chmod 4755 /usr/local/bin/shutdown_suid

    This will enable the setuid bit, meaning that the executable will run with the privileges of its owner (root) regardless of “who” has launched it.

  5. Your PHP script can now call exec("/usr/local/bin/shutdown_suid") to shutdown the system.

This solution seems good to me because it doesn’t break the distro by changing the original shutdown permissions, it doesn’t rely on sudo, and it’s reasonably safe. Theoretically, you could also create a simple script and set the setuid bit on it, but on many systems this is not allowed.

Tags: linux, php
comments powered by Disqus
Fork me on GitHub