xref: /aosp_15_r20/external/selinux/libselinux/src/compute_user.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
3*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
5*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
6*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
7*2d543d20SAndroid Build Coastguard Worker #include <string.h>
8*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
9*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
10*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
11*2d543d20SAndroid Build Coastguard Worker #include "callbacks.h"
12*2d543d20SAndroid Build Coastguard Worker 
security_compute_user_raw(const char * scon,const char * user,char *** con)13*2d543d20SAndroid Build Coastguard Worker int security_compute_user_raw(const char * scon,
14*2d543d20SAndroid Build Coastguard Worker 			      const char *user, char *** con)
15*2d543d20SAndroid Build Coastguard Worker {
16*2d543d20SAndroid Build Coastguard Worker 	char path[PATH_MAX];
17*2d543d20SAndroid Build Coastguard Worker 	char **ary;
18*2d543d20SAndroid Build Coastguard Worker 	char *buf, *ptr;
19*2d543d20SAndroid Build Coastguard Worker 	size_t size;
20*2d543d20SAndroid Build Coastguard Worker 	int fd, ret;
21*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, nel;
22*2d543d20SAndroid Build Coastguard Worker 
23*2d543d20SAndroid Build Coastguard Worker 	if (!selinux_mnt) {
24*2d543d20SAndroid Build Coastguard Worker 		errno = ENOENT;
25*2d543d20SAndroid Build Coastguard Worker 		return -1;
26*2d543d20SAndroid Build Coastguard Worker 	}
27*2d543d20SAndroid Build Coastguard Worker 
28*2d543d20SAndroid Build Coastguard Worker 	selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n");
29*2d543d20SAndroid Build Coastguard Worker 
30*2d543d20SAndroid Build Coastguard Worker 	snprintf(path, sizeof path, "%s/user", selinux_mnt);
31*2d543d20SAndroid Build Coastguard Worker 	fd = open(path, O_RDWR | O_CLOEXEC);
32*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0)
33*2d543d20SAndroid Build Coastguard Worker 		return -1;
34*2d543d20SAndroid Build Coastguard Worker 
35*2d543d20SAndroid Build Coastguard Worker 	size = selinux_page_size;
36*2d543d20SAndroid Build Coastguard Worker 	buf = malloc(size);
37*2d543d20SAndroid Build Coastguard Worker 	if (!buf) {
38*2d543d20SAndroid Build Coastguard Worker 		ret = -1;
39*2d543d20SAndroid Build Coastguard Worker 		goto out;
40*2d543d20SAndroid Build Coastguard Worker 	}
41*2d543d20SAndroid Build Coastguard Worker 
42*2d543d20SAndroid Build Coastguard Worker 	ret = snprintf(buf, size, "%s %s", scon, user);
43*2d543d20SAndroid Build Coastguard Worker 	if (ret < 0 || (size_t)ret >= size) {
44*2d543d20SAndroid Build Coastguard Worker 		errno = EOVERFLOW;
45*2d543d20SAndroid Build Coastguard Worker 		ret = -1;
46*2d543d20SAndroid Build Coastguard Worker 		goto out2;
47*2d543d20SAndroid Build Coastguard Worker 	}
48*2d543d20SAndroid Build Coastguard Worker 
49*2d543d20SAndroid Build Coastguard Worker 	ret = write(fd, buf, strlen(buf));
50*2d543d20SAndroid Build Coastguard Worker 	if (ret < 0)
51*2d543d20SAndroid Build Coastguard Worker 		goto out2;
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker 	memset(buf, 0, size);
54*2d543d20SAndroid Build Coastguard Worker 	ret = read(fd, buf, size - 1);
55*2d543d20SAndroid Build Coastguard Worker 	if (ret < 0)
56*2d543d20SAndroid Build Coastguard Worker 		goto out2;
57*2d543d20SAndroid Build Coastguard Worker 
58*2d543d20SAndroid Build Coastguard Worker 	if (sscanf(buf, "%u", &nel) != 1) {
59*2d543d20SAndroid Build Coastguard Worker 		ret = -1;
60*2d543d20SAndroid Build Coastguard Worker 		goto out2;
61*2d543d20SAndroid Build Coastguard Worker 	}
62*2d543d20SAndroid Build Coastguard Worker 
63*2d543d20SAndroid Build Coastguard Worker 	ary = malloc((nel + 1) * sizeof(char *));
64*2d543d20SAndroid Build Coastguard Worker 	if (!ary) {
65*2d543d20SAndroid Build Coastguard Worker 		ret = -1;
66*2d543d20SAndroid Build Coastguard Worker 		goto out2;
67*2d543d20SAndroid Build Coastguard Worker 	}
68*2d543d20SAndroid Build Coastguard Worker 
69*2d543d20SAndroid Build Coastguard Worker 	ptr = buf + strlen(buf) + 1;
70*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
71*2d543d20SAndroid Build Coastguard Worker 		ary[i] = strdup(ptr);
72*2d543d20SAndroid Build Coastguard Worker 		if (!ary[i]) {
73*2d543d20SAndroid Build Coastguard Worker 			freeconary(ary);
74*2d543d20SAndroid Build Coastguard Worker 			ret = -1;
75*2d543d20SAndroid Build Coastguard Worker 			goto out2;
76*2d543d20SAndroid Build Coastguard Worker 		}
77*2d543d20SAndroid Build Coastguard Worker 		ptr += strlen(ptr) + 1;
78*2d543d20SAndroid Build Coastguard Worker 	}
79*2d543d20SAndroid Build Coastguard Worker 	ary[nel] = NULL;
80*2d543d20SAndroid Build Coastguard Worker 	*con = ary;
81*2d543d20SAndroid Build Coastguard Worker 	ret = 0;
82*2d543d20SAndroid Build Coastguard Worker       out2:
83*2d543d20SAndroid Build Coastguard Worker 	free(buf);
84*2d543d20SAndroid Build Coastguard Worker       out:
85*2d543d20SAndroid Build Coastguard Worker 	close(fd);
86*2d543d20SAndroid Build Coastguard Worker 	return ret;
87*2d543d20SAndroid Build Coastguard Worker }
88*2d543d20SAndroid Build Coastguard Worker 
89*2d543d20SAndroid Build Coastguard Worker 
security_compute_user(const char * scon,const char * user,char *** con)90*2d543d20SAndroid Build Coastguard Worker int security_compute_user(const char * scon,
91*2d543d20SAndroid Build Coastguard Worker 			  const char *user, char *** con)
92*2d543d20SAndroid Build Coastguard Worker {
93*2d543d20SAndroid Build Coastguard Worker 	int ret;
94*2d543d20SAndroid Build Coastguard Worker 	char * rscon;
95*2d543d20SAndroid Build Coastguard Worker 
96*2d543d20SAndroid Build Coastguard Worker 	if (selinux_trans_to_raw_context(scon, &rscon))
97*2d543d20SAndroid Build Coastguard Worker 		return -1;
98*2d543d20SAndroid Build Coastguard Worker 
99*2d543d20SAndroid Build Coastguard Worker 	IGNORE_DEPRECATED_DECLARATION_BEGIN
100*2d543d20SAndroid Build Coastguard Worker 	ret = security_compute_user_raw(rscon, user, con);
101*2d543d20SAndroid Build Coastguard Worker 	IGNORE_DEPRECATED_DECLARATION_END
102*2d543d20SAndroid Build Coastguard Worker 
103*2d543d20SAndroid Build Coastguard Worker 	freecon(rscon);
104*2d543d20SAndroid Build Coastguard Worker 	if (!ret) {
105*2d543d20SAndroid Build Coastguard Worker 		char **ptr, *tmpcon;
106*2d543d20SAndroid Build Coastguard Worker 		for (ptr = *con; *ptr; ptr++) {
107*2d543d20SAndroid Build Coastguard Worker 			if (selinux_raw_to_trans_context(*ptr, &tmpcon)) {
108*2d543d20SAndroid Build Coastguard Worker 				freeconary(*con);
109*2d543d20SAndroid Build Coastguard Worker 				*con = NULL;
110*2d543d20SAndroid Build Coastguard Worker 				return -1;
111*2d543d20SAndroid Build Coastguard Worker 			}
112*2d543d20SAndroid Build Coastguard Worker 			freecon(*ptr);
113*2d543d20SAndroid Build Coastguard Worker 			*ptr = tmpcon;
114*2d543d20SAndroid Build Coastguard Worker 		}
115*2d543d20SAndroid Build Coastguard Worker 	}
116*2d543d20SAndroid Build Coastguard Worker 
117*2d543d20SAndroid Build Coastguard Worker 	return ret;
118*2d543d20SAndroid Build Coastguard Worker }
119*2d543d20SAndroid Build Coastguard Worker 
120