16cd6a6acSopenharmony_ci#include <unistd.h> 26cd6a6acSopenharmony_ci#include <sys/types.h> 36cd6a6acSopenharmony_ci#include <fcntl.h> 46cd6a6acSopenharmony_ci#include <stdlib.h> 56cd6a6acSopenharmony_ci#include <stdio.h> 66cd6a6acSopenharmony_ci#include <errno.h> 76cd6a6acSopenharmony_ci#include <string.h> 86cd6a6acSopenharmony_ci#include "selinux_internal.h" 96cd6a6acSopenharmony_ci#include "policy.h" 106cd6a6acSopenharmony_ci#include <limits.h> 116cd6a6acSopenharmony_ci#include "callbacks.h" 126cd6a6acSopenharmony_ci 136cd6a6acSopenharmony_ciint security_compute_user_raw(const char * scon, 146cd6a6acSopenharmony_ci const char *user, char *** con) 156cd6a6acSopenharmony_ci{ 166cd6a6acSopenharmony_ci char path[PATH_MAX]; 176cd6a6acSopenharmony_ci char **ary; 186cd6a6acSopenharmony_ci char *buf, *ptr; 196cd6a6acSopenharmony_ci size_t size; 206cd6a6acSopenharmony_ci int fd, ret; 216cd6a6acSopenharmony_ci unsigned int i, nel; 226cd6a6acSopenharmony_ci 236cd6a6acSopenharmony_ci if (!selinux_mnt) { 246cd6a6acSopenharmony_ci errno = ENOENT; 256cd6a6acSopenharmony_ci return -1; 266cd6a6acSopenharmony_ci } 276cd6a6acSopenharmony_ci 286cd6a6acSopenharmony_ci selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n"); 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci snprintf(path, sizeof path, "%s/user", selinux_mnt); 316cd6a6acSopenharmony_ci fd = open(path, O_RDWR | O_CLOEXEC); 326cd6a6acSopenharmony_ci if (fd < 0) 336cd6a6acSopenharmony_ci return -1; 346cd6a6acSopenharmony_ci 356cd6a6acSopenharmony_ci size = selinux_page_size; 366cd6a6acSopenharmony_ci buf = malloc(size); 376cd6a6acSopenharmony_ci if (!buf) { 386cd6a6acSopenharmony_ci ret = -1; 396cd6a6acSopenharmony_ci goto out; 406cd6a6acSopenharmony_ci } 416cd6a6acSopenharmony_ci 426cd6a6acSopenharmony_ci ret = snprintf(buf, size, "%s %s", scon, user); 436cd6a6acSopenharmony_ci if (ret < 0 || (size_t)ret >= size) { 446cd6a6acSopenharmony_ci errno = EOVERFLOW; 456cd6a6acSopenharmony_ci ret = -1; 466cd6a6acSopenharmony_ci goto out2; 476cd6a6acSopenharmony_ci } 486cd6a6acSopenharmony_ci 496cd6a6acSopenharmony_ci ret = write(fd, buf, strlen(buf)); 506cd6a6acSopenharmony_ci if (ret < 0) 516cd6a6acSopenharmony_ci goto out2; 526cd6a6acSopenharmony_ci 536cd6a6acSopenharmony_ci memset(buf, 0, size); 546cd6a6acSopenharmony_ci ret = read(fd, buf, size - 1); 556cd6a6acSopenharmony_ci if (ret < 0) 566cd6a6acSopenharmony_ci goto out2; 576cd6a6acSopenharmony_ci 586cd6a6acSopenharmony_ci if (sscanf(buf, "%u", &nel) != 1) { 596cd6a6acSopenharmony_ci ret = -1; 606cd6a6acSopenharmony_ci goto out2; 616cd6a6acSopenharmony_ci } 626cd6a6acSopenharmony_ci 636cd6a6acSopenharmony_ci ary = malloc((nel + 1) * sizeof(char *)); 646cd6a6acSopenharmony_ci if (!ary) { 656cd6a6acSopenharmony_ci ret = -1; 666cd6a6acSopenharmony_ci goto out2; 676cd6a6acSopenharmony_ci } 686cd6a6acSopenharmony_ci 696cd6a6acSopenharmony_ci ptr = buf + strlen(buf) + 1; 706cd6a6acSopenharmony_ci for (i = 0; i < nel; i++) { 716cd6a6acSopenharmony_ci ary[i] = strdup(ptr); 726cd6a6acSopenharmony_ci if (!ary[i]) { 736cd6a6acSopenharmony_ci freeconary(ary); 746cd6a6acSopenharmony_ci ret = -1; 756cd6a6acSopenharmony_ci goto out2; 766cd6a6acSopenharmony_ci } 776cd6a6acSopenharmony_ci ptr += strlen(ptr) + 1; 786cd6a6acSopenharmony_ci } 796cd6a6acSopenharmony_ci ary[nel] = NULL; 806cd6a6acSopenharmony_ci *con = ary; 816cd6a6acSopenharmony_ci ret = 0; 826cd6a6acSopenharmony_ci out2: 836cd6a6acSopenharmony_ci free(buf); 846cd6a6acSopenharmony_ci out: 856cd6a6acSopenharmony_ci close(fd); 866cd6a6acSopenharmony_ci return ret; 876cd6a6acSopenharmony_ci} 886cd6a6acSopenharmony_ci 896cd6a6acSopenharmony_ci 906cd6a6acSopenharmony_ciint security_compute_user(const char * scon, 916cd6a6acSopenharmony_ci const char *user, char *** con) 926cd6a6acSopenharmony_ci{ 936cd6a6acSopenharmony_ci int ret; 946cd6a6acSopenharmony_ci char * rscon; 956cd6a6acSopenharmony_ci 966cd6a6acSopenharmony_ci if (selinux_trans_to_raw_context(scon, &rscon)) 976cd6a6acSopenharmony_ci return -1; 986cd6a6acSopenharmony_ci 996cd6a6acSopenharmony_ci ret = security_compute_user_raw(rscon, user, con); 1006cd6a6acSopenharmony_ci 1016cd6a6acSopenharmony_ci freecon(rscon); 1026cd6a6acSopenharmony_ci if (!ret) { 1036cd6a6acSopenharmony_ci char **ptr, *tmpcon; 1046cd6a6acSopenharmony_ci for (ptr = *con; *ptr; ptr++) { 1056cd6a6acSopenharmony_ci if (selinux_raw_to_trans_context(*ptr, &tmpcon)) { 1066cd6a6acSopenharmony_ci freeconary(*con); 1076cd6a6acSopenharmony_ci *con = NULL; 1086cd6a6acSopenharmony_ci return -1; 1096cd6a6acSopenharmony_ci } 1106cd6a6acSopenharmony_ci freecon(*ptr); 1116cd6a6acSopenharmony_ci *ptr = tmpcon; 1126cd6a6acSopenharmony_ci } 1136cd6a6acSopenharmony_ci } 1146cd6a6acSopenharmony_ci 1156cd6a6acSopenharmony_ci return ret; 1166cd6a6acSopenharmony_ci} 1176cd6a6acSopenharmony_ci 118