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