http://qs321.pair.com?node_id=99861

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

I have a daemon running on Solaris/Linux boxes -- it runs as root, and accepts script(s) from users and runs it under that user's uid by changing $> and $<. ( Security isn't a concern, for now ). Here's a pseudocode:

daemon loop: while .... { if( job ) { $pid = fork(); if( child ) { $> = job->uid; $< = job->uid; run script exit ; } } }

If you just use %ENV that's available through the daemon, it will show %ENV of the root user. What I want to do is to pull the user's environment variables before running the script.

Is there anyway to do this?

Replies are listed 'Best First'.
Re: Can you import ENV variables at run time?
by bikeNomad (Priest) on Jul 26, 2001 at 04:29 UTC
    The problem is that users don't have environment variables, processes do. What you sees in your environment variables when logged into an interactive shell is the result of that shell running some shell scripts (like .profile, .bashrc, /etc/profile, etc., depending on the shell).

    There are a few you could guess at from the contents of the passwd file: home directory, initial shell; but past this it's going to be hard to guess what the environment variable would have been.

    If you run your scripts using the shell (after setting $HOME, $USER, etc.) you may be able to get the shell to interpret these files. For instance, under bash you can do this:

    system("/bin/bash --login -c $yourScript");
    and get the environment variables set.

    update: I realize that not everyone has the same shell; you'd want to use getpwuid to get the passwd file setting for login shell and HOME. tilly's suggestion sounds good.

      /bin/bash isn't necessarily everyone's shell and thus any environment variables they set up upon login won't necessarily be set by bash.
      $command = sprintf('exec - %s -c env', (getpwuid($>))[8]); $ENV{'HOME'} = (getpwuid($>))[7]; $env = `$command`;
      This should run someone's shell as a login shell regardless of what shell it is, and $env will contain the output of env which should be easy to parse.
Re (tilly) 1: Can you import ENV variables at run time?
by tilly (Archbishop) on Jul 26, 2001 at 05:07 UTC

      oops, I was apparently looking at an old cache of this page when I wrote my thank you post... didn't mean to ignore you, tilly.

      thanks, I'll look into that as well

Re: Can you import ENV variables at run time?
by lestrrat (Deacon) on Jul 26, 2001 at 05:49 UTC

    Thank you both!

    I think this is what I'm going to do:

    use Env; ## uid = 0 at this point. ## delete root's env foreach my $key ( keys %ENV ) { delete $ENV{ $key }; } ## set standard PATH, apparently some scripts ## rely on this $ENV{ PATH } = '/bin:/usr/bin:/usr/local/bin:/usr/ucb'; $> = $target_uid; $< = $target_uid; my( $shell, $home ) = ( getpwuid( $> ) ) [ 7, 8 ]; $ENV{ HOME } = $home; my $env_str = qx/exec $shell -c env/; # now parse
      Any reason you couldn't do something like:
      %ENV = ( HOME => $home, PATH => '/bin:/usr/bin:/usr/local/bin:/usr/ucb', );
      Seems a lot simpler than explictly deleting every key of %ENV, and then inserting things one by one.