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

Okay so I'm considering writing a script to use suidperl (yes yes I know, but setuid on a script usually doesn't work, and I have valid reasons, I'm writing crontab(1)). Okay so, when you run the program the program is run as root. So how do you know how invoked you? I'm thinking getlogin, but that can return null so you need a full back and clearly falling back to the example $< does no good and $ENV{USER} is unsafe. So what's my fallback? I was thinking along the lines of discovering the owner of the parent process. But I can only get halfway there (getppid)...

BTW this should ideally rely upon no external programs or modules and be platform indpendent ;-).

--
perl -p -e "s/(?:\w);([st])/'\$1/mg"

Replies are listed 'Best First'.
Re: Process owner
by mortis (Pilgrim) on Dec 15, 2001 at 03:27 UTC
    (Under Unix) I'd think $< (UID) and $> (EUID) are what you really want.

    man perlvar has some more to say on the subject, as should man setuid on your (Unix) system.

    EUID is what you can effectivly do - if you're EUID is root (0), you can set your UID. If it's not, you can't. Your paren't process can effect your UID before you're execed, but once you're execed, you've got your UID/EUID (and GID/EGID) for the remaining lifetime of your process.

      $< is not what I want that is 0, the script is setuid root (# chmod u+s). $> *might* be handled correctly bysuidperl but I haven't built one to play with yet. It seems unlikely however.

      --
      perl -p -e "s/(?:\w);([st])/'\$1/mg"

Re: Process owner
by Zaxo (Archbishop) on Dec 15, 2001 at 03:35 UTC

    The POSIX module has what you need.

    use POSIX qw( getuid geteuid getpwuid );
    Have you considered sudo instead of suidperl?

    Update: Corrected a typo. mortis points out a better way for simple cases.

    After Compline,
    Zaxo

Re: Process owner
by belg4mit (Prior) on Dec 15, 2001 at 03:46 UTC
    Okay, nevermind. Sorry
    $ ls -l setuidscript -rws------ 1 root root 49 Dec 14 22:26 /tmp/setuidscr +ipt $ cat setuidscript #!/usr/bin/sperl5.6.0 print "UID: $< EUID $>\n"; $ ./setuidscript UID: 8029 EUID 0

    UPDATED: Changed back to the original syntax, that works ( a file, instead of a one-liner).

    --
    perl -p -e "s/(?:\w);([st])/'\$1/mg"

      Thats odd... I get:
      % /usr/bin/sperl5.6.0 -e 'print "UID: $< EUID $>\n"'; No -e allowed in setuid scripts.

      -Blake

        Doh guess I shouldn't modify my examples on the fly/untested. It was actually in a script but it looked like it would be nicer to put in the node as a one-liner :-/

        --
        perl -p -e "s/(?:\w);([st])/'\$1/mg"

Re: Process owner
by thayer (Sexton) on Dec 16, 2001 at 00:53 UTC
    Some code might clarify. The man page to read first is perlsec. Tainting and setuid are very complex issues. Here's a transcript of what I think you were trying to do originally. Note that the last prompt "$" is run as myself instead of root.
    # cat s.c main(int ac, char **av) { execv("/home/thayer/foo.pl", av); } # gcc s.c -o s # chown root s; chmod a+rx,u+s s ; ls -l s -rwsrwxr-x 1 root users 11394 Dec 15 11:43 s # cat foo.pl #!/usr/local/bin/perl -T print "$< $>\n"; # ls -l foo.pl -r-xr-xr-x 1 thayer users 43 Dec 15 11:42 foo.pl $ ./s 3068 0
    When it comes to suid and perl, running on the command line is different than running from a real file. In unix there's a race condition running scripts, #! files, between the time the kernel detects what script program to use and when the script actually reads the file. Using a compiled wrapper or sudo are common work-arounds.