#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include static void usage (void); static int perm_set (uid_t); int main (int argc, char *argv[]) { if (argc < 2) { usage(); exit(1); } uid_t ruid = getuid(); // Copy argv and argc int c_argc = argc - 1; char **c_argv = malloc((c_argc + 1) * sizeof(char *)); if (!c_argv) { fprintf(stderr, "malloc: %s\n", strerror(errno)); goto fail_end; } for (int i = 0; i < c_argc; i++) c_argv[i] = strdup(argv[i+1]); c_argc[c_argv] = NULL; if (perm_set(0) == -1) { // 0 = root fprintf(stderr, "perm_set: %s\n", strerror(errno)); goto fail_end; } if (execvp(*c_argv, c_argv) == -1) // execvp searches in path fprintf(stderr, "execv: %s\n", strerror(errno)); // if exec fails reset the permissions if (perm_set(ruid) == -1) { // 0 = root fprintf(stderr, "perm_set: %s\n", strerror(errno)); goto fail_end; } fail_end: return 0; } static inline void usage (void) { printf("usage: us [command]\n"); } static inline int perm_set (uid_t id) { return seteuid(id); }