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