File: mock_exec_uid.c

package info (click to toggle)
uid-wrapper 1.2.4%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 476 kB
  • sloc: ansic: 5,244; makefile: 48; sh: 11
file content (157 lines) | stat: -rw-r--r-- 3,593 bytes parent folder | download | duplicates (4)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "config.h"

#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>

#ifndef discard_const
#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
#endif

#ifndef discard_const_p
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
#endif

struct user_ids {
	uid_t ruid;
	uid_t euid;
	uid_t suid;
	gid_t gid;
};

static void print_usage(const char *prog_name)
{
	fprintf(stderr,
		"Usage: %s [-r ruid] [-e euid] [-s suid] [-g gid]\n"
		"\n"
		"    -r The ruid to validate\n"
		"    -e The euid to validate\n"
		"    -s The suid to validate\n"
		"    -g The gid to validate\n"
		"\n",
		prog_name);
}

int main(int argc, char *argv[])
{
	const struct option long_options[] = {
		{ discard_const_p(char, "ruid"),  required_argument,  0, 'r' },
		{ discard_const_p(char, "euid"),  required_argument,  0, 'e' },
		{ discard_const_p(char, "suid"),  required_argument,  0, 's' },
		{ discard_const_p(char, "gid"),   required_argument,  0, 'g' },
		{ 0,                              0,                  0, 0 }
	};
	int opt_idx;
	int opt;
	struct user_ids expected_ids = {
		.ruid = (uid_t)-1,
		.euid = (uid_t)-1,
		.suid = (uid_t)-1,
		.gid  = (gid_t)-1,
	};
	struct user_ids real_ids = {
		.ruid = (uid_t)-1,
		.euid = (uid_t)-1,
		.suid = (uid_t)-1,
		.gid  = (gid_t)-1,
	};
	int rc;

	for (opt = getopt_long(argc, argv, "r:e:s:g:", long_options, &opt_idx);
	     opt != -1;
	     opt = getopt_long(argc, argv, "r:e:s:g:", long_options, &opt_idx)) {
		errno = 0;

		switch (opt) {
			case 0:
				break;
			case 'r':
				expected_ids.ruid = strtol(optarg,
							   (char **)NULL,
							   10);
				break;
			case 'e':
				expected_ids.euid = strtol(optarg,
						           (char **)NULL,
							   10);
				break;
			case 's':
				expected_ids.suid = strtol(optarg,
						           (char **)NULL,
							   10);
				break;
			case 'g':
				expected_ids.gid = strtol(optarg,
						          (char **)NULL,
							  10);
				break;
			default:
				print_usage(argv[0]);
				return 1;
		}

		if (errno == EINVAL || errno == ERANGE) {
			return 1;
		}
	}

	if (expected_ids.ruid == (uid_t)-1 &&
	    expected_ids.euid == (uid_t)-1 &&
	    expected_ids.suid == (uid_t)-1) {
		print_usage(argv[0]);
		return 1;
	}

	rc = getresuid(&real_ids.ruid, &real_ids.euid, &real_ids.suid);
	if (rc != 0) {
		fprintf(stderr, "getresuid() failed - %s\n", strerror(errno));
		return 1;
	}

	if (expected_ids.ruid != (uid_t)-1) {
		if (expected_ids.ruid != real_ids.ruid) {
			printf("MOCK_TEST ruid mismatch - ruid=%u, expected ruid=%u\n",
			       real_ids.ruid,
			       expected_ids.ruid);
			return 1;
		}
		printf("MOCK_TEST ruid=%d\n", real_ids.ruid);
	}

	if (expected_ids.euid != (uid_t)-1) {
		if (expected_ids.euid != real_ids.euid) {
			printf("MOCK_TEST euid mismatch - euid=%u, expected euid=%u\n",
			       real_ids.euid,
			       expected_ids.euid);
			return 1;
		}
		printf("MOCK_TEST euid=%d\n", real_ids.euid);
	}

	if (expected_ids.suid != (uid_t)-1) {
		if (expected_ids.suid != real_ids.suid) {
			printf("MOCK_TEST suid mismatch - suid=%u, expected suid=%u\n",
			       real_ids.suid,
			       expected_ids.suid);
			return 1;
		}
		printf("MOCK_TEST suid=%d\n", real_ids.suid);
	}

	real_ids.gid = getgid();
	if (real_ids.gid != (gid_t)-1) {
		if (expected_ids.gid != real_ids.gid) {
			printf("MOCK_TEST gid mismatch - gid=%u, expected gid=%u\n",
			       real_ids.gid,
			       expected_ids.gid);
			return 1;
		}
		printf("MOCK_TEST gid=%d\n", real_ids.gid);
	}

	return 0;
}