Establish read permission of a file in C (UNIX / Linux)

M

MS

I need to establish whether the user running my program (a command line
tool) has read permission of the files they entered on the command line.

The code was using stat() and then checking st_mode with S_IRUSR (read
permission, owner) but I've now realized that just checks whether the
owner has read permission and not whether the user running the program
is the owner and has read permission. So if the permissions of a file are:

rw------- and it's owned by root, and the user is NOT root, but the user
has read permission of the directory where the file is then S_IRUSR will
be set - the owner has read permission.

How do I tell if the user running the program has read permission of the
file?

Note: I realize I could just fopen() the file and if that fails then I
have my answer but that seems like a rather inelegant solution.

Thanks.
 
P

pk

MS said:
I need to establish whether the user running my program (a command line
tool) has read permission of the files they entered on the command line.

The code was using stat() and then checking st_mode with S_IRUSR (read
permission, owner) but I've now realized that just checks whether the
owner has read permission and not whether the user running the program
is the owner and has read permission. So if the permissions of a file are:

rw------- and it's owned by root, and the user is NOT root, but the user
has read permission of the directory where the file is then S_IRUSR will
be set - the owner has read permission.

How do I tell if the user running the program has read permission of the
file?

Note: I realize I could just fopen() the file and if that fails then I
have my answer but that seems like a rather inelegant solution.

man 2 access
 
R

Richard Kettlewell

MS said:
How do I tell if the user running the program has read permission of
the file?

Note: I realize I could just fopen() the file and if that fails then I
have my answer but that seems like a rather inelegant solution.

It's a perfectly good solution, and more reliable than doing a separate
check and open.
 
S

Stephen Sprunk

How do I tell if the user running the program has read permission of the
file?

Note: I realize I could just fopen() the file and if that fails then I
have my answer but that seems like a rather inelegant solution.

Check-and-open introduces a potential race condition: some other process
could change the permissions and/or ownership between your two steps,
meaning you still have to handle the case of open failing due to
permissions problems _in addition to_ handling the case of permissions
problems _before_ you try to open the file.

Therefore, simply trying to open the file and dealing with any problems
afterward is actually the more elegant solution. Let the OS do your
work for you.

S
 
M

MS

Check-and-open introduces a potential race condition: some other process
could change the permissions and/or ownership between your two steps,
meaning you still have to handle the case of open failing due to
permissions problems _in addition to_ handling the case of permissions
problems _before_ you try to open the file.

Therefore, simply trying to open the file and dealing with any problems
afterward is actually the more elegant solution. Let the OS do your
work for you.

Ahh yes - but my program will not be opening the files at all. :)

My note was not meant to suggest I would be using fopen() for anything
other than a means of checking read permission.
 
K

Keith Thompson

Stephen Sprunk said:
Check-and-open introduces a potential race condition: some other process
could change the permissions and/or ownership between your two steps,
meaning you still have to handle the case of open failing due to
permissions problems _in addition to_ handling the case of permissions
problems _before_ you try to open the file.

Therefore, simply trying to open the file and dealing with any problems
afterward is actually the more elegant solution. Let the OS do your
work for you.

Agreed. Presumably you were going to try to open the file anyway;
otherwise you (probably) don't care whether it's readable.

And the permissions on the file can be misleading; for example,
it might be on a file system that's mounted read-only.

Finally, the C language itself has nothing to say about this; it
depends on the operating system. Try comp.unix.programer if you
have more questions. (I see you already posted there; consider
dropping comp.lang.c from any followups unless you have questions
about the standard language and library.)
 
M

MS

It's a perfectly good solution, and more reliable than doing a separate
check and open.

If indeed I was going to open the files, which I am not. :)

See my reply to Stephen.
 
M

MS

Agreed. Presumably you were going to try to open the file anyway;
otherwise you (probably) don't care whether it's readable.

And the permissions on the file can be misleading; for example,
it might be on a file system that's mounted read-only.

No, not opening the file at all.

I'm writing a command line utility (primarily for myself) which is a
kind of 'universal' archive extractor. Given 'archive.ext' the code
determines the command needed to extract the archive (based on '.ext')
to a new subdir with the name of 'archive' ('.ext' dropped) - so given
the file:

/home/user/bak/projsrc.zip

The program will create and run the command line:

unzip "/home/user/bak/projsrc.zip" -d "/home/user/bak/projsrc/"

Unzip will be opening the file, not my code, but I want to check that
the program has read permission on the file before calling anything
else. (And, of course, that creating the directory will be ok too).

So far zip, rar, 7zip, arj, tar (with or without gz or bz2) are all
handled, but I'll be handling more archive and compression only types as
well. Then the only command I have to remember is:

uniext archive_name [archive_name_2 ...]

Finally, the C language itself has nothing to say about this; it
depends on the operating system. Try comp.unix.programer if you
have more questions. (I see you already posted there; consider
dropping comp.lang.c from any followups unless you have questions
about the standard language and library.)

Ok sorry about that, will do.

Thanks all.
 
L

lawrence.jones

pk said:
man 2 access

Note that access() and fopen() don't necessarily work the same way --
access() uses the real user and group IDs where fopen() uses the
effective user and group IDs.
 
J

Jorgen Grahn

["Followup-To:" header set to comp.lang.c.]
No, not opening the file at all.

I'm writing a command line utility (primarily for myself) which is a
kind of 'universal' archive extractor. Given 'archive.ext' the code
determines the command needed to extract the archive (based on '.ext')
to a new subdir with the name of 'archive' ('.ext' dropped) - so given
the file:

/home/user/bak/projsrc.zip

The program will create and run the command line:

unzip "/home/user/bak/projsrc.zip" -d "/home/user/bak/projsrc/"

Unzip will be opening the file, not my code, but I want to check that
the program has read permission on the file before calling anything
else. (And, of course, that creating the directory will be ok too).

I still tend to think you are better off /not/ checking arguments,
and instead monitoring the exit status and stderr of tar or whatever
your backend happens to be. You'll have to have such control anyway,
because you /cannot/ predict everything that can go wrong.

/Jorgen
 
M

Morris Keesan

Note that if your program is running setuid,
access() will give you different information than success/failure of
open(), and this is the real reason for the existence of the access
system call. access tells you what the permissions are for the REAL
user id; open succeeds or fails based on the EFFECTIVE user id.
 
R

Rainer Weikusat

MS said:
I need to establish whether the user running my program (a command
line tool) has read permission of the files they entered on the
command line.
[...]

How do I tell if the user running the program has read permission of
the file?

The answer is actually "You can't" (or "This is impossible"). The
best you can achieve is to determine if a user had read permission on
a particular file 'a short time ago' (namely, when the check was
done). The result of this check can be become invalid (in the sense
that it isn't consistent with the actual file system permissions
anymore) at any time after the check.
 
N

Nobody

I need to establish whether the user running my program (a command line
tool) has read permission of the files they entered on the command line.

Do you only need to check the *permissions*, or whether the user can
actually open the file?

If it's the latter, the only accurate solution is to actually open the
file, as there are other factors beyond permissions which can affect
whether open() succeeds.
 
S

Seebs

I need to establish whether the user running my program (a command line
tool) has read permission of the files they entered on the command line.

First:

This is a UNIX question, not a C question.

Second:

What you want is fundamentally incoherent.
Note: I realize I could just fopen() the file and if that fails then I
have my answer but that seems like a rather inelegant solution.

No, that is the *correct* solution.

Welcome to a multitasking environment. *It is possible for the file's
permissions to change between when you check them and when you try to open
the file*. Thus, no matter what, you have to try to open the file and handle
failure gracefully. The previous check adds no value.

-s
 
S

Seebs

Ahh yes - but my program will not be opening the files at all. :)

....

Why do you care whether they're readable, then?
My note was not meant to suggest I would be using fopen() for anything
other than a means of checking read permission.

Ahh. Well, typically, if you aren't going to read them, it doesn't matter
whether you could.

Note that there really isn't a way to do this that will be reliable and
consistent. So, whatever you're testing for, just be aware that you *will*
someday get a wrong answer.

-s
 
S

Seebs

Unzip will be opening the file, not my code, but I want to check that
the program has read permission on the file before calling anything
else. (And, of course, that creating the directory will be ok too).

What does performing this check buy you?

I mean, really. How much better is it to get:
myprogname: foo.zip: Permission denied.
than
unzip: foo.zip: Permission denied.

I guess... This is the kind of thing which feels like it will be a source
of bugs but not a source of features.

-s
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top