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