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 12 int security_compute_user_raw(const char * scon, 13 const char *user, char *** con) 14 { 15 char path[PATH_MAX]; 16 char **ary; 17 char *buf, *ptr; 18 size_t size; 19 int fd, ret; 20 unsigned int i, nel; 21 22 if (!selinux_mnt) { 23 errno = ENOENT; 24 return -1; 25 } 26 27 snprintf(path, sizeof path, "%s/user", selinux_mnt); 28 fd = open(path, O_RDWR | O_CLOEXEC); 29 if (fd < 0) 30 return -1; 31 32 size = selinux_page_size; 33 buf = malloc(size); 34 if (!buf) { 35 ret = -1; 36 goto out; 37 } 38 snprintf(buf, size, "%s %s", scon, user); 39 40 ret = write(fd, buf, strlen(buf)); 41 if (ret < 0) 42 goto out2; 43 44 memset(buf, 0, size); 45 ret = read(fd, buf, size - 1); 46 if (ret < 0) 47 goto out2; 48 49 if (sscanf(buf, "%u", &nel) != 1) { 50 ret = -1; 51 goto out2; 52 } 53 54 ary = malloc((nel + 1) * sizeof(char *)); 55 if (!ary) { 56 ret = -1; 57 goto out2; 58 } 59 60 ptr = buf + strlen(buf) + 1; 61 for (i = 0; i < nel; i++) { 62 ary[i] = strdup(ptr); 63 if (!ary[i]) { 64 freeconary(ary); 65 ret = -1; 66 goto out2; 67 } 68 ptr += strlen(ptr) + 1; 69 } 70 ary[nel] = NULL; 71 *con = ary; 72 ret = 0; 73 out2: 74 free(buf); 75 out: 76 close(fd); 77 return ret; 78 } 79 80 hidden_def(security_compute_user_raw) 81 82 int security_compute_user(const char * scon, 83 const char *user, char *** con) 84 { 85 int ret; 86 char * rscon; 87 88 if (selinux_trans_to_raw_context(scon, &rscon)) 89 return -1; 90 91 ret = security_compute_user_raw(rscon, user, con); 92 93 freecon(rscon); 94 if (!ret) { 95 char **ptr, *tmpcon; 96 for (ptr = *con; *ptr; ptr++) { 97 if (selinux_raw_to_trans_context(*ptr, &tmpcon)) { 98 freeconary(*con); 99 *con = NULL; 100 return -1; 101 } 102 freecon(*ptr); 103 *ptr = tmpcon; 104 } 105 } 106 107 return ret; 108 } 109 110 hidden_def(security_compute_user) 111