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