Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

The scenario is this - I have a command line program that might not run as root, part of the requirements is to warn if another user has write permissions to some folder / file

e.g.

  • I'm running as non root user A
  • I would like to get the answer to the question: "does user B has write permissions to folder F"

So my questions are

  • Is it even possible to do as a root user? if so how?
  • Is there any way to do it as a non root user?
share|improve this question
4  
This is actually hard to answer in general. For example, the answers here fail to consider ACLs. They also fail to consider user/group mapping that may occur on a network share. –  derobert May 28 at 17:28

5 Answers 5

In general, the only way to know if user B can write to directory D is for user B to attempt to write to directory D.

So, as root, you can su to the user and try it. Though that may not be 100% accurate as the user logging in and entering his password may change things (e.g., a pam module might set up crypto keys based on the user's password).

Almost as accurate, again as root, you can su to the user and use the access(2) syscall or similar. Probably, this is what the shell does if you use test -w, and also be what /usr/bin/test does. Though as the manpage warns, on NFSv2, the actual check is done by the server, but the test for the access syscall is done locally, so it may be wrong. Similarly, FUSE filesystems may do the same.

(The access(2) manpage also mentions a race condition which is fundamental to what you're doing: B's permissions on D might change between when you check and when B actually tries to write to D.)

Other than that, you have to decide how accurate you are willing to accept:

  1. You could stat the directory, and check the users & groups (as several of the other answers show)
  2. You could additionally check the ACLs on the directory.

But even if you do that, the following will trip you up:

  1. With NFS and various other network filesystems, the server decides if access is permitted. It can make that decision based on, well, whatever it likes. Consider e.g., the various squash NFS export options.
  2. Permissions checks are actually done by the filesystem; non-Unix filesystems may give unexpected answers (how is the Unix user mapped to a SID for NTFS?). All bets are off with e.g., FUSE filesystems.
share|improve this answer
1  
+1 FUSE filesystems mounted with --allow-other are world writable regardless of file mode. –  goldilocks May 28 at 17:46
    
"the only way to know if user B can write to directory D is for user B to attempt to write to directory D" What has access(2)/faccessat(2) been invented for then and why is it so heavily used? strace -e trace=faccessat bash -c 'test -w /tmp' –  Hauke Laging May 28 at 17:49
    
@HaukeLaging access/etc. don't always work, though they're much closer. See the last paragraph under "NOTES" in the access(2) manpage: These calls may not work correctly on NFSv2 filesystems with UID mapping enabled, because UID mapping is done on the server and hidden from the client, which checks permissions. (NFS versions 3 and higher per‐ form the check on the server.) Similar problems can occur to FUSE mounts. I'll add in a note about it, though. –  derobert May 28 at 17:52
1  
@HaukeLaging note added. –  derobert May 28 at 17:58
1  
I would go so far as to say that all uses of access should be assumed to be bugs until proven otherwise; I'm not sure I've ever seen a situation, even in a setuid program, where it was the Right Thing. –  Zack May 28 at 20:22

"does user B has write permissions to folder F"

User A's ability to determine this hinges on A's access to folder F. For example, if F is /home/B/foo/bar and A cannot read /home/B/foo, then A cannot even check if F exists, much less what permissions are set on it.

Presuming A does have read access to F, and can therefore stat()1 it to get the permissions, the next step is to determine if B is the owner, or in the group. With regard to the latter, you can get a list of users in the group with getgrent() (native C -- it has a man page; note this does not take an argument but instead iterates /etc/group one entry at a time), which returns a struct group:

       struct group {
           char   *gr_name;       /* group name */
           char   *gr_passwd;     /* group password */
           gid_t   gr_gid;        /* group ID */
           char  **gr_mem;        /* group members */
       };

The last field, gr_mem, is an array of strings containing the list of user names (this list is terminated with a NULL pointer). That, combined with the file mode, is enough information to tell you whether a particular user has write permission.

An example using getgrent(), to print a list of groups with IDs and members:

#include <stdio.h>
#include <sys/types.h>
#include <grp.h>

// std=c99

int main (void) {
    struct group *ent = getgrent();
    while (ent) {
        printf (
            "%s GID %d\n",
            ent->gr_name,
            ent->gr_gid
        );
        int i = 0;
        char *p = ent->gr_mem[i];
        while (p) {
            printf("\t%s\n", p);
            p = ent->gr_mem[++i];
        }
        ent = getgrent();
    }
    return 0;
} 

Access to /etc/group (and use of getgrent()) does not require privileges.

1 You do not mention what language you are using, but hopefully "stat" is reasonably agnostic. getgrent() should be mostly be ported too, but to what depends on the language.

share|improve this answer
1  
"A cannot read /home/B/foo, then A cannot even check if F exists" oh yes, A can do that. A cannot if A has no execute permission for foo... –  Hauke Laging May 28 at 17:18
    
@HaukeLaging No, if A does not have read (plus execute) permissions on /foo, A cannot check if a subfolder of /foo exists. Note I didn't mention the mode, I just said "can read" (as opposed to "has read permissions"). WRT read access on /foo's subfolder (so F =/foo/bar), that's all that's required to stat() it. So A does not actually need execute permissions on F. –  goldilocks May 28 at 17:28
1  
Sure you can check whether a certain subfolder (or file) exists. You just cannot read the list of directory entries. You must know the path you want to check. –  Hauke Laging May 28 at 17:36
2  
@goldilocks it's <!-- language: lang-c -->. Fixed it for you. –  derobert May 28 at 17:40
    
@HaukeLaging Playing around, it seems you can stat a filepath that you have no permissions on BUT to do that you need execute on the folder it's in. So that applies to the parent of F, point taken! –  goldilocks May 28 at 17:42

Answer to the first question (running as root):

YES -> su - userB -c '<command as userB to touch file in folderF>'

Answer to the second question:

MAYBE -> only if non user is within the same group as userB and tries to touch a file in folderF

share|improve this answer
    
Don't use sudo su. If you want a shell, do sudo -s, else just use sudo regularly. –  HalosGhost May 28 at 16:49
    
I've edited my answer, I tested with my own user so I had do sudo su, but you're right! –  Marcel May 28 at 16:53
    
Again, you do not need sudo su for this purpose. Take a look at sudo -u. :) –  HalosGhost May 28 at 16:55

I am not aware of a single command to fulfill this purpose, but there are several commands that would allow you to determine the answer without root.

ls -l F will show you the owner and group of the file in-question. If the user is not the owner, then you can check groups user to see if the user belongs to the file's group. If the userB is either the owner, or belongs to the file's group, then the access permissions for u and g (respectively) will tell you what permissions they have; else, the access permissions for o will tell you what permissions the user has.

share|improve this answer
2  
I just say: ACLs... –  Hauke Laging May 28 at 17:15

If I understand it correctly, you need to check the user permission on a particular folder.

So basically first run the groups command on the user.

groups userB

The above command will list all the groups that the userB belong to. After that,

Use the stat command to find the octal permissions on the file/folder as below.

stat -c "%a %n" /some-folder

The above command will return the octal permission on that particular folder/file.

For example, if the above command returns 775, it means user and group have full rwx access on the file/folder others have r-x access on the file/folder.

Determine the groups of userA as well using groups userA command and if both userA and userB belong to the same group then it means userB has write permissions on the file.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.