Find the answer to your Linux question:
Results 1 to 8 of 8
I am attempting to write a script in PHP to create a new user, a home directory, and chown/chmod the directory so that it can be used by the new ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jun 2005
    Posts
    5

    Creating new users with PHP


    I am attempting to write a script in PHP to create a new user, a home directory, and chown/chmod the directory so that it can be used by the new user via FTP. My problem is that PHP will not allow me to execute useradd, chmod, or chown, since my web server is not running as root (obviously). I have tried using PHP to execute a shell script, and just passing the shell script the variables from PHP using shell_exec(). My problem now is, my script doesn't seem to work quite right. This is probably an easy fix, but this is my first time working with shell scripts. Take a look.
    Code:
    #!/bin/sh
    #include <sys/types.h>
    #include <unistd.h>
    
    setuid&#40;0&#41;;
    useradd -d $1 -g teachers -m -k $2 -p $3 -s /dev/null $4
    chown $4&#58;teachers $1
    chmod 755 $1
    As you can see, I am attempting to run the script as root, so that useradd, chown, and chmod will work. $1 is the home directory, $2 is the skeleton directory, $3 is the encrypted password, and $4 is the username. If you know what I am doing wrong, or have an alternative idea, rather than using a shell script, PLEASE let me know. I need to get this part of my project finished relatively soon, which is why I'm asking for your help. Thanks in advance!

  2. #2
    Linux Enthusiast
    Join Date
    Jan 2005
    Posts
    575
    Can I ask what purpose the lines
    Code:
    #include <sys/types.h>
    #include <unistd.h>
    serve ?

  3. #3
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Well... I don't mean to be mean or anything, but it's rather obvious that it's your first time working with shell scripts. What you have described there is not a shell script, but some weird mixture of C and shell scripting.

    The #include and setuid lines are C-specific. Even if they weren't though, they still wouldn't work. The shell script, being invoked by PHP code running in the web server, will still run as the same user that the web server runs as, and, obviously, no user is allowed to change UID to root. In fact, only root is allowed to change setuid at all (except in some special circumstances that I'd rather not go into right now).

    What you need is a SUID root program. Unfortunately, Linux doesn't allow any interpreted scripts to be SUID (actually, it does allow it, it just ignores it), so you'll actually need a C program to do the job. I'd suggest something like this:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    
    #define GID_OF_TEACHERS 150 /* Replace this */
    
    char buf&#91;1024&#93;;
    
    int main&#40;int argc, char **argv&#41;
    &#123;
        if&#40;argc < 5&#41; &#123;
            fprintf&#40;stderr, "usage&#58; apache-useradd homedir skeldir passwd username\n"&#41;;
            exit&#40;1&#41;;
        &#125;
        if&#40;snprintf&#40;buf, sizeof&#40;buf&#41;, "useradd -d %s -g teachers -s -k %s -p %s -s /dev/null %s", argv&#91;1&#93;, argv&#91;2&#93;, argv&#91;3&#93;, argv&#91;4&#93;&#41; >= sizeof&#40;buf&#41;&#41; &#123;
            fprintf&#40;stderr, "arguments were too long\n"&#41;;
            exit&#40;1&#41;;
        &#125;
        if&#40;system&#40;buf&#41;&#41; &#123;
            fprintf&#40;stderr, "useradd failed\n"&#41;;
            exit&#40;1&#41;;
        &#125;
        chown&#40;argv&#91;1&#93;, -1, GID_OF_TEACHERS&#41;;
        chmod&#40;argv&#91;1&#93;, 0755&#41;;
        return&#40;0&#41;;
    &#125;
    Then compile it with something similar to this:
    Code:
    gcc -g -Wall -o apache-useradd apache-useradd.c
    And then chmod it to a SUID program, like this:
    Code:
    chmod 4755 apache-useradd
    And, of course, ensure that it's owned by root.

    Mind you, however, that in this reincarnation, this program is an enormous security risk. Anyone could create a user or create directories every here and and anything. If you really, really, really trust your web server (remember that it, too, may be able to get cracked, however), and it's running with the GID of the apache group, you could do it like this:
    Code:
    chown root&#58;apache apache-useradd
    chmod 4754 apache-useradd
    So that only the web server can run it. Again, though, remember that even if you trust what's running on your web server, it might even get cracked.

    Also, I haven't actually tried to compile that program, so it may well contain a typo or three.

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Enthusiast
    Join Date
    Jan 2005
    Posts
    575
    What you need is a SUID root program. Unfortunately, Linux doesn't allow any interpreted scripts to be SUID (actually, it does allow it, it just ignores it), so you'll actually need a C program to do the job.
    Is this certain ? I think Bash ignores SUID but other shells may not.

    Anyway using system() is an additional security risk.
    execve() is to be preferred.

  6. #5
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Quote Originally Posted by Santa's little helper
    What you need is a SUID root program. Unfortunately, Linux doesn't allow any interpreted scripts to be SUID (actually, it does allow it, it just ignores it), so you'll actually need a C program to do the job.
    Is this certain ? I think Bash ignores SUID but other shells may not.
    No, it's the kernel itself that ignores SUID on interpreted executables. Well, I haven't actually checked the kernel source, but I haven't found a single interpreter that can do SUID on Linux, so I'm assuming it to be the kernel. Also, if you create a SUID shell script, run it, and then look in /proc on its process directory, the pseudo-files in there are owned by your original user and not the SUID target user, which indicates to me that the kernel ignores it.

    Quote Originally Posted by Santa's little helper
    Anyway using system() is an additional security risk.
    execve() is to be preferred.
    Naturally, but since it's so unsafe either way, I didn't really care. ;-)

  7. #6
    Linux Enthusiast
    Join Date
    Jan 2005
    Posts
    575
    It seems that you're right.From the man page on execve
    Linux ignores the SUID and SGID bits on scripts.

  8. #7
    Just Joined!
    Join Date
    Jun 2005
    Posts
    5

    wow

    LOL. Wow. I was WAAAY off. Shell scripts have always been somewhat of a mystery to me. I've been able to read some here and there, but never made too much sense. Some time I'll sit down and read a tutorial on shell scripting and other essential linux languages. For now, this should work. I'm not too worried about security on this machine, since it won't be mine once I write the script for it. Anyway, thanks for all your help.

  9. #8
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Shell scripts really aren't that curious in themselves. A shell script is nothing more than a sequence of normal shell commands that are carried out in turn.

    Of course, there are some shell commands that can by themselves be quite complex, but that they are regardlessly ov whether they are used in scripts or in an interactive shell.

    You may want to check out http://www.linuxcommand.org/.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •