1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define __cpluscplus
17 #include "dac_config.h"
18
19 #include <fstream>
20 #include <iostream>
21 #include <sstream>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 #include <linux/capability.h>
26
27 using namespace std;
28
29 namespace {
30 struct DacConfig {
31 unsigned int uid;
32 unsigned int gid;
33 unsigned int mode;
34 uint64_t capabilities;
35 string path;
36
DacConfig__anone94bee0c0111::DacConfig37 DacConfig() : uid(0), gid(0), mode(0), capabilities(0), path("") {}
DacConfig__anone94bee0c0111::DacConfig38 DacConfig(unsigned int m, unsigned int u, unsigned int g, uint64_t c, const string &p) :
39 uid(u),
40 gid(g),
41 mode(m),
42 capabilities(c),
43 path(p) {}
44
SetDefault__anone94bee0c0111::DacConfig45 void SetDefault(unsigned int m, unsigned int u, unsigned int g, uint64_t c, const string &p)
46 {
47 this->uid = u;
48 this->gid = g;
49 this->mode = m;
50 this->capabilities = c;
51 this->path = p;
52 }
53 };
54
55 unordered_map<string, DacConfig> g_configMap;
56
Trim(const string & s)57 static string Trim(const string& s)
58 {
59 if (s.size() == 0) {
60 return s;
61 }
62
63 size_t start = 0;
64 size_t end = s.size() - 1;
65
66 while (start < s.size() && isspace(s[start])) {
67 start++;
68 }
69
70 while (end >= start && isspace(s[end])) {
71 end--;
72 }
73
74 if (end < start) {
75 return "";
76 }
77
78 return s.substr(start, end - start + 1);
79 }
80
81 unordered_map<string, unsigned int> g_capStrCapNum = {
82 { "CAP_CHOWN", CAP_CHOWN },
83 { "CAP_DAC_OVERRIDE", CAP_DAC_OVERRIDE },
84 { "CAP_DAC_READ_SEARCH", CAP_DAC_READ_SEARCH },
85 { "CAP_FOWNER", CAP_FOWNER },
86 { "CAP_FSETID", CAP_FSETID },
87 { "CAP_KILL", CAP_KILL },
88 { "CAP_SETGID", CAP_SETGID },
89 { "CAP_SETUID", CAP_SETUID },
90 { "CAP_LINUX_IMMUTABLE", CAP_LINUX_IMMUTABLE },
91 { "CAP_NET_BIND_SERVICE", CAP_NET_BIND_SERVICE },
92 { "CAP_NET_BROADCAST", CAP_NET_BROADCAST },
93 { "CAP_NET_ADMIN", CAP_NET_ADMIN },
94 { "CAP_NET_RAW", CAP_NET_RAW },
95 { "CAP_IPC_LOCK", CAP_IPC_LOCK },
96 { "CAP_IPC_OWNER", CAP_IPC_OWNER },
97 { "CAP_SYS_MODULE", CAP_SYS_MODULE },
98 { "CAP_SYS_RAWIO", CAP_SYS_RAWIO },
99 { "CAP_SYS_CHROOT", CAP_SYS_CHROOT },
100 { "CAP_SYS_PTRACE", CAP_SYS_PTRACE },
101 { "CAP_SYS_PACCT", CAP_SYS_PACCT },
102 { "CAP_SYS_ADMIN", CAP_SYS_ADMIN },
103 { "CAP_SYS_ROOT", CAP_SYS_BOOT },
104 { "CAP_SYS_NICE", CAP_SYS_NICE },
105 { "CAP_SYS_RESOURCE", CAP_SYS_RESOURCE },
106 { "CAP_SYS_TIME", CAP_SYS_TIME },
107 { "CAP_SYS_TTY_CONFIG", CAP_SYS_TTY_CONFIG },
108 { "CAP_MKNOD", CAP_MKNOD },
109 { "CAP_LEASE", CAP_LEASE },
110 { "CAP_AUDIT_WRITE", CAP_AUDIT_WRITE },
111 { "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL },
112 { "CAP_SETFCAP", CAP_SETFCAP },
113 { "CAP_MAC_OVERRIDE", CAP_MAC_OVERRIDE },
114 { "CAP_MAC_ADMIN", CAP_MAC_ADMIN },
115 { "CAP_SYSLOG", CAP_SYSLOG },
116 { "CAP_WAKE_ALARM", CAP_WAKE_ALARM },
117 { "CAP_BLOCK_SUSPEND", CAP_BLOCK_SUSPEND },
118 };
119
GetCap(string cap)120 static uint64_t GetCap(string cap)
121 {
122 if (isdigit(cap[0])) {
123 return stoll(cap);
124 }
125
126 stringstream ss(cap);
127 string value;
128 uint64_t c = 0;
129 while (getline(ss, value, '|')) {
130 value = Trim(value);
131 if (g_capStrCapNum.count(value)) {
132 c |= (1ULL << g_capStrCapNum[value]);
133 }
134 }
135
136 return c;
137 }
138
139 enum {
140 DAC_PATH_IDX = 0,
141 DAC_MODE_IDX,
142 DAC_UID_IDX,
143 DAC_GID_IDX,
144 DAC_CAP_IDX,
145 DAC_NUM
146 };
147
148 extern "C" {
LoadDacConfig(const char * fn)149 int LoadDacConfig(const char* fn)
150 {
151 ifstream readFile(fn);
152 if (readFile.fail()) {
153 return -1;
154 }
155
156 string str;
157 vector<string> values(DAC_NUM, ""); // path, mode, uid, gid, cap
158 while (getline(readFile, str)) {
159 str = Trim(str);
160 if (str.empty() || str[0] == '#') {
161 continue;
162 }
163
164 stringstream ss(str);
165 string value;
166 int i = 0;
167 while (getline(ss, value, ',')) {
168 if (i >= DAC_NUM) {
169 break;
170 }
171
172 value = Trim(value);
173 if (value.empty()) {
174 continue;
175 }
176 values[i++] = value;
177 }
178
179 if (i != DAC_NUM) {
180 continue;
181 }
182
183 int uid = 0;
184 if (isdigit(values[DAC_UID_IDX][0])) {
185 uid = stoi(values[DAC_UID_IDX]);
186 }
187
188 int gid = 0;
189 if (isdigit(values[DAC_GID_IDX][0])) {
190 uid = stoi(values[DAC_GID_IDX]);
191 }
192
193 uint64_t cap = GetCap(values[DAC_CAP_IDX]);
194 DacConfig dacConfig(stoi(values[DAC_MODE_IDX], 0, 8), uid, gid, cap, values[DAC_PATH_IDX]); // 8 oct
195 g_configMap[dacConfig.path] = dacConfig;
196 }
197
198 return 0;
199 }
200
GetDacConfig(const char * path,int dir,char *,unsigned * uid,unsigned * gid,unsigned * mode,uint64_t * capabilities)201 void GetDacConfig(const char* path, int dir, char*,
202 unsigned* uid, unsigned* gid, unsigned* mode,
203 uint64_t* capabilities)
204 {
205 string str = (path != nullptr && *path == '/') ? path + 1 : path;
206 DacConfig dacConfig(00755, 0, 0, 0, "");
207
208 if (dir == 0) {
209 dacConfig.SetDefault(00644, 0, 0, 0, "");
210 }
211
212 auto it = g_configMap.find(str);
213 if (it != g_configMap.end()) {
214 dacConfig = it->second;
215 } else if (dir == 0 && !str.empty()) {
216 for (int i = static_cast<int>(str.size()) - 1; i >= 0; i--) {
217 if (str[i] == '/') {
218 break;
219 } else {
220 it = g_configMap.find(str.substr(0, i) + "*");
221 if (it != g_configMap.end()) {
222 dacConfig = it->second;
223 break;
224 }
225 }
226 }
227 }
228
229 *uid = dacConfig.uid;
230 *gid = dacConfig.gid;
231 *mode = dacConfig.mode;
232 *capabilities = dacConfig.capabilities;
233 }
234 }
235 }
236