File indexing completed on 2024-05-05 17:56:55
0001 /* 0002 SPDX-FileCopyrightText: 2000 Shie Erlich <krusader@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2000 Rafi Yanai <krusader@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "krpermhandler.h" 0010 0011 // QtCore 0012 #include <QLocale> 0013 0014 #include <grp.h> 0015 #include <pwd.h> 0016 #include <sys/stat.h> 0017 0018 QSet<int> KrPermHandler::currentGroups; 0019 QHash<int, QString> KrPermHandler::uidCache; 0020 QHash<int, QString> KrPermHandler::gidCache; 0021 0022 QString KrPermHandler::mode2QString(mode_t m) 0023 { 0024 char perm[11]; 0025 for (int i = 0; i != 10; i++) 0026 perm[i] = '-'; 0027 perm[10] = 0; 0028 0029 if (S_ISLNK(m)) 0030 perm[0] = 'l'; // check for symLink 0031 if (S_ISDIR(m)) 0032 perm[0] = 'd'; // check for directory 0033 0034 // ReadUser = 0400, WriteUser = 0200, ExeUser = 0100, Suid = 04000 0035 if (m & 0400) 0036 perm[1] = 'r'; 0037 if (m & 0200) 0038 perm[2] = 'w'; 0039 if (m & 0100) 0040 perm[3] = 'x'; 0041 if (m & 04000) 0042 perm[3] = 's'; 0043 // ReadGroup = 0040, WriteGroup = 0020, ExeGroup = 0010, Gid = 02000 0044 if (m & 0040) 0045 perm[4] = 'r'; 0046 if (m & 0020) 0047 perm[5] = 'w'; 0048 if (m & 0010) 0049 perm[6] = 'x'; 0050 if (m & 02000) 0051 perm[6] = 's'; 0052 // ReadOther = 0004, WriteOther = 0002, ExeOther = 0001, Sticky = 01000 0053 if (m & 0004) 0054 perm[7] = 'r'; 0055 if (m & 0002) 0056 perm[8] = 'w'; 0057 if (m & 0001) 0058 perm[9] = 'x'; 0059 if (m & 01000) 0060 perm[9] = 't'; 0061 0062 return QString(perm); 0063 } 0064 0065 void KrPermHandler::init() 0066 { 0067 // set the umask to 022 0068 // umask( 022 ); 0069 0070 // 200 groups should be enough 0071 gid_t groupList[200]; 0072 int groupNo = getgroups(200, groupList); 0073 0074 // In kdewin32 implementation as of 4.1.2, getpwent always returns the same struct 0075 #ifndef Q_OS_WIN 0076 // fill the UID cache 0077 struct passwd *pass; 0078 while ((pass = getpwent()) != nullptr) { 0079 uidCache.insert(pass->pw_uid, pass->pw_name); 0080 } 0081 delete pass; 0082 endpwent(); 0083 0084 // fill the GID cache 0085 struct group *gr; 0086 while ((gr = getgrent()) != nullptr) { 0087 gidCache.insert(gr->gr_gid, QString(gr->gr_name)); 0088 } 0089 delete gr; 0090 endgrent(); 0091 #endif 0092 0093 // fill the groups for the current user 0094 for (int i = 0; i < groupNo; ++i) { 0095 currentGroups.insert(groupList[i]); 0096 } 0097 // just to be sure add the effective gid... 0098 currentGroups.insert(getegid()); 0099 } 0100 0101 char KrPermHandler::readable(const QString &perm, gid_t gid, uid_t uid) 0102 { 0103 return getLocalPermission(perm, gid, uid, 0); 0104 } 0105 0106 char KrPermHandler::writeable(const QString &perm, gid_t gid, uid_t uid) 0107 { 0108 return getLocalPermission(perm, gid, uid, 1); 0109 } 0110 0111 char KrPermHandler::executable(const QString &perm, gid_t gid, uid_t uid) 0112 { 0113 return getLocalPermission(perm, gid, uid, 2, true); 0114 } 0115 0116 char KrPermHandler::getLocalPermission(const QString &perm, gid_t gid, uid_t uid, int permOffset, bool ignoreRoot) 0117 { 0118 // root override 0119 if (!ignoreRoot && getuid() == 0) 0120 return ALLOWED_PERM; 0121 // first check other permissions. 0122 if (perm[7 + permOffset] != '-') 0123 return ALLOWED_PERM; 0124 // now check group permission 0125 if ((perm[4 + permOffset] != '-') && currentGroups.contains(gid)) 0126 return ALLOWED_PERM; 0127 // the last chance - user permissions 0128 if ((perm[1 + permOffset] != '-') && (uid == getuid())) 0129 return ALLOWED_PERM; 0130 // sorry ! 0131 return NO_PERM; 0132 } 0133 0134 char KrPermHandler::ftpReadable(const QString &fileOwner, const QString &userName, const QString &perm) 0135 { 0136 return getFtpPermission(fileOwner, userName, perm, 0); 0137 } 0138 0139 char KrPermHandler::ftpWriteable(const QString &fileOwner, const QString &userName, const QString &perm) 0140 { 0141 return getFtpPermission(fileOwner, userName, perm, 1); 0142 } 0143 0144 char KrPermHandler::ftpExecutable(const QString &fileOwner, const QString &userName, const QString &perm) 0145 { 0146 return getFtpPermission(fileOwner, userName, perm, 2); 0147 } 0148 0149 char KrPermHandler::getFtpPermission(const QString &fileOwner, const QString &userName, const QString &perm, int permOffset) 0150 { 0151 // first check other permissions. 0152 if (perm[7 + permOffset] != '-') 0153 return ALLOWED_PERM; 0154 // can't check group permission ! 0155 // so check the user permissions 0156 if ((perm[1 + permOffset] != '-') && (fileOwner == userName)) 0157 return ALLOWED_PERM; 0158 if ((perm[1 + permOffset] != '-') && (userName.isEmpty())) 0159 return UNKNOWN_PERM; 0160 if (perm[4 + permOffset] != '-') 0161 return UNKNOWN_PERM; 0162 return NO_PERM; 0163 } 0164 0165 QString KrPermHandler::parseSize(KIO::filesize_t val) 0166 { 0167 return QLocale().toString(val); 0168 } 0169 0170 QString KrPermHandler::gid2group(gid_t groupId) 0171 { 0172 return gidCache.value(groupId, QStringLiteral("???")); 0173 } 0174 0175 QString KrPermHandler::uid2user(uid_t userId) 0176 { 0177 return uidCache.value(userId, QStringLiteral("???")); 0178 }