Hi,

I noticed the following behavior on OpenAFS on Linux (1.4.12+dfsg-3 on Ubuntu 10.04 i386, but I've seen symptoms explainable by this behavior on other Linux systems). Given that /mit/geofft/hello.c is in AFS and system:anyuser l (not rl) and geofft rlidkwa, and I have tokens for geofft but root does not:

geo...@white-elephant:/tmp$ cat access.c
#include <unistd.h>
main() {
        perror("access", access("/mit/geofft/hello.c", F_OK));
        return 0;
}
geo...@white-elephant:/tmp$ ./access
access: Success
geo...@white-elephant:/tmp$ sudo ./access
access: Success
geo...@white-elephant:/tmp$ fs flushv /mit/geofft/
geo...@white-elephant:/tmp$ sudo ./access
access: Permission denied
geo...@white-elephant:/tmp$ sudo stat /mit/geofft/hello.c
stat: cannot stat `/mit/geofft/hello.c': Permission denied
geo...@white-elephant:/tmp$ ./access
access: Success
geo...@white-elephant:/tmp$ sudo ./access
access: Success
geo...@white-elephant:/tmp$ sudo stat /mit/geofft/hello.c
  File: `/mit/geofft/hello.c'
  Size: 148             Blocks: 2          IO Block: 4096   regular file
Device: 16h/22d Inode: 1101648276  Links: 1
Access: (0600/-rw-------)  Uid: (40490/ UNKNOWN)   Gid: (  101/ libuuid)
Access: 2008-09-09 06:40:03.000000000 -0400
Modify: 2008-09-09 06:40:03.000000000 -0400
Change: 2008-09-09 06:40:03.000000000 -0400


In other words, access(F_OK) or stat() on a file that clearly exists returns EACCES until such time as a user who has more permissions tries to access it. At that point, access(F_OK) will return 0 and stat() will return stat info until it leaves cache. (Note that for nonexistent files it will correctly return ENOENT instead.)

It's not really clear to me that POSIX permits access(F_OK) to return EACCES if all the directories up to that point are searchable (i.e., "l"), and either way the cache-dependent behavior of 0 vs. EACCES is confusing.

øFor example, the current implementation of Kerberos' .k5login-checking behavior effectively assumes that any nonzero return of access(F_OK) must be ENOENT, so if you have a non-world-readable .k5login file, it will _mostly_ appear to krb5_kuserok to not exist by access() returning EACCES, but if you get your .k5login into cache, access() will start returning 0 instead, and you'll be unable to log in for some period of time (since the file isn't world-readable). We've suggested an alternative implementation to the Kerberos list, but the apparently-nondeterministic behavior of access(F_OK) and stat() is nonetheless confusing and extremely difficult to track down.

--
Geoffrey Thomas
[email protected]

Reply via email to