• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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