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