File indexing completed on 2024-12-01 03:41:21
0001 /* 0002 SPDX-FileCopyrightText: 2000-2002 Till Adam <adam@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef ACLHELPERS_P_H 0008 #define ACLHELPERS_P_H 0009 0010 /************************************* 0011 * 0012 * ACL handling helpers 0013 * 0014 *************************************/ 0015 0016 #include <config-kiocore.h> 0017 0018 #include "utils_p.h" 0019 #include <KIO/UDSEntry> 0020 0021 #include <sys/types.h> 0022 0023 #if HAVE_SYS_ACL_H 0024 #include <sys/acl.h> 0025 #endif 0026 #if HAVE_ACL_LIBACL_H 0027 #include <acl/libacl.h> 0028 #endif 0029 0030 namespace KIO 0031 { 0032 /** 0033 * @internal 0034 * WARNING: DO NOT USE outside KIO Framework 0035 */ 0036 namespace ACLPortability 0037 { 0038 /// @internal 0039 __attribute__((unused)) static inline int acl_cmp(acl_t acl1, acl_t acl2) 0040 { 0041 #ifdef Q_OS_FREEBSD 0042 return ::acl_cmp_np(acl1, acl2); 0043 #else 0044 return ::acl_cmp(acl1, acl2); 0045 #endif 0046 } 0047 0048 /// @internal 0049 __attribute__((unused)) static inline acl_t acl_from_mode(const mode_t mode) 0050 { 0051 #ifdef Q_OS_FREEBSD 0052 return ::acl_from_mode_np(mode); 0053 #else 0054 return ::acl_from_mode(mode); 0055 #endif 0056 } 0057 0058 /// @internal 0059 static inline int acl_equiv_mode(acl_t acl, mode_t *mode_p) 0060 { 0061 #ifdef Q_OS_FREEBSD 0062 return ::acl_equiv_mode_np(acl, mode_p); 0063 #else 0064 return ::acl_equiv_mode(acl, mode_p); 0065 #endif 0066 } 0067 0068 /// @internal 0069 __attribute__((unused)) static inline int acl_get_perm(acl_permset_t permset_d, acl_perm_t perm) 0070 { 0071 #ifdef Q_OS_FREEBSD 0072 return ::acl_get_perm_np(permset_d, perm); 0073 #else 0074 return ::acl_get_perm(permset_d, perm); 0075 #endif 0076 } 0077 0078 /// @internal 0079 __attribute__((unused)) static inline int acl_extended_file(const char *path_p) 0080 { 0081 #ifdef Q_OS_FREEBSD 0082 return ::acl_extended_file_np(path_p); 0083 #else 0084 return ::acl_extended_file(path_p); 0085 #endif 0086 } 0087 0088 } // namespace ACLPortability 0089 } // namespace KIO 0090 0091 static QString aclToText(acl_t acl) 0092 { 0093 ssize_t size = 0; 0094 char *txt = acl_to_text(acl, &size); 0095 const QString ret = QString::fromLatin1(txt, size); 0096 acl_free(txt); 0097 return ret; 0098 } 0099 0100 /* Append an atom indicating whether the file has extended acl information 0101 * and if withACL is specified also one with the acl itself. If it's a directory 0102 * and it has a default ACL, also append that. */ 0103 __attribute__((unused)) static void appendACLAtoms(const QByteArray &path, KIO::UDSEntry &entry, mode_t type) 0104 { 0105 // first check for a noop 0106 if (KIO::ACLPortability::acl_extended_file(path.data()) == 0) { 0107 return; 0108 } 0109 0110 acl_t acl = nullptr; 0111 acl_t defaultAcl = nullptr; 0112 // do we have an acl for the file, and/or a default acl for the dir, if it is one? 0113 acl = acl_get_file(path.data(), ACL_TYPE_ACCESS); 0114 /* Sadly libacl does not provided a means of checking for extended ACL and default 0115 * ACL separately. Since a directory can have both, we need to check again. */ 0116 if (Utils::isDirMask(type)) { 0117 if (acl) { 0118 if (KIO::ACLPortability::acl_equiv_mode(acl, nullptr) == 0) { 0119 acl_free(acl); 0120 acl = nullptr; 0121 } 0122 } 0123 defaultAcl = acl_get_file(path.data(), ACL_TYPE_DEFAULT); 0124 } 0125 0126 if (acl || defaultAcl) { 0127 // qDebug() << path.constData() << "has extended ACL entries"; 0128 entry.replace(KIO::UDSEntry::UDS_EXTENDED_ACL, 1); 0129 0130 if (acl) { 0131 const QString str = aclToText(acl); 0132 entry.replace(KIO::UDSEntry::UDS_ACL_STRING, str); 0133 // qDebug() << path.constData() << "ACL:" << str; 0134 acl_free(acl); 0135 } 0136 0137 if (defaultAcl) { 0138 const QString str = aclToText(defaultAcl); 0139 entry.replace(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING, str); 0140 // qDebug() << path.constData() << "DEFAULT ACL:" << str; 0141 acl_free(defaultAcl); 0142 } 0143 } 0144 } 0145 0146 #endif // ACLHELPERS_P_H