Home | History | Annotate | Download | only in src
      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);
     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