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

So I have a condition where I will eventually setuid to other users (think root launching the httpd server as apache)

Obviously I can check the perms after I drop down in permissions, but that's not the idea here. I want to alert the admin before they get nasty failures, and potentially remedy the situation

I would like to check to see if my target user has write/read permissions for a specific set of files. And if not, then change things before I switch users.

Is there a perl way to do this?

Here is what I'm thinking:

if (! -w $file $user) { #do permission-ey things to fix that }

Replies are listed 'Best First'.
Re: How do I check if another user can access a file?
by chrestomanci (Priest) on Aug 18, 2011 at 09:07 UTC

    Why not fork of a child process as the target user and directly test if the specific set of files are accessible?

    Something like this: (Untested)

    #!/usr/bin/perl -w use strict; use English; my $child_pid = open(FROM_KID, "|-") or die "can't fork: $!"; if ($child_pid) { # am the parent read FROM_KID my $child_message = <FROM_KID>; if( $child_message =~ m/ERROR accessing files/ ) { # Alert the sysadmin } # Else OK. wait $child_pid; # Wait for the child to quit before continuing +. } else { # Change userID $EGID=22; # aka: $> $UID=22; # aka: $< # am the child; use STDIN/STDOUT normally if( test_access_files() ) { print "OK accessing files as userID 22\n"; } else { print "ERROR accessing files as userID 22\n"; } exit; }

      Actually trying to access a file is the only way you'll be sure that you can access it. What if you're using some other file-system, e.g. AFS, which has different means of access control? chrestomanci has the best general way here.

      Of course, you may know how/where the code will be executed and may know that this level of generality is not required.

Re: How do I check if another user can access a file?
by roboticus (Chancellor) on Aug 18, 2011 at 02:30 UTC

    mtnboy:

    I've never tried it, but perhaps File::stat can be of use? The cando method looks promising.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

    Update: Promosing speeling korrekshun.

Re: How do I check if another user can access a file?
by i5513 (Pilgrim) on Aug 18, 2011 at 10:00 UTC

    I would write in a sub in perl:

    • Get (and read manual) stat from file (permissions, user and group owner)
    • If user is the owner, verify r/w permission with S_IRUSR S_IWUSR masks and fix if don't have permission you want
    • If user is in group owner (getgrnam), then verify r/w permission with S_IRGRP S_IWGRP masks and fix if don't have permission you want
    • If user is not in group owner, then verify r/w permission with S_IROTH S_IWOTH masks, and fix with system and adduser from your S.O.

    But probably you should simplify your environment and make a good use of groups and umasks ;)

Re: How do I check if another user can access a file?
by locked_user sundialsvc4 (Abbot) on Aug 18, 2011 at 13:27 UTC

    In my experience, “the one and only way to know is to try it.”   Write your code so that, upon switching to the target user, it attempts to do various harmless things.   For example, try to create a dummy file and to delete it again.   Read the list of files to be sure that the files exist and that you can open them all (one at a time).   Then, if the bridge seems to be supporting your weight as it should, venture to cross it.

Re: How do I check if another user can access a file?
by Perlbotics (Archbishop) on Aug 18, 2011 at 15:46 UTC

    Sure, you could re-evaluate permission checks of your OS and emulate access before running the real application. But, you'll probably never get the tests 100% waterproof and will have to rely on your runtime checks.

    The problem with the let it run and see approach is that some services can run a remarkably long time before a problem becomes visible, e.g. when an exceptional condition occurs that requires to save some evidence to a file and certainly - no permission. And there's also a chance that the application/system is left in an inconsistent state.

    From my experience, it's better to have a clear and structured permission- and ownership-plan for a given set of directories and applications and to strictly adhere to this plan.

    This concept is usually supported by catching exceptions at run-time (as you already do - but that is a second line of countermeasure) plus an automated mechanism (update-script) that enforces correct ownerships and permissions for file-types and - where necessary - individual files. It might be useful to let this script also create (empty) directory-trees.

    Since your application-starter now can expect with confidence that the environment (permissions, ownerships) has a consistent and predictive state (remember update-script), things become easy for your application(-starter). It just has to check if the user belongs to a group (or set of groups) that is permitted to run a certain application (role: application). Sometimes you need another role for programs that update your files or need higher permissions (role: application-adm). If some of your programs are executed with root-permission - and you cannot avoid that - let those files be owned by root.

    The whole concept can be scripted (update-script) and automated (e.g. cron). In extreme, the update-script is started before you run the application. This catches a lot of problems that can occur if e.g. someone has updated/installed files and forgot to set proper permissions/ownerships.

    So, my advice is to separate permission/ownership-management (an administrative task) from application-startup (an operational task). YMMV, but I successfully run this (old school?) approach in one of our environments for years without any problems.
    HTH

Re: How do I check if another user can access a file?
by blue_cowdawg (Monsignor) on Aug 18, 2011 at 15:55 UTC
        I would like to check to see if my target user has write/read permissions for a specific set of files. And if not, then change things before I switch users.

    Personally I'd rather take the proactive approach and change the perms accordingly on the files before dropping down into the lesser permissioned user. This way you don't have to be concerned with the issue.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: How do I check if another user can access a file?
by slinky773 (Sexton) on Aug 18, 2011 at 17:30 UTC
    You could always just do this:
    if(! FILE, ">filename") { #dosomething } else { #dosomethingelse }