norm has asked for the wisdom of the Perl Monks concerning the following question:

I've been poking around on the web trying to get info on how to get around using 777 for the permissions of files I want a script to modify. I've figured out that I should be using a setuid script (right?), and that I should make the permissions something like 7555, but things are still working, so I was hoping someone could explain the nuances and subtleties of such creatures.

Thanks,
oren

Replies are listed 'Best First'.
Re: setuid scripts
by cleen (Pilgrim) on Jul 08, 2000 at 03:14 UTC
    To make this short and sweet, you want to look into 'suidperl' or sperl. This allows for the script to be run securly (unless -U is specified) while changing the effective user id of the process it will run under. You dont really need to set somthing 777 to modify a file, having user write permissions or group write permissions should be the way to go. I dont think making somthing setuid in this case would be a good idea, unless you want multiple users in multiple groups (still you should just add them to a central group that has permission to write to that specified file)to have access to that file.

    having somthing setuid is usually somthing that is done for giving rights to things that a normal user shouldnt usually have rights to. (IE icmp using ping or somthing). Though sperl does provide a good basis for "not messing up and keeping it secure", there will always be that mist of air that screams "security hole"

    -cleen
      My idea was that it would be a better way of making a CGI script able to create/modify some files, without making it so that anyone could modify those files, at least not without using the script.

      oren

        If this is a cgi script, then Im guessing this script will be executed by the user who owns the httpd process right? Then why not make it so the httpd process has the proper rights to that file, and nobody else?
      I'm trying to do exactly what you say this might be used for (icmp using Net::Ping). I'm having trouble finding any documentation about setuid, suidperl or sperl. I'm running on an NT box and I suspect that matters. Thanks for any help you can provide. Henry Hartley

        Windows (not even WindowsNT) doesn't have Set-UID. The closest thing is probably LogonUser() followed by CreateProcessAsUser(). Though, this requires that you stash an unencrypted password somewhere and already have some special privileges, which makes it both less useful and a worse security risk than SUID (which is already a big security risk).

        But that doesn't matter because WindowsNT doesn't require you to have privileges in order to send ICMP packets. You just have to know how to use the advanced socket interfaces. Net::Ping just incorrectly assumes that only VMS is this way. Just comment out the line:

        croak("icmp ping requires root privilege") if ($> and $^O ne 'VMS');
        and Net::Ping can do ICMP pings under WindowsNT just fine!

        Gee, I wish I'd know the fix was that easy a long time ago!.

RE: setuid scripts, how?
by Anonymous Monk on Jul 08, 2000 at 04:27 UTC
    Unfortunatley Suid scripts don't work so well with perl, even when you use suidperl. It does set the euid and egid right, but not the uid and gid. So its really running as root but when it executes other programs like useradd for example they wont run as root when executed which is a major neusense.
    So a good solution is to write a small wrapper in C and have it execute the script.

    Something like this:
    #include <unistd.h> int main(int argc, char** argv) { if (getuid() == 110) { setuid(geteuid()); setgid(getegid()); execl("/path/to/script.pl", NULL); } return 0; }

      Your C code is the same as this Perl code:

      if( 110 == $< ) { $< = $>; $( = $); }

      So you could write this wrapper in Perl or, much better, just add this code to your SUID perl script.

Re: setuid scripts
by Anonymous Monk on Jul 09, 2000 at 20:07 UTC
    You might want to try looking into sudo for the purpose of running scripts as root.