Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Obtaining %ENV values via su cmd

by Trizor (Pilgrim)
on May 14, 2007 at 23:28 UTC ( [id://615435]=note: print w/replies, xml ) Need Help??


in reply to Obtaining %ENV values via su cmd

Try using Data::Dumper to see what is in %ENV, it is posible that user bin explicity unsets USER or some other shenanigains. This is the output that I get on my box (Dapper drake server).

env.pl, the test script
#!/usr/bin/perl -w use strict; use Data::Dumper; print Dumper(\%ENV);
And the output:
trizor@trap:/home$ sudo su - greg -c /home/env.pl $VAR1 = { 'HOME' => '/home/greg', 'LOGNAME' => 'greg', 'SHLVL' => '1', '_' => '/home/dummy.pl', 'SHELL' => '/bin/bash', 'TERM' => 'xterm', 'PWD' => '/home/greg', 'USER' => 'greg', 'LANG' => 'en_US.UTF-8' };

As you can see, USER is there plain as day.

Replies are listed 'Best First'.
Re^2: Obtaining %ENV values via su cmd
by chrism01 (Friar) on May 14, 2007 at 23:47 UTC
    Interesting ... turns out 'USER' ISN'T there, but LOGNAME is.
    BTW, ref to bin user is just an example quoted from man page.
    I'm having to run this as the root user.
    I need to be able to do this from cron eventually ie root or system crontab.
    I'll try that now.
    BTW, what is the diff between USER and LOGNAME and are there any other values I can check for in case they aren't there.
    Basically, the real prog will be run on various systems under different users and I need to know which user when it runs, as certain users aren't allowed to call my program... it's part of a system monitor suite.

    Cheers
    Chris

      I don't know much about %ENV, I rarely use it. If you need to know what user you're running as my guess would be to check $> and $< against /etc/passwd or use POSIX;. I definitely wouldn't trust %ENV, since it is passed to the program at execution time and could be modified to fake values.

      I would also advise reading perlsec if you're writing any system that needs to be secure.

        While checking /etc/passwd may work in many situations, it's an awful habit to get into, even if there aren't better solutions. Since this is perl, not shell, there are better solutions:

        (I prefer the latter.) There are many variations on this theme (using User::pwent::getpw instead of getpwuid, etc.), but not significantly different, so I'm not going to show all of them..

        If all that these do is look into /etc/passwd, they'd still be better than reading /etc/passwd directly - any gotchas would be dealt with by people who probably have spent more time on the issue than us. However, that's not what they do at all. They use the POSIX API to query the OS for the user information. The C library then goes and figures out how the system is set up - whether that's using /etc/passwd, or NIS, or LDAP, or DCE, or ... well, there are more ways to store user information than I can shake a stick at. Heck, I could write a PAM module that uses mySQL or Oracle or DB2 (or even a Windows MS SQL box) to store the user info, and thus query it from each machine in my network. All of this is then handled identically by everything from login to the shell ... to your POSIX-compliant perl script.

      I've had similar situations where I had to "just get it working", and, seeing the variance in environment settings across systems, I just did something like this:
      my $username = $ENV{USER} || $ENV{LOGNAME} || `whoami`; chomp $username; # in case it came from the shell command
      But I never had to do this in a situation where "su" was being used, and I'd worry about whether one or the other %ENV setting gets "updated" or not across the "su" (with or without the "-" to invoke the new user's rc file(s)).

      Having just tried it on freebsd, it looks like "whoami" definitely reports the "effective username" (i.e. the user that you "su" to); maybe the price of running the backtick command is worthwhile, considering the stability you get in return...

        The prob I was having was that in the cron/su situation, $ENV{USER} wasn't getting set, although it turns out LOGNAME is. I also came up with about 3 other ways ie parse $ENV{MAIL}, $ENV{HOME} and POSIX::cuserid(). I'll prob use some or all of them similarly to your soln.

        Cheers
        Chris

        Turns out that the prod servers generally have local accts, but my Solaris desktop uses LDAP ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://615435]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (8)
As of 2024-04-18 07:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found