-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
53 lines (42 loc) · 1.42 KB
/
main.c
File metadata and controls
53 lines (42 loc) · 1.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#define _DEFAULT_SOURCE
#include <errno.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char *prog_name;
static void exit_error(int line, char *msg) {
fprintf(stderr, "[ERROR %s] line %d: %s\n", prog_name, line, msg);
_exit(1);
}
static void exit_errno(int line) {
exit_error(line, strerror(errno));
}
#define LIST_MAX_SIZE 1000
int main(int argc, char *argv[]) {
prog_name = argv[0];
if(argc < 2) {
fprintf(stderr, "Usage : %s <uid>[,gid][,groups][... ,groups] [the_program] [arg1] [arg2] [... argN]\n", prog_name);
fprintf(stderr, "Example : %s 1,2,3,4,5 sh -c 'echo Hello with $(id)'\n", prog_name);
_exit(1);
}
unsigned int list[LIST_MAX_SIZE], list_n = 0;
for(char *tok = strtok(argv[1], ","); tok; tok = strtok(NULL, ",")) {
if(list_n == LIST_MAX_SIZE) exit_error(__LINE__, "Too much number in the list");
char *rptr;
list[list_n++] = strtol(tok, &rptr, 0);
if(*tok == 0 || *rptr != 0) exit_error(__LINE__, "Cannot parse as list of integer");
}
if(list_n >= 2) if(setgid(list[1]) == -1) exit_errno(__LINE__);
if(list_n >= 3) if(setgroups(list_n - 2, &list[2]) == -1) exit_errno(__LINE__);
if(list_n >= 1) if(setuid(list[0]) == -1) exit_errno(__LINE__);
if(argc >= 3) {
char *new_arg[argc - 1];
for(int i = 2; i < argc; ++i) new_arg[i - 2] = argv[i];
new_arg[argc - 2] = 0;
execvp(new_arg[0], new_arg);
exit_errno(__LINE__);
}
return 0;
}