Here's a little test for this: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <time.h> #include <utime.h> #include <grp.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <stdbool.h> static int touch(const char *path, mode_t mode, bool current_time) { if (current_time) return utime(path, NULL); else { time_t now = time(NULL); struct utimbuf times = { .actime = now, .modtime = now, }; return utime(path, ×); } } static int su(uid_t uid, gid_t gid) { int ret; ret = seteuid(0); if (ret != 0) return ret; ret = setegid(gid); if (ret != 0) return ret; ret = setgroups(0, NULL); if (ret != 0) return ret; ret = seteuid(uid); return ret; } static void die(const char *str) { perror(str); exit(1); } void cleanup(void) { su(0, 0); unlink("foo"); } int main(void) { int ret; atexit(cleanup); ret = creat("foo", 0600); if (ret < 0) die("foo"); close(ret); ret = chown("foo", 0, 12345); if (ret != 0) die("foo"); ret = su(12345, 12345); if (ret != 0) die("su"); errno = 0; ret = touch("foo", 0660, true); if (ret == 0) die("touch should have failed"); ret = su(0, 0); if (ret != 0) die("su"); ret = chmod("foo", 0660); if (ret != 0) die("foo"); ret = su(12345, 12345); if (ret != 0) die("su"); errno = 0; ret = touch("foo", 0660, true); if (ret != 0) die("touch should have succeeded"); ret = touch("foo", 0660, false); if (ret == 0) die("touch should fail on NFSv3+"); return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html