73 lines
1.6 KiB
C
73 lines
1.6 KiB
C
|
#include <errno.h>
|
||
|
#include <grp.h>
|
||
|
#include <pwd.h>
|
||
|
#include <limits.h>
|
||
|
#include <stdint.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#ifndef NINJUTSU_SEC_GROUP
|
||
|
#ifdef __APPLE__
|
||
|
#define NINJUTSU_SEC_GROUP "staff"
|
||
|
#else
|
||
|
#define NINJUTSU_SEC_GROUP "wheel"
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#define NINJUTSU_SEC_EUID 0
|
||
|
|
||
|
int main(int argc, char **argv) {
|
||
|
if(argc < 2) {
|
||
|
fprintf(stderr, "no command provided\n");
|
||
|
return 1;
|
||
|
} else if(NINJUTSU_SEC_EUID != geteuid()) {
|
||
|
fprintf(stderr, "permissions are incorrect\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
struct passwd *entry = getpwuid(getuid());
|
||
|
|
||
|
if(!entry) {
|
||
|
fprintf(stderr, "unable to get passwd entry: %s\n", strerror(errno));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int groups[NGROUPS_MAX] = { 0 };
|
||
|
int groups_sz = NGROUPS_MAX;
|
||
|
|
||
|
if(getgrouplist(entry->pw_name, entry->pw_gid, groups, &groups_sz) < 0) {
|
||
|
fprintf(stderr, "unable to get full group list\n");
|
||
|
}
|
||
|
|
||
|
struct group *group = getgrnam(NINJUTSU_SEC_GROUP);
|
||
|
|
||
|
if(!group) {
|
||
|
fprintf(stderr, "unable to get group entry: %s\n", strerror(errno));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
uint8_t idx = 0;
|
||
|
uint8_t found_group = 0;
|
||
|
|
||
|
for(; idx < groups_sz; idx += 1) {
|
||
|
if(group->gr_gid == (unsigned int) groups[idx]) {
|
||
|
found_group = 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!found_group) {
|
||
|
fprintf(stderr, "I'm sorry, %s. I'm afraid I can't do that.\n", entry->pw_name);
|
||
|
return 1;
|
||
|
} else if(setuid(geteuid()) < 0) {
|
||
|
fprintf(stderr, "could not set uid: %s\n", strerror(errno));
|
||
|
return 1;
|
||
|
} else if(execvp(*(argv + 1), argv + 1) < 0) {
|
||
|
fprintf(stderr, "could not run command: %s\n", strerror(errno));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|