#define _GNU_SOURCE #include #include #include #include #include #include #include "vers.h" static void * get_func (const char *symbol, const char *version) { void *addr; addr = dlvsym (RTLD_NEXT, symbol, version); #ifdef DEBUG fprintf (stderr, "dlvsym (RTLD_NEXT, %s, %s) = %p\n", symbol, version, addr); #endif if (!addr) error (1, errno, "dlvsym: %s@@%s", symbol, version); return addr; } typedef int (*chown_fptr) (const char *, uid_t, gid_t); int chown (const char *path, uid_t owner, gid_t group) { if (getuid ()) { static chown_fptr func = 0; if (!func) func = get_func ("chown", chown_vers); return func (path, owner, group); } return 0; } typedef int (*lchown_fptr) (const char *, uid_t, gid_t); int lchown (const char *path, uid_t owner, gid_t group) { if (getuid ()) { static lchown_fptr func = 0; if (!func) func = get_func ("lchown", lchown_vers); return func (path, owner, group); } return 0; } typedef int (*fchown_fptr) (int, uid_t, gid_t); int fchown (int fd, uid_t owner, gid_t group) { if (getuid ()) { static fchown_fptr func = 0; if (!func) func = get_func ("fchown", fchown_vers); return func (fd, owner, group); } return 0; } typedef int (*chmod_fptr) (const char *, mode_t); int chmod (const char *path, mode_t mode) { if (getuid ()) { static chmod_fptr func = 0; if (!func) func = get_func ("chmod", chmod_vers); return func (path, mode); } return 0; } typedef int (*fchmod_fptr) (int, mode_t); int fchmod (int fildes, mode_t mode) { if (getuid ()) { static fchmod_fptr func = 0; if (!func) func = get_func ("fchmod", chmod_vers); return func (fildes, mode); } return 0; }