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 snprintf(buf, size, "%s %s", scon, user);
42
43 ret = write(fd, buf, strlen(buf));
44 if (ret < 0)
45 goto out2;
46
47 memset(buf, 0, size);
48 ret = read(fd, buf, size - 1);
49 if (ret < 0)
50 goto out2;
51
52 if (sscanf(buf, "%u", &nel) != 1) {
53 ret = -1;
54 goto out2;
55 }
56
57 ary = malloc((nel + 1) * sizeof(char *));
58 if (!ary) {
59 ret = -1;
60 goto out2;
61 }
62
63 ptr = buf + strlen(buf) + 1;
64 for (i = 0; i < nel; i++) {
65 ary[i] = strdup(ptr);
66 if (!ary[i]) {
67 freeconary(ary);
68 ret = -1;
69 goto out2;
70 }
71 ptr += strlen(ptr) + 1;
72 }
73 ary[nel] = NULL;
74 *con = ary;
75 ret = 0;
76 out2:
77 free(buf);
78 out:
79 close(fd);
80 return ret;
81 }
82
83
security_compute_user(const char * scon,const char * user,char *** con)84 int security_compute_user(const char * scon,
85 const char *user, char *** con)
86 {
87 int ret;
88 char * rscon;
89
90 if (selinux_trans_to_raw_context(scon, &rscon))
91 return -1;
92
93 ret = security_compute_user_raw(rscon, user, con);
94
95 freecon(rscon);
96 if (!ret) {
97 char **ptr, *tmpcon;
98 for (ptr = *con; *ptr; ptr++) {
99 if (selinux_raw_to_trans_context(*ptr, &tmpcon)) {
100 freeconary(*con);
101 *con = NULL;
102 return -1;
103 }
104 freecon(*ptr);
105 *ptr = tmpcon;
106 }
107 }
108
109 return ret;
110 }
111
112