1 /* 2 * Copyright (C) 2023 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 #ifndef OHOS_MEDIALIBRARY_ACL_H 17 #define OHOS_MEDIALIBRARY_ACL_H 18 19 #include <functional> 20 #include <iosfwd> 21 #include <set> 22 #include <string> 23 24 #include "medialibrary_db_const.h" 25 26 namespace OHOS { 27 namespace Media { 28 #define EXPORT __attribute__ ((visibility ("default"))) 29 /* 30 * ACL extended attributes (xattr) names 31 */ 32 constexpr const char *ACL_XATTR_ACCESS = "system.posix_acl_access"; 33 constexpr const char *ACL_XATTR_DEFAULT = "system.posix_acl_default"; 34 35 /* 36 * ACL tag values 37 */ 38 enum class ACL_TAG : uint16_t { 39 UNDEFINED = 0x00, 40 USER_OBJ = 0x01, 41 USER = 0x02, 42 GROUP_OBJ = 0x04, 43 GROUP = 0x08, 44 MASK = 0x10, 45 OTHER = 0x20, 46 }; 47 48 /* 49 * ACL perm values 50 */ 51 class ACL_PERM { 52 uint16_t value = 0; 53 public: 54 enum Value : uint16_t { 55 READ = 0x04, 56 WRITE = 0x02, 57 EXECUTE = 0x01, 58 }; 59 ACL_PERM() = default; ACL_PERM(const uint16_t x)60 ACL_PERM(const uint16_t x) 61 { 62 value = (x & READ) | (x & WRITE) | (x & EXECUTE); 63 } SetRead()64 void SetRead() 65 { 66 value |= READ; 67 } SetWrite()68 void SetWrite() 69 { 70 value |= WRITE; 71 } SetExecute()72 void SetExecute() 73 { 74 value |= EXECUTE; 75 } IsReadable()76 bool IsReadable() const 77 { 78 return value & READ; 79 } IsWritable()80 bool IsWritable() const 81 { 82 return value & WRITE; 83 } IsExecutable()84 bool IsExecutable() const 85 { 86 return value & EXECUTE; 87 } Merge(const ACL_PERM & acl_perm)88 void Merge(const ACL_PERM &acl_perm) 89 { 90 value |= acl_perm.value; 91 } uint16_t()92 operator uint16_t() const 93 { 94 return value; 95 } 96 }; 97 98 /* 99 * Other constants 100 */ 101 constexpr uint32_t ACL_EA_VERSION = 0x0002; 102 constexpr uint32_t ACL_UNDEFINED_ID = (uint32_t)-1; 103 constexpr uint32_t THUMB_ACL_GROUP = 2008; 104 constexpr uint32_t MEDIA_DB_ACL_GROUP = 3008; 105 constexpr uint32_t DDMS_ACL_GROUP = 3012; 106 107 EXPORT const std::string THUMB_DIR = "/storage/cloud/files/.thumbs/Photo"; 108 EXPORT const std::string RDB_DIR = MEDIA_DB_DIR + "/rdb"; 109 EXPORT const std::string KVDB_DIR = MEDIA_DB_DIR + "/kvdb"; 110 /* 111 * ACL data structure 112 */ 113 struct AclXattrHeader { 114 uint32_t version = ACL_EA_VERSION; 115 }; 116 117 struct AclXattrEntry { 118 ACL_TAG tag = ACL_TAG::UNDEFINED; 119 ACL_PERM perm = {}; 120 uint32_t id = ACL_UNDEFINED_ID; IsValidAclXattrEntry121 bool IsValid() const 122 { 123 if (tag == ACL_TAG::USER || tag == ACL_TAG::GROUP) { 124 return id != ACL_UNDEFINED_ID; 125 } 126 return tag != ACL_TAG::UNDEFINED; 127 } 128 bool operator<(const AclXattrEntry &rhs) const 129 { 130 if (tag == rhs.tag) { 131 return id < rhs.id; 132 } 133 return tag < rhs.tag; 134 } 135 friend inline bool operator<(const AclXattrEntry &lhs, const ACL_TAG &rhs) 136 { 137 return lhs.tag < rhs; 138 } 139 friend inline bool operator<(const ACL_TAG &lhs, const AclXattrEntry &rhs) 140 { 141 return lhs < rhs.tag; 142 } 143 }; 144 145 class Acl { 146 public: 147 EXPORT bool IsEmpty(); 148 EXPORT bool IsValid(); 149 EXPORT int InsertEntry(const AclXattrEntry &entry); 150 EXPORT char *Serialize(size_t &bufSize); 151 EXPORT int DeSerialize(const char* aclHead, size_t size); 152 153 EXPORT static int32_t AclSetDefault(); 154 EXPORT static int32_t AclSetDatabase(); 155 EXPORT static int32_t AclSetSlaveDatabase(); 156 EXPORT static int32_t EntryInsert(AclXattrEntry& entry, const std::string& path, const char* aclAttrName); 157 EXPORT static int32_t RecursiveEnableAcl(const std::string& path, const char* aclAttrName, 158 const uint16_t& permission, uint32_t groupId); 159 EXPORT static int32_t EnableAcl(const std::string& path, const char* aclAttrName, 160 const uint16_t& permission, uint32_t groupId); 161 EXPORT void Print(const std::string& path); 162 EXPORT ~Acl(); 163 private: 164 void CompareInsertEntry(const AclXattrEntry &entry); 165 166 AclXattrHeader header; 167 /* 168 * Only one entry should exist for the following types: 169 * ACL_USER_OBJ 170 * ACL_GROUP_OBJ 171 * ACL_MASK 172 * ACL_OTHER 173 * While for these types, multiple entries could exist, but one entry 174 * for each id (i.e. uid/gid): 175 * ACL_USER 176 * ACL_GROUP 177 */ 178 std::set<AclXattrEntry, std::less<>> entries; 179 char *buf = nullptr; 180 unsigned maskDemand = 0; 181 static constexpr size_t ENTRIES_MAX_NUM = 100; // just heuristic 182 static constexpr size_t BUF_MAX_SIZE = sizeof(AclXattrHeader) + sizeof(AclXattrEntry) * ENTRIES_MAX_NUM; 183 ACL_PERM ReCalcMaskPerm(); 184 }; 185 186 } // MEDIA 187 } // OHOS 188 189 #endif // OHOS_MEDIALIBRARY_ACL_H 190