File indexing completed on 2024-04-28 03:53:51
0001 /* 0002 KUser - represent a user/account 0003 0004 SPDX-FileCopyrightText: 2002-2003 Tim Jansen <tim@tjansen.de> 0005 SPDX-FileCopyrightText: 2003 Oswald Buddenhagen <ossi@kde.org> 0006 SPDX-FileCopyrightText: 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> 0007 SPDX-FileCopyrightText: 2014 Alex Richardson <arichardson.kde@gmail.com> 0008 0009 SPDX-License-Identifier: LGPL-2.0-or-later 0010 */ 0011 #ifndef KUSER_H 0012 #define KUSER_H 0013 0014 #include <kcoreaddons_export.h> 0015 0016 #include <QSharedDataPointer> 0017 #include <QStringList> 0018 #include <QVariant> 0019 #include <qcontainerfwd.h> 0020 0021 class KUserGroup; 0022 class QString; 0023 0024 #ifdef Q_OS_WIN 0025 typedef void *K_UID; 0026 typedef void *K_GID; 0027 struct WindowsSIDWrapper; 0028 #else 0029 #include <sys/types.h> 0030 typedef uid_t K_UID; 0031 typedef gid_t K_GID; 0032 struct passwd; 0033 struct group; 0034 #endif 0035 0036 // The following is to avoid compile errors using msvc, and it is done 0037 // using a common #define to avoid helpful people accidentally cleaning this 0038 // not quite pretty thing and breaking it for people on windows. 0039 // See https://git.reviewboard.kde.org/r/127598/ for details 0040 #define KCOREADDONS_UINT_MAX (std::numeric_limits<uint>::max)() 0041 0042 /** A platform independent user or group ID. 0043 * 0044 * 0045 * This struct is required since Windows does not have an integer uid_t/gid_t type 0046 * but instead uses an opaque binary blob (SID) which must free allocated memory. 0047 * On UNIX this is simply a uid_t/gid_t and all operations are inline, so there is 0048 * no runtime overhead over using the uid_t/gid_t directly. On Windows this is an implicitly 0049 * shared class that frees the underlying SID once no more references remain. 0050 * 0051 * Unlike KUser/KUserGroup this does not query additional information, it is simply 0052 * an abstraction over the native user/group ID type. If more information is necessary, a 0053 * KUser or KUserGroup instance can be constructed from this ID 0054 * 0055 * @internal 0056 * @author Alex Richardson <arichardson.kde@gmail.com> 0057 */ 0058 template<typename T> 0059 struct KCOREADDONS_EXPORT KUserOrGroupId { 0060 typedef T NativeType; 0061 0062 protected: 0063 /** Creates an invalid KUserOrGroupId */ 0064 KUserOrGroupId(); 0065 /** Creates a KUserOrGroupId from a native user/group ID. On windows this will not take 0066 * ownership over the passed SID, a copy will be created instead. 0067 */ 0068 explicit KUserOrGroupId(NativeType nativeId); 0069 /** Copy constructor. This is very fast, objects can be passed by value */ 0070 KUserOrGroupId(const KUserOrGroupId<T> &other); 0071 KUserOrGroupId &operator=(const KUserOrGroupId<T> &other); 0072 ~KUserOrGroupId(); 0073 0074 public: 0075 /** @return true if this object references a valid user/group ID. 0076 * @note If this returns true it doesn't necessarily mean that the referenced user/group exists, 0077 * it only checks whether this value could be a valid user/group ID. 0078 */ 0079 bool isValid() const; 0080 /** 0081 * @return A user/group ID that can be used in operating system specific functions 0082 * @note On Windows the returned pointer will be freed once the last KUserOrGroupId referencing 0083 * this user/group ID is deleted. Make sure that the KUserOrGroupId object remains valid as 0084 * long as the native pointer is needed. 0085 */ 0086 NativeType nativeId() const; 0087 /** @return A string representation of this user ID, not the name of the user 0088 * On UNIX this is a simple integer, e.g. "0" for root. On Windows this is a string 0089 * like e.g. "S-1-5-32-544" for the Administrators group 0090 */ 0091 QString toString() const; 0092 /** @return whether this KUserOrGroupId is equal to @p other */ 0093 bool operator==(const KUserOrGroupId &other) const; 0094 /** @return whether this KUserOrGroupId is not equal to @p other */ 0095 bool operator!=(const KUserOrGroupId &other) const; 0096 0097 private: 0098 #ifdef Q_OS_WIN 0099 QExplicitlySharedDataPointer<WindowsSIDWrapper> data; 0100 #else 0101 NativeType id; 0102 #endif 0103 }; 0104 0105 #ifdef Q_OS_WIN 0106 template<> 0107 KUserOrGroupId<void *>::KUserOrGroupId(); 0108 template<> 0109 KUserOrGroupId<void *>::~KUserOrGroupId(); 0110 template<> 0111 KUserOrGroupId<void *>::KUserOrGroupId(KUserOrGroupId::NativeType nativeId); 0112 template<> 0113 KUserOrGroupId<void *>::KUserOrGroupId(const KUserOrGroupId &other); 0114 template<> 0115 KUserOrGroupId<void *> &KUserOrGroupId<void *>::operator=(const KUserOrGroupId &other); 0116 template<> 0117 bool KUserOrGroupId<void *>::isValid() const; 0118 template<> 0119 KUserOrGroupId<void *>::NativeType KUserOrGroupId<void *>::nativeId() const; 0120 template<> 0121 QString KUserOrGroupId<void *>::toString() const; 0122 template<> 0123 bool KUserOrGroupId<void *>::operator==(const KUserOrGroupId &other) const; 0124 template<> 0125 bool KUserOrGroupId<void *>::operator!=(const KUserOrGroupId &other) const; 0126 #endif 0127 0128 /** A platform independent user ID. 0129 * @see KUserOrGroupId 0130 * @since 5.0 0131 * @author Alex Richardson <arichardson.kde@gmail.com> 0132 */ 0133 struct KCOREADDONS_EXPORT KUserId : public KUserOrGroupId<K_UID> { 0134 /** Creates an invalid KUserId */ 0135 KUserId() 0136 { 0137 } 0138 /** Creates an KUserId from the native user ID type */ 0139 explicit KUserId(K_UID uid) 0140 : KUserOrGroupId(uid) 0141 { 0142 } 0143 KUserId(const KUserId &other) 0144 : KUserOrGroupId(other) 0145 { 0146 } 0147 ~KUserId() 0148 { 0149 } 0150 /** @return a KUserId for the user with name @p name, or an invalid KUserId if no 0151 * user with this name was found on the system 0152 */ 0153 static KUserId fromName(const QString &name); 0154 /** @return a KUserId for the current user. This is like ::getuid() on UNIX. */ 0155 static KUserId currentUserId(); 0156 /** @return a KUserId for the current effective user. This is like ::geteuid() on UNIX. 0157 * @note Windows does not have setuid binaries, so on Windows this will always be the same 0158 * as KUserId::currentUserId() 0159 */ 0160 static KUserId currentEffectiveUserId(); 0161 }; 0162 0163 /** A platform independent group ID. 0164 * @see KUserOrGroupId 0165 * @since 5.0 0166 * @author Alex Richardson <arichardson.kde@gmail.com> 0167 */ 0168 struct KCOREADDONS_EXPORT KGroupId : public KUserOrGroupId<K_GID> { 0169 /** Creates an invalid KGroupId */ 0170 KGroupId() 0171 { 0172 } 0173 /** Creates an KGroupId from the native group ID type */ 0174 explicit KGroupId(K_GID gid) 0175 : KUserOrGroupId(gid) 0176 { 0177 } 0178 KGroupId(const KGroupId &other) 0179 : KUserOrGroupId(other) 0180 { 0181 } 0182 ~KGroupId() 0183 { 0184 } 0185 /** @return A KGroupId for the user with name @p name, or an invalid KGroupId if no 0186 * user with this name was found on the system 0187 */ 0188 static KGroupId fromName(const QString &name); 0189 /** @return a KGroupId for the current user. This is like ::getgid() on UNIX. */ 0190 static KGroupId currentGroupId(); 0191 /** @return a KGroupId for the current effective user. This is like ::getegid() on UNIX. 0192 * @note Windows does not have setuid binaries, so on Windows this will always be the same 0193 * as KGroupId::currentGroupId() 0194 */ 0195 static KGroupId currentEffectiveGroupId(); 0196 }; 0197 0198 #ifndef Q_OS_WIN 0199 inline size_t qHash(const KUserId &id, size_t seed = 0) 0200 { 0201 return qHash(id.nativeId(), seed); 0202 } 0203 inline size_t qHash(const KGroupId &id, size_t seed = 0) 0204 { 0205 return qHash(id.nativeId(), seed); 0206 } 0207 #else 0208 // can't be inline on windows, because we would need to include windows.h (which can break code) 0209 KCOREADDONS_EXPORT size_t qHash(const KUserId &id, size_t seed = 0); 0210 KCOREADDONS_EXPORT size_t qHash(const KGroupId &id, size_t seed = 0); 0211 #endif 0212 0213 /** 0214 * \class KUser kuser.h <KUser> 0215 * 0216 * @short Represents a user on your system 0217 * 0218 * This class represents a user on your system. You can either get 0219 * information about the current user, or fetch information about 0220 * a user on the system. Instances of this class will be explicitly shared, 0221 * so copying objects is very cheap and you can safely pass objects by value. 0222 * 0223 * @author Tim Jansen <tim@tjansen.de> 0224 */ 0225 class KCOREADDONS_EXPORT KUser 0226 { 0227 public: 0228 enum UIDMode { 0229 UseEffectiveUID, ///< Use the effective user id. 0230 UseRealUserID, ///< Use the real user id. 0231 }; 0232 0233 /** 0234 * Creates an object that contains information about the current user. 0235 * (as returned by getuid(2) or geteuid(2), taking $LOGNAME/$USER into 0236 * account). 0237 * @param mode if #UseEffectiveUID is passed the effective 0238 * user is returned. 0239 * If #UseRealUserID is passed the real user will be 0240 * returned. 0241 * The real UID will be different than the effective UID in setuid 0242 * programs; in 0243 * such a case use the effective UID for checking permissions, and 0244 * the real UID for displaying information about the user. 0245 */ 0246 explicit KUser(UIDMode mode = UseEffectiveUID); 0247 0248 /** 0249 * Creates an object for the user with the given user id. 0250 * If the user does not exist isValid() will return false. 0251 * @param uid the user id 0252 */ 0253 explicit KUser(K_UID uid); 0254 0255 /** 0256 * Creates an object for the user with the given user id. 0257 * If the KUserId object is invalid this one will be, too. 0258 * @param uid the user id 0259 */ 0260 explicit KUser(KUserId uid); 0261 0262 /** 0263 * Creates an object that contains information about the user with the given 0264 * name. If the user does not exist isValid() will return false. 0265 * 0266 * @param name the name of the user 0267 */ 0268 explicit KUser(const QString &name); 0269 0270 /** 0271 * Creates an object that contains information about the user with the given 0272 * name. If the user does not exist isValid() will return false. 0273 * 0274 * @param name the name of the user 0275 */ 0276 explicit KUser(const char *name); 0277 0278 #ifndef Q_OS_WIN 0279 /** 0280 * Creates an object from a passwd structure. 0281 * If the pointer is null isValid() will return false. 0282 * 0283 * @param p the passwd structure to create the user from 0284 */ 0285 explicit KUser(const passwd *p); 0286 #endif 0287 0288 /** 0289 * Creates an object from another KUser object 0290 * @param user the user to create the new object from 0291 */ 0292 KUser(const KUser &user); 0293 0294 /** 0295 * Copies a user 0296 * @param user the user to copy 0297 * @return this object 0298 */ 0299 KUser &operator=(const KUser &user); 0300 0301 /** 0302 * Two KUser objects are equal if the userId() are identical. 0303 * Invalid users never compare equal. 0304 */ 0305 bool operator==(const KUser &user) const; 0306 0307 /** 0308 * Two KUser objects are not equal if userId() are not identical. 0309 * Invalid users always compare unequal. 0310 */ 0311 bool operator!=(const KUser &user) const; 0312 0313 /** 0314 * Returns true if the user is valid. A KUser object can be invalid if 0315 * you created it with an non-existing uid or name. 0316 * @return true if the user is valid 0317 */ 0318 bool isValid() const; 0319 0320 /** @return the native user id of the user. */ 0321 KUserId userId() const; 0322 0323 /** @return the native user id of the user. */ 0324 KGroupId groupId() const; 0325 0326 /** 0327 * Checks whether the user is the super user (root). 0328 * @return true if the user is root 0329 */ 0330 bool isSuperUser() const; 0331 0332 /** 0333 * The login name of the user. 0334 * @return the login name of the user or QString() if user is invalid 0335 */ 0336 QString loginName() const; 0337 0338 /** 0339 * The path to the user's home directory. 0340 * @return the home directory of the user or QString() if the 0341 * user is invalid 0342 */ 0343 QString homeDir() const; 0344 0345 /** 0346 * The path to the user's face file. 0347 * @return the path to the user's face file or QString() if no 0348 * face has been set 0349 */ 0350 QString faceIconPath() const; 0351 0352 /** 0353 * The path to the user's login shell. 0354 * @return the login shell of the user or QString() if the 0355 * user is invalid 0356 */ 0357 QString shell() const; 0358 0359 /** 0360 * @param maxCount the maximum number of groups to return 0361 * @return all groups of the user 0362 */ 0363 QList<KUserGroup> groups(uint maxCount = KCOREADDONS_UINT_MAX) const; 0364 0365 /** 0366 * @param maxCount the maximum number of groups to return 0367 * @return all group names of the user 0368 */ 0369 QStringList groupNames(uint maxCount = KCOREADDONS_UINT_MAX) const; 0370 0371 enum UserProperty { 0372 FullName, 0373 RoomNumber, 0374 WorkPhone, 0375 HomePhone, 0376 }; 0377 0378 /** 0379 * Returns an extended property. 0380 * 0381 * Under Windows, @p RoomNumber, @p WorkPhone and @p HomePhone are unsupported. 0382 * 0383 * @return a QVariant with the value of the property or an invalid QVariant, 0384 * if the property is not set 0385 */ 0386 QVariant property(UserProperty which) const; 0387 0388 /** 0389 * Destructor. 0390 */ 0391 ~KUser(); 0392 0393 /** 0394 * @param maxCount the maximum number of users to return 0395 * @return all users of the system. 0396 */ 0397 static QList<KUser> allUsers(uint maxCount = KCOREADDONS_UINT_MAX); 0398 0399 /** 0400 * @param maxCount the maximum number of users to return 0401 * @return all user names of the system. 0402 */ 0403 static QStringList allUserNames(uint maxCount = KCOREADDONS_UINT_MAX); 0404 0405 private: 0406 QExplicitlySharedDataPointer<class KUserPrivate> d; 0407 }; 0408 0409 Q_DECLARE_TYPEINFO(KUser, Q_RELOCATABLE_TYPE); 0410 0411 /** 0412 * \class KUserGroup kuser.h <KUserGroup> 0413 * 0414 * @short Represents a group on your system 0415 * 0416 * This class represents a group on your system. You can either get 0417 * information about the group of the current user, of fetch information about 0418 * a group on the system. Instances of this class will be explicitly shared, 0419 * so copying objects is very cheap and you can safely pass objects by value. 0420 * 0421 * @author Jan Schaefer <j_schaef@informatik.uni-kl.de> 0422 */ 0423 class KCOREADDONS_EXPORT KUserGroup 0424 { 0425 public: 0426 /** 0427 * Create an object from a group name. 0428 * If the group does not exist, isValid() will return false. 0429 * @param name the name of the group 0430 */ 0431 explicit KUserGroup(const QString &name); 0432 0433 /** 0434 * Create an object from a group name. 0435 * If the group does not exist, isValid() will return false. 0436 * @param name the name of the group 0437 */ 0438 explicit KUserGroup(const char *name); 0439 0440 /** 0441 * Creates an object for the group with the given group id. 0442 * If the KGroupId object is invalid this one will be, too. 0443 * @param gid the group id 0444 */ 0445 explicit KUserGroup(KGroupId gid); 0446 0447 /** 0448 * Create an object from the group of the current user. 0449 * @param mode if #KUser::UseEffectiveUID is passed the effective user 0450 * will be used. If #KUser::UseRealUserID is passed the real user 0451 * will be used. 0452 * The real UID will be different than the effective UID in setuid 0453 * programs; in such a case use the effective UID for checking 0454 * permissions, and the real UID for displaying information about 0455 * the group associated with the user. 0456 */ 0457 explicit KUserGroup(KUser::UIDMode mode = KUser::UseEffectiveUID); 0458 0459 /** 0460 * Create an object from a group id. 0461 * If the group does not exist, isValid() will return false. 0462 * @param gid the group id 0463 */ 0464 explicit KUserGroup(K_GID gid); 0465 0466 #ifndef Q_OS_WIN 0467 /** 0468 * Creates an object from a group structure. 0469 * If the pointer is null, isValid() will return false. 0470 * @param g the group structure to create the group from. 0471 */ 0472 explicit KUserGroup(const group *g); 0473 #endif 0474 0475 /** 0476 * Creates a new KUserGroup instance from another KUserGroup object 0477 * @param group the KUserGroup to copy 0478 */ 0479 KUserGroup(const KUserGroup &group); 0480 0481 /** 0482 * Copies a group 0483 * @param group the group that should be copied 0484 * @return this group 0485 */ 0486 KUserGroup &operator=(const KUserGroup &group); 0487 0488 /** 0489 * Two KUserGroup objects are equal if their gid()s are identical. 0490 * Invalid groups never compare equal. 0491 * @return true if the groups are identical 0492 */ 0493 bool operator==(const KUserGroup &group) const; 0494 0495 /** 0496 * Two KUserGroup objects are not equal if their gid()s are not identical. 0497 * Invalid groups always compare unequal. 0498 * @return true if the groups are not identical 0499 */ 0500 bool operator!=(const KUserGroup &group) const; 0501 0502 /** 0503 * Returns whether the group is valid. 0504 * A KUserGroup object can be invalid if it is 0505 * created with a non-existing gid or name. 0506 * @return true if the group is valid 0507 */ 0508 bool isValid() const; 0509 0510 /** @return the native group id of the user. */ 0511 KGroupId groupId() const; 0512 0513 /** 0514 * The name of the group. 0515 * @return the name of the group 0516 */ 0517 QString name() const; 0518 0519 /** 0520 * @param maxCount the maximum number of users to return 0521 * @return a list of all users of the group 0522 */ 0523 QList<KUser> users(uint maxCount = KCOREADDONS_UINT_MAX) const; 0524 0525 /** 0526 * @param maxCount the maximum number of groups to return 0527 * @return a list of all user login names of the group 0528 */ 0529 QStringList userNames(uint maxCount = KCOREADDONS_UINT_MAX) const; 0530 0531 /** 0532 * Destructor. 0533 */ 0534 ~KUserGroup(); 0535 0536 /** 0537 * @param maxCount the maximum number of groups to return 0538 * @return a list of all groups on this system 0539 */ 0540 static QList<KUserGroup> allGroups(uint maxCount = KCOREADDONS_UINT_MAX); 0541 0542 /** 0543 * @param maxCount the maximum number of groups to return 0544 * @return a list of all group names on this system 0545 */ 0546 static QStringList allGroupNames(uint maxCount = KCOREADDONS_UINT_MAX); 0547 0548 private: 0549 QSharedDataPointer<class KUserGroupPrivate> d; 0550 }; 0551 0552 Q_DECLARE_TYPEINFO(KUserGroup, Q_RELOCATABLE_TYPE); 0553 0554 #if !defined(Q_OS_WIN) 0555 // inline UNIX implementation of KUserOrGroupId 0556 template<typename T> 0557 inline bool KUserOrGroupId<T>::isValid() const 0558 { 0559 return id != NativeType(-1); 0560 } 0561 template<typename T> 0562 inline bool KUserOrGroupId<T>::operator==(const KUserOrGroupId<T> &other) const 0563 { 0564 return id == other.id; 0565 } 0566 template<typename T> 0567 inline bool KUserOrGroupId<T>::operator!=(const KUserOrGroupId<T> &other) const 0568 { 0569 return id != other.id; 0570 } 0571 template<typename T> 0572 inline typename KUserOrGroupId<T>::NativeType KUserOrGroupId<T>::nativeId() const 0573 { 0574 return id; 0575 } 0576 template<typename T> 0577 inline QString KUserOrGroupId<T>::toString() const 0578 { 0579 return QString::number(id); 0580 } 0581 template<typename T> 0582 inline KUserOrGroupId<T>::KUserOrGroupId() 0583 : id(-1) 0584 { 0585 } 0586 template<typename T> 0587 inline KUserOrGroupId<T>::KUserOrGroupId(KUserOrGroupId<T>::NativeType nativeId) 0588 : id(nativeId) 0589 { 0590 } 0591 template<typename T> 0592 inline KUserOrGroupId<T>::KUserOrGroupId(const KUserOrGroupId<T> &other) 0593 : id(other.id) 0594 { 0595 } 0596 template<typename T> 0597 inline KUserOrGroupId<T> &KUserOrGroupId<T>::operator=(const KUserOrGroupId<T> &other) 0598 { 0599 id = other.id; 0600 return *this; 0601 } 0602 template<typename T> 0603 inline KUserOrGroupId<T>::~KUserOrGroupId() 0604 { 0605 } 0606 #endif // !defined(Q_OS_WIN) 0607 0608 inline bool KUser::operator!=(const KUser &other) const 0609 { 0610 return !operator==(other); 0611 } 0612 0613 inline bool KUserGroup::operator!=(const KUserGroup &other) const 0614 { 0615 return !operator==(other); 0616 } 0617 0618 #endif