File indexing completed on 2024-05-12 15:35:02
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 uint qHash(const KUserId &id, uint seed = 0) 0200 { 0201 return qHash(id.nativeId(), seed); 0202 } 0203 inline uint qHash(const KGroupId &id, uint 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 uint qHash(const KUserId &id, uint seed = 0); 0210 KCOREADDONS_EXPORT uint qHash(const KGroupId &id, uint 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 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 0) 0327 /** 0328 * Returns the group id of the user. 0329 * @return the id of the group or -1 if user is invalid 0330 * @deprecated since 5.0 use KUser::groupId() 0331 */ 0332 KCOREADDONS_DEPRECATED_VERSION(5, 0, "Use KUser::groupId()") 0333 K_GID gid() const 0334 { 0335 return groupId().nativeId(); 0336 } 0337 #endif 0338 0339 /** 0340 * Checks whether the user is the super user (root). 0341 * @return true if the user is root 0342 */ 0343 bool isSuperUser() const; 0344 0345 /** 0346 * The login name of the user. 0347 * @return the login name of the user or QString() if user is invalid 0348 */ 0349 QString loginName() const; 0350 0351 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 0) 0352 /** 0353 * The full name of the user. 0354 * @return the full name of the user or QString() if user is invalid 0355 * @deprecated Since 5.0, use property(KUser::FullName) instead 0356 */ 0357 KCOREADDONS_DEPRECATED_VERSION(5, 0, "Use KUser::property(KUser::FullName).toString()") 0358 QString fullName() const 0359 { 0360 return property(FullName).toString(); 0361 } 0362 /** 0363 * Returns the user id of the user. 0364 * @return the id of the user or -1 (UNIX)/ null(Windows) if user is invalid 0365 * @deprecated since 5.0 use KUser::userId() 0366 */ 0367 KCOREADDONS_DEPRECATED_VERSION(5, 0, "Use KUser::userId().nativeId()") 0368 K_UID uid() const 0369 { 0370 return userId().nativeId(); 0371 } 0372 #endif 0373 0374 /** 0375 * The path to the user's home directory. 0376 * @return the home directory of the user or QString() if the 0377 * user is invalid 0378 */ 0379 QString homeDir() const; 0380 0381 /** 0382 * The path to the user's face file. 0383 * @return the path to the user's face file or QString() if no 0384 * face has been set 0385 */ 0386 QString faceIconPath() const; 0387 0388 /** 0389 * The path to the user's login shell. 0390 * @return the login shell of the user or QString() if the 0391 * user is invalid 0392 */ 0393 QString shell() const; 0394 0395 /** 0396 * @param maxCount the maximum number of groups to return 0397 * @return all groups of the user 0398 */ 0399 QList<KUserGroup> groups(uint maxCount = KCOREADDONS_UINT_MAX) const; 0400 0401 /** 0402 * @param maxCount the maximum number of groups to return 0403 * @return all group names of the user 0404 */ 0405 QStringList groupNames(uint maxCount = KCOREADDONS_UINT_MAX) const; 0406 0407 enum UserProperty { 0408 FullName, 0409 RoomNumber, 0410 WorkPhone, 0411 HomePhone, 0412 }; 0413 0414 /** 0415 * Returns an extended property. 0416 * 0417 * Under Windows, @p RoomNumber, @p WorkPhone and @p HomePhone are unsupported. 0418 * 0419 * @return a QVariant with the value of the property or an invalid QVariant, 0420 * if the property is not set 0421 */ 0422 QVariant property(UserProperty which) const; 0423 0424 /** 0425 * Destructor. 0426 */ 0427 ~KUser(); 0428 0429 /** 0430 * @param maxCount the maximum number of users to return 0431 * @return all users of the system. 0432 */ 0433 static QList<KUser> allUsers(uint maxCount = KCOREADDONS_UINT_MAX); 0434 0435 /** 0436 * @param maxCount the maximum number of users to return 0437 * @return all user names of the system. 0438 */ 0439 static QStringList allUserNames(uint maxCount = KCOREADDONS_UINT_MAX); 0440 0441 private: 0442 QExplicitlySharedDataPointer<class KUserPrivate> d; 0443 }; 0444 0445 /** 0446 * \class KUserGroup kuser.h <KUserGroup> 0447 * 0448 * @short Represents a group on your system 0449 * 0450 * This class represents a group on your system. You can either get 0451 * information about the group of the current user, of fetch information about 0452 * a group on the system. Instances of this class will be explicitly shared, 0453 * so copying objects is very cheap and you can safely pass objects by value. 0454 * 0455 * @author Jan Schaefer <j_schaef@informatik.uni-kl.de> 0456 */ 0457 class KCOREADDONS_EXPORT KUserGroup 0458 { 0459 public: 0460 /** 0461 * Create an object from a group name. 0462 * If the group does not exist, isValid() will return false. 0463 * @param name the name of the group 0464 */ 0465 explicit KUserGroup(const QString &name); 0466 0467 /** 0468 * Create an object from a group name. 0469 * If the group does not exist, isValid() will return false. 0470 * @param name the name of the group 0471 */ 0472 explicit KUserGroup(const char *name); 0473 0474 /** 0475 * Creates an object for the group with the given group id. 0476 * If the KGroupId object is invalid this one will be, too. 0477 * @param gid the group id 0478 */ 0479 explicit KUserGroup(KGroupId gid); 0480 0481 /** 0482 * Create an object from the group of the current user. 0483 * @param mode if #KUser::UseEffectiveUID is passed the effective user 0484 * will be used. If #KUser::UseRealUserID is passed the real user 0485 * will be used. 0486 * The real UID will be different than the effective UID in setuid 0487 * programs; in such a case use the effective UID for checking 0488 * permissions, and the real UID for displaying information about 0489 * the group associated with the user. 0490 */ 0491 explicit KUserGroup(KUser::UIDMode mode = KUser::UseEffectiveUID); 0492 0493 /** 0494 * Create an object from a group id. 0495 * If the group does not exist, isValid() will return false. 0496 * @param gid the group id 0497 */ 0498 explicit KUserGroup(K_GID gid); 0499 0500 #ifndef Q_OS_WIN 0501 /** 0502 * Creates an object from a group structure. 0503 * If the pointer is null, isValid() will return false. 0504 * @param g the group structure to create the group from. 0505 */ 0506 explicit KUserGroup(const group *g); 0507 #endif 0508 0509 /** 0510 * Creates a new KUserGroup instance from another KUserGroup object 0511 * @param group the KUserGroup to copy 0512 */ 0513 KUserGroup(const KUserGroup &group); 0514 0515 /** 0516 * Copies a group 0517 * @param group the group that should be copied 0518 * @return this group 0519 */ 0520 KUserGroup &operator=(const KUserGroup &group); 0521 0522 /** 0523 * Two KUserGroup objects are equal if their gid()s are identical. 0524 * Invalid groups never compare equal. 0525 * @return true if the groups are identical 0526 */ 0527 bool operator==(const KUserGroup &group) const; 0528 0529 /** 0530 * Two KUserGroup objects are not equal if their gid()s are not identical. 0531 * Invalid groups always compare unequal. 0532 * @return true if the groups are not identical 0533 */ 0534 bool operator!=(const KUserGroup &group) const; 0535 0536 /** 0537 * Returns whether the group is valid. 0538 * A KUserGroup object can be invalid if it is 0539 * created with a non-existing gid or name. 0540 * @return true if the group is valid 0541 */ 0542 bool isValid() const; 0543 0544 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 0) 0545 /** 0546 * Returns the group id of the group. 0547 * @return the group id of the group or -1 if the group is invalid 0548 * @deprecated since 5.0 use KUserGroup::groupId() 0549 */ 0550 KCOREADDONS_DEPRECATED_VERSION(5, 0, "Use KUserGroup::groupId().nativeId()") 0551 K_GID gid() const 0552 { 0553 return groupId().nativeId(); 0554 } 0555 #endif 0556 0557 /** @return the native group id of the user. */ 0558 KGroupId groupId() const; 0559 0560 /** 0561 * The name of the group. 0562 * @return the name of the group 0563 */ 0564 QString name() const; 0565 0566 /** 0567 * @param maxCount the maximum number of users to return 0568 * @return a list of all users of the group 0569 */ 0570 QList<KUser> users(uint maxCount = KCOREADDONS_UINT_MAX) const; 0571 0572 /** 0573 * @param maxCount the maximum number of groups to return 0574 * @return a list of all user login names of the group 0575 */ 0576 QStringList userNames(uint maxCount = KCOREADDONS_UINT_MAX) const; 0577 0578 /** 0579 * Destructor. 0580 */ 0581 ~KUserGroup(); 0582 0583 /** 0584 * @param maxCount the maximum number of groups to return 0585 * @return a list of all groups on this system 0586 */ 0587 static QList<KUserGroup> allGroups(uint maxCount = KCOREADDONS_UINT_MAX); 0588 0589 /** 0590 * @param maxCount the maximum number of groups to return 0591 * @return a list of all group names on this system 0592 */ 0593 static QStringList allGroupNames(uint maxCount = KCOREADDONS_UINT_MAX); 0594 0595 private: 0596 QSharedDataPointer<class KUserGroupPrivate> d; 0597 }; 0598 0599 #if !defined(Q_OS_WIN) 0600 // inline UNIX implementation of KUserOrGroupId 0601 template<typename T> 0602 inline bool KUserOrGroupId<T>::isValid() const 0603 { 0604 return id != NativeType(-1); 0605 } 0606 template<typename T> 0607 inline bool KUserOrGroupId<T>::operator==(const KUserOrGroupId<T> &other) const 0608 { 0609 return id == other.id; 0610 } 0611 template<typename T> 0612 inline bool KUserOrGroupId<T>::operator!=(const KUserOrGroupId<T> &other) const 0613 { 0614 return id != other.id; 0615 } 0616 template<typename T> 0617 inline typename KUserOrGroupId<T>::NativeType KUserOrGroupId<T>::nativeId() const 0618 { 0619 return id; 0620 } 0621 template<typename T> 0622 inline QString KUserOrGroupId<T>::toString() const 0623 { 0624 return QString::number(id); 0625 } 0626 template<typename T> 0627 inline KUserOrGroupId<T>::KUserOrGroupId() 0628 : id(-1) 0629 { 0630 } 0631 template<typename T> 0632 inline KUserOrGroupId<T>::KUserOrGroupId(KUserOrGroupId<T>::NativeType nativeId) 0633 : id(nativeId) 0634 { 0635 } 0636 template<typename T> 0637 inline KUserOrGroupId<T>::KUserOrGroupId(const KUserOrGroupId<T> &other) 0638 : id(other.id) 0639 { 0640 } 0641 template<typename T> 0642 inline KUserOrGroupId<T> &KUserOrGroupId<T>::operator=(const KUserOrGroupId<T> &other) 0643 { 0644 id = other.id; 0645 return *this; 0646 } 0647 template<typename T> 0648 inline KUserOrGroupId<T>::~KUserOrGroupId() 0649 { 0650 } 0651 #endif // !defined(Q_OS_WIN) 0652 0653 inline bool KUser::operator!=(const KUser &other) const 0654 { 0655 return !operator==(other); 0656 } 0657 0658 inline bool KUserGroup::operator!=(const KUserGroup &other) const 0659 { 0660 return !operator==(other); 0661 } 0662 0663 #endif