• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #ifndef OHOS_STORAGE_DAEMON_ACL_H
16 #define OHOS_STORAGE_DAEMON_ACL_H
17 
18 #include <set>
19 
20 namespace OHOS {
21 namespace StorageDaemon {
22 /*
23  * ACL extended attributes (xattr) names
24  */
25 constexpr const char *ACL_XATTR_ACCESS  = "system.posix_acl_access";
26 constexpr const char *ACL_XATTR_DEFAULT = "system.posix_acl_default";
27 
28 /*
29  * ACL tag values
30  */
31 enum class ACL_TAG : uint16_t {
32     UNDEFINED = 0x00,
33     USER_OBJ  = 0x01,
34     USER      = 0x02,
35     GROUP_OBJ = 0x04,
36     GROUP     = 0x08,
37     MASK      = 0x10,
38     OTHER     = 0x20,
39 };
40 
41 /*
42  * ACL perm values
43  */
44 class ACL_PERM {
45     uint16_t value = 0;
46     enum Value : uint16_t {
47         READ    = 0x04,
48         WRITE   = 0x02,
49         EXECUTE = 0x01,
50     };
51 public:
52     ACL_PERM() = default;
ACL_PERM(const uint16_t x)53     ACL_PERM(const uint16_t x)
54     {
55         value = (x & READ) | (x & WRITE) | (x & EXECUTE);
56     }
SetR()57     void SetR()
58     {
59         value |= READ;
60     }
SetW()61     void SetW()
62     {
63         value |= WRITE;
64     }
SetE()65     void SetE()
66     {
67         value |= EXECUTE;
68     }
IsReadable()69     bool IsReadable() const
70     {
71         return value & READ;
72     }
IsWritable()73     bool IsWritable() const
74     {
75         return value & WRITE;
76     }
IsExecutable()77     bool IsExecutable() const
78     {
79         return value & EXECUTE;
80     }
Merge(const ACL_PERM & acl_perm)81     void Merge(const ACL_PERM &acl_perm)
82     {
83         value |= acl_perm.value;
84     }
85 };
86 
87 /*
88  * Other constants
89  */
90 constexpr uint32_t ACL_EA_VERSION = 0x0002;
91 constexpr uint32_t ACL_UNDEFINED_ID = (uint32_t)-1;
92 
93 /*
94  * ACL data structure
95  */
96 struct AclXattrHeader {
97     uint32_t version = ACL_EA_VERSION;
98 };
99 
100 struct AclXattrEntry {
101     ACL_TAG tag = ACL_TAG::UNDEFINED;
102     ACL_PERM perm = {};
103     uint32_t id = ACL_UNDEFINED_ID;
IsValidAclXattrEntry104     bool IsValid() const
105     {
106         if (tag == ACL_TAG::USER || tag == ACL_TAG::GROUP) {
107             return id != ACL_UNDEFINED_ID;
108         }
109         return tag != ACL_TAG::UNDEFINED;
110     }
111     bool operator<(const AclXattrEntry &rhs) const
112     {
113         if (tag == rhs.tag) {
114             return id < rhs.id;
115         }
116         return tag < rhs.tag;
117     }
118     friend inline bool operator<(const AclXattrEntry &lhs, const ACL_TAG &rhs)
119     {
120         return lhs.tag < rhs;
121     }
122     friend inline bool operator<(const ACL_TAG &lhs, const AclXattrEntry &rhs)
123     {
124         return lhs < rhs.tag;
125     }
126 };
127 
128 class Acl {
129     AclXattrHeader header;
130     /*
131      * Only one entry should exist for the following types:
132      *     ACL_USER_OBJ
133      *     ACL_GROUP_OBJ
134      *     ACL_MASK
135      *     ACL_OTHER
136      * While for these types, multiple entries could exist, but one entry
137      * for each id (i.e. uid/gid):
138      *     ACL_USER
139      *     ACL_GROUP
140      */
141     std::set<AclXattrEntry, std::less<>> entries;
142     char *buf = nullptr;
143     unsigned maskDemand = 0;
144     constexpr static size_t ENTRIES_MAX_NUM = 100; // just heuristic
145     constexpr static size_t BUF_MAX_SIZE = sizeof(AclXattrHeader) + sizeof(AclXattrEntry) * ENTRIES_MAX_NUM;
146     ACL_PERM ReCalcMaskPerm();
147 public:
148     bool IsEmpty();
149     bool IsValid();
150     int InsertEntry(const AclXattrEntry &entry);
151     char *Serialize(size_t &bufSize);
152     int DeSerialize(const char *p, size_t size);
153     ~Acl();
154 private:
155     void CompareInsertEntry(const AclXattrEntry &entry);
156     void SetMaskEntry();
157 };
158 
159 int AclSetDefault(const std::string &targetFile, const std::string &entryTxt);
160 } // STORAGE_DAEMON
161 } // OHOS
162 
163 #endif // OHOS_STORAGE_DAEMON_ACL_H
164