#include #include #include #include #include #include #include #include #include #include #ifdef __i386__ #define __NR_getluid 510 #define __NR_setluid 511 #define __NR_setublimit 512 #define __NR_ubstat 513 #else #error "syscall numbers are not defined" #endif // long sys_setublimit(uid_t uid, unsigned long resource, // unsigned long *limits) static _syscall3(long, setublimit, int, uid, unsigned long, resource, unsigned long *, limits); // long sys_setluid(uid_t uid) static _syscall1(long, setluid, int, uid); void usage(char *name) { fprintf(stderr, "%s commands\n" "\tset uid resource barrier [limit]\n" "\t\t set barrier end limit\n" "\tenter uid\n" "\t\tset luid and exec SHELL\n" , name); } int main(int argc, char **argv) { uid_t uid; unsigned long resource; long ret; char *endptr; if (argc <3) { usage(argv[0]); exit(1); } uid = strtol(argv[2], &endptr, 0); if (*endptr != '\0') { usage(argv[0]); exit(1); } if (strstr(argv[1], "set") == argv[1]) { unsigned long limits[2]; if (argc < 5) { usage(argv[0]); exit(1); } resource = strtol(argv[3], &endptr, 0); if (*endptr != '\0') { usage(argv[0]); exit(1); } limits[0] = strtol(argv[4], &endptr, 0); if (*endptr != '\0') { usage(argv[0]); exit(1); } limits[1] = limits[0]; if (argc > 5) { limits[1] = strtol(argv[5], &endptr, 0); if (*endptr != '\0') { usage(argv[0]); exit(1); } } ret = setublimit(uid, resource, limits); if (ret < 0) { perror("setublimit:"); exit(1); } } else if (strstr(argv[1], "enter") == argv[1]) { char *shell; ret = setluid(uid); if (ret < 0) { perror("setluid:"); exit(1); } shell = getenv("SHELL"); if (shell == NULL) shell = "/bin/sh"; execl(shell, shell, NULL); perror("execl"); exit(1); } else { usage(argv[0]); exit(1); } return 0; }