1 #include "config.h"
2 
3 #include <errno.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <getopt.h>
9 #include <unistd.h>
10 
11 #ifndef discard_const
12 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
13 #endif
14 
15 #ifndef discard_const_p
16 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
17 #endif
18 
19 struct user_ids {
20 	uid_t ruid;
21 	uid_t euid;
22 	uid_t suid;
23 	gid_t gid;
24 };
25 
print_usage(const char * prog_name)26 static void print_usage(const char *prog_name)
27 {
28 	fprintf(stderr,
29 		"Usage: %s [-r ruid] [-e euid] [-s suid] [-g gid]\n"
30 		"\n"
31 		"    -r The ruid to validate\n"
32 		"    -e The euid to validate\n"
33 		"    -s The suid to validate\n"
34 		"    -g The gid to validate\n"
35 		"\n",
36 		prog_name);
37 }
38 
main(int argc,char * argv[])39 int main(int argc, char *argv[])
40 {
41 	const struct option long_options[] = {
42 		{ discard_const_p(char, "ruid"),  required_argument,  0, 'r' },
43 		{ discard_const_p(char, "euid"),  required_argument,  0, 'e' },
44 		{ discard_const_p(char, "suid"),  required_argument,  0, 's' },
45 		{ discard_const_p(char, "gid"),   required_argument,  0, 'g' },
46 		{ 0,                              0,                  0, 0 }
47 	};
48 	int opt_idx;
49 	int opt;
50 	struct user_ids expected_ids = {
51 		.ruid = (uid_t)-1,
52 		.euid = (uid_t)-1,
53 		.suid = (uid_t)-1,
54 		.gid  = (gid_t)-1,
55 	};
56 	struct user_ids real_ids = {
57 		.ruid = (uid_t)-1,
58 		.euid = (uid_t)-1,
59 		.suid = (uid_t)-1,
60 		.gid  = (gid_t)-1,
61 	};
62 	int rc;
63 
64 	for (opt = getopt_long(argc, argv, "r:e:s:g:", long_options, &opt_idx);
65 	     opt != -1;
66 	     opt = getopt_long(argc, argv, "r:e:s:g:", long_options, &opt_idx)) {
67 		errno = 0;
68 
69 		switch (opt) {
70 			case 0:
71 				break;
72 			case 'r':
73 				expected_ids.ruid = strtol(optarg,
74 							   (char **)NULL,
75 							   10);
76 				break;
77 			case 'e':
78 				expected_ids.euid = strtol(optarg,
79 						           (char **)NULL,
80 							   10);
81 				break;
82 			case 's':
83 				expected_ids.suid = strtol(optarg,
84 						           (char **)NULL,
85 							   10);
86 				break;
87 			case 'g':
88 				expected_ids.gid = strtol(optarg,
89 						          (char **)NULL,
90 							  10);
91 				break;
92 			default:
93 				print_usage(argv[0]);
94 				return 1;
95 		}
96 
97 		if (errno == EINVAL || errno == ERANGE) {
98 			return 1;
99 		}
100 	}
101 
102 	if (expected_ids.ruid == (uid_t)-1 &&
103 	    expected_ids.euid == (uid_t)-1 &&
104 	    expected_ids.suid == (uid_t)-1) {
105 		print_usage(argv[0]);
106 		return 1;
107 	}
108 
109 	rc = getresuid(&real_ids.ruid, &real_ids.euid, &real_ids.suid);
110 	if (rc != 0) {
111 		fprintf(stderr, "getresuid() failed - %s\n", strerror(errno));
112 		return 1;
113 	}
114 
115 	if (expected_ids.ruid != (uid_t)-1) {
116 		if (expected_ids.ruid != real_ids.ruid) {
117 			printf("MOCK_TEST ruid mismatch - ruid=%u, expected ruid=%u\n",
118 			       real_ids.ruid,
119 			       expected_ids.ruid);
120 			return 1;
121 		}
122 		printf("MOCK_TEST ruid=%d\n", real_ids.ruid);
123 	}
124 
125 	if (expected_ids.euid != (uid_t)-1) {
126 		if (expected_ids.euid != real_ids.euid) {
127 			printf("MOCK_TEST euid mismatch - euid=%u, expected euid=%u\n",
128 			       real_ids.euid,
129 			       expected_ids.euid);
130 			return 1;
131 		}
132 		printf("MOCK_TEST euid=%d\n", real_ids.euid);
133 	}
134 
135 	if (expected_ids.suid != (uid_t)-1) {
136 		if (expected_ids.suid != real_ids.suid) {
137 			printf("MOCK_TEST suid mismatch - suid=%u, expected suid=%u\n",
138 			       real_ids.suid,
139 			       expected_ids.suid);
140 			return 1;
141 		}
142 		printf("MOCK_TEST suid=%d\n", real_ids.suid);
143 	}
144 
145 	real_ids.gid = getgid();
146 	if (real_ids.gid != (gid_t)-1) {
147 		if (expected_ids.gid != real_ids.gid) {
148 			printf("MOCK_TEST gid mismatch - gid=%u, expected gid=%u\n",
149 			       real_ids.gid,
150 			       expected_ids.gid);
151 			return 1;
152 		}
153 		printf("MOCK_TEST gid=%d\n", real_ids.gid);
154 	}
155 
156 	return 0;
157 }
158