blob: 9559d421219742718aff66119c1e9cdb4316287c [file] [log] [blame]
Joshua Brindle13cd4c82008-08-19 15:30:36 -04001#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 <limits.h>
Kohei KaiGai2b5a0532012-03-25 22:05:17 +02009#include <ctype.h>
Joshua Brindle13cd4c82008-08-19 15:30:36 -040010#include "selinux_internal.h"
11#include "policy.h"
12#include "mapping.h"
13
Kohei KaiGai2b5a0532012-03-25 22:05:17 +020014static int object_name_encode(const char *objname, char *buffer, size_t buflen)
15{
16 int code;
17 size_t offset = 0;
18
19 if (buflen - offset < 1)
20 return -1;
21 buffer[offset++] = ' ';
22
23 do {
24 code = *objname++;
25
26 if (isalnum(code) || code == '\0' || code == '-' ||
27 code == '.' || code == '_' || code == '~') {
28 if (buflen - offset < 1)
29 return -1;
30 buffer[offset++] = code;
31 } else if (code == ' ') {
32 if (buflen - offset < 1)
33 return -1;
34 buffer[offset++] = '+';
35 } else {
36 static const char *table = "0123456789ABCDEF";
37 int l = (code & 0x0f);
38 int h = (code & 0xf0) >> 4;
39
40 if (buflen - offset < 3)
41 return -1;
42 buffer[offset++] = '%';
43 buffer[offset++] = table[h];
44 buffer[offset++] = table[l];
45 }
46 } while (code != '\0');
47
48 return 0;
49}
50
Stephen Smalley9eb9c932014-02-19 09:16:17 -050051int security_compute_create_name_raw(const char * scon,
52 const char * tcon,
Kohei KaiGai2b5a0532012-03-25 22:05:17 +020053 security_class_t tclass,
54 const char *objname,
Stephen Smalley9eb9c932014-02-19 09:16:17 -050055 char ** newcon)
Joshua Brindle13cd4c82008-08-19 15:30:36 -040056{
57 char path[PATH_MAX];
58 char *buf;
59 size_t size;
Kohei KaiGai2b5a0532012-03-25 22:05:17 +020060 int fd, ret, len;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040061
62 if (!selinux_mnt) {
63 errno = ENOENT;
64 return -1;
65 }
66
67 snprintf(path, sizeof path, "%s/create", selinux_mnt);
68 fd = open(path, O_RDWR);
69 if (fd < 0)
70 return -1;
71
72 size = selinux_page_size;
73 buf = malloc(size);
74 if (!buf) {
75 ret = -1;
76 goto out;
77 }
Kohei KaiGai2b5a0532012-03-25 22:05:17 +020078 len = snprintf(buf, size, "%s %s %hu",
79 scon, tcon, unmap_class(tclass));
80 if (objname &&
81 object_name_encode(objname, buf + len, size - len) < 0) {
82 errno = ENAMETOOLONG;
83 ret = -1;
84 goto out2;
85 }
Joshua Brindle13cd4c82008-08-19 15:30:36 -040086
87 ret = write(fd, buf, strlen(buf));
88 if (ret < 0)
89 goto out2;
90
91 memset(buf, 0, size);
92 ret = read(fd, buf, size - 1);
93 if (ret < 0)
94 goto out2;
95
96 *newcon = strdup(buf);
97 if (!(*newcon)) {
98 ret = -1;
99 goto out2;
100 }
101 ret = 0;
102 out2:
103 free(buf);
104 out:
105 close(fd);
106 return ret;
107}
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200108hidden_def(security_compute_create_name_raw)
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400109
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500110int security_compute_create_raw(const char * scon,
111 const char * tcon,
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200112 security_class_t tclass,
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500113 char ** newcon)
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200114{
115 return security_compute_create_name_raw(scon, tcon, tclass,
116 NULL, newcon);
117}
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400118hidden_def(security_compute_create_raw)
119
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500120int security_compute_create_name(const char * scon,
121 const char * tcon,
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200122 security_class_t tclass,
123 const char *objname,
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500124 char ** newcon)
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400125{
126 int ret;
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500127 char * rscon;
128 char * rtcon;
129 char * rnewcon;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400130
131 if (selinux_trans_to_raw_context(scon, &rscon))
132 return -1;
133 if (selinux_trans_to_raw_context(tcon, &rtcon)) {
134 freecon(rscon);
135 return -1;
136 }
137
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200138 ret = security_compute_create_name_raw(rscon, rtcon, tclass,
139 objname, &rnewcon);
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400140 freecon(rscon);
141 freecon(rtcon);
142 if (!ret) {
143 ret = selinux_raw_to_trans_context(rnewcon, newcon);
144 freecon(rnewcon);
145 }
146
147 return ret;
148}
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200149hidden_def(security_compute_create_name)
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400150
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500151int security_compute_create(const char * scon,
152 const char * tcon,
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200153 security_class_t tclass,
Stephen Smalley9eb9c932014-02-19 09:16:17 -0500154 char ** newcon)
Kohei KaiGai2b5a0532012-03-25 22:05:17 +0200155{
156 return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
157}
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400158hidden_def(security_compute_create)