11 #include "config-getgrouplist.h" 12 #include "config-accountsservice.h" 13 #include "kcoreaddons_debug.h" 26 #if defined(__BIONIC__) && __ANDROID_API__ < 26 27 static inline struct passwd * getpwent() {
return nullptr; }
28 inline void setpwent() { }
29 static inline void setgrent() { }
30 static inline struct group * getgrent() {
return nullptr; }
31 inline void endpwent() { }
32 static inline void endgrent() { }
44 Private() : uid(uid_t(-1)), gid(gid_t(-1)) {}
45 Private(
const char *name) : uid(uid_t(-1)), gid(gid_t(-1))
47 fillPasswd(name ? ::getpwnam(name) :
nullptr);
49 Private(
const passwd *p) : uid(uid_t(-1)), gid(gid_t(-1))
54 void fillPasswd(
const passwd *p)
64 while (gecosList.
size() < 4) {
71 properties[KUser::FullName] =
QVariant(gecosList[0]);
72 properties[KUser::RoomNumber] =
QVariant(gecosList[1]);
73 properties[KUser::WorkPhone] =
QVariant(gecosList[2]);
74 properties[KUser::HomePhone] =
QVariant(gecosList[3]);
75 if (uid == ::getuid() && uid == ::geteuid()) {
88 uid_t _uid = ::getuid(), _euid;
89 if (mode == UseEffectiveUID && (_euid = ::geteuid()) != _uid) {
90 d =
new Private(::getpwuid(_euid));
92 d =
new Private(qgetenv(
"LOGNAME").constData());
94 d =
new Private(qgetenv(
"USER").constData());
96 d =
new Private(::getpwuid(_uid));
103 : d(new Private(::getpwuid(_uid)))
108 : d(new Private(::getpwuid(_uid.nativeId())))
113 : d(new Private(name.toLocal8Bit().data()))
118 : d(new Private(name))
140 return isValid() && (d->uid == user.d->uid);
145 return d->uid != uid_t(-1);
176 if (!d->loginName.isEmpty()) {
177 pathToFaceIcon = QStringLiteral(ACCOUNTS_SERVICE_ICON_DIR) +
QLatin1Char(
'/') + d->loginName;
181 return pathToFaceIcon;
186 if (
QFileInfo(pathToFaceIcon).isReadable()) {
187 return pathToFaceIcon;
199 static void listGroupsForUser(
const char *name, gid_t gid, uint maxCount, Func handleNextGroup)
201 if (Q_UNLIKELY(maxCount == 0)) {
205 #if HAVE_GETGROUPLIST 208 int numGroups = gid_buffer.
size();
209 int result = getgrouplist(name, gid, gid_buffer.
data(), &numGroups);
210 if (result < 0 && uint(numGroups) < maxCount) {
212 qCDebug(KCOREADDONS_DEBUG,
"Buffer was too small: %d, need %d", gid_buffer.
size(), numGroups);
213 gid_buffer.
resize(numGroups);
214 numGroups = gid_buffer.
size();
215 getgrouplist(name, gid, gid_buffer.
data(), &numGroups);
217 for (
int i = 0; i < numGroups && found < maxCount; ++i) {
218 struct group *g = getgrgid(gid_buffer[i]);
229 struct group *g = getgrgid(gid);
233 if (found >= maxCount) {
238 static const auto groupContainsUser = [](
struct group * g,
const char *name) ->
bool {
239 for (
char **user = g->gr_mem; *user; user++)
241 if (strcmp(name, *user) == 0) {
249 while ((g = getgrent())) {
251 if (g->gr_gid != gid && groupContainsUser(g, name)) {
254 if (found >= maxCount) {
267 d->loginName.toLocal8Bit().
constData(), d->gid, maxCount,
268 [&](
const group * g) {
279 d->loginName.toLocal8Bit().
constData(), d->gid, maxCount,
280 [&](
const group * g) {
289 return d->properties.value(which);
299 for (uint i = 0; i < maxCount && (p = getpwent()); ++i) {
315 for (uint i = 0; i < maxCount && (p = getpwent()); ++i) {
327 class Q_DECL_HIDDEN KUserGroup::Private :
public QSharedData 333 Private() :
gid(gid_t(-1)) {}
334 Private(
const char *_name) :
gid(gid_t(-1))
336 fillGroup(_name ? ::getgrnam(_name) :
nullptr);
338 Private(const ::group *p) :
gid(gid_t(-1))
343 void fillGroup(const ::group *p)
354 d =
new Private(getgrgid(
KUser(mode).
groupId().nativeId()));
358 : d(new Private(getgrgid(_gid)))
363 : d(new Private(getgrgid(_gid.nativeId())))
368 : d(new Private(_name.toLocal8Bit().data()))
373 : d(new Private(_name))
395 return isValid() && (d->gid == group.d->gid);
400 return d->gid != gid_t(-1);
413 static void listGroupMembers(gid_t gid, uint maxCount, std::function<
void(passwd *)> handleNextGroupUser)
418 struct group *g = getgrgid(gid);
424 struct passwd *p =
nullptr;
425 for (
char **user = g->gr_mem; *user; user++) {
426 if ((p = getpwnam(*user))) {
427 addedUsers.
append(p->pw_uid);
428 handleNextGroupUser(p);
430 if (found >= maxCount) {
438 while ((p = getpwent()) && found < maxCount) {
439 if (p->pw_gid != gid) {
443 if (std::find(addedUsers.
cbegin(), addedUsers.
cend(), p->pw_uid) == addedUsers.
cend()) {
444 handleNextGroupUser(p);
454 listGroupMembers(d->gid, maxCount, [&](
const passwd *p) {
455 result.append(KUser(p));
463 listGroupMembers(d->gid, maxCount, [&](
const passwd *p) {
464 result.append(QString::fromLocal8Bit(p->pw_name));
476 for (uint i = 0; i < maxCount && (g = getgrent()); ++i) {
492 for (uint i = 0; i < maxCount && (g = getgrent()); ++i) {
511 struct passwd *p = ::getpwnam(name8Bit.
constData());
513 qCWarning(KCOREADDONS_DEBUG,
"Failed to lookup user %s: %s", name8Bit.
constData(), strerror(errno));
525 struct group *g = ::getgrnam(name8Bit.
constData());
527 qCWarning(KCOREADDONS_DEBUG,
"Failed to lookup group %s: %s", name8Bit.
constData(), strerror(errno));
KUserGroup(const QString &name)
Create an object from a group name.
QVarLengthArray::const_iterator cend() const const
static QList< KUser > allUsers(uint maxCount=KCOREADDONS_UINT_MAX)
bool isValid() const
Returns whether the group is valid.
static KGroupId currentGroupId()
QString name() const
The name of the group.
static KGroupId currentEffectiveGroupId()
const T * constData() const const
QVariant property(UserProperty which) const
Returns an extended property.
Represents a group on your system.
static KUserId currentUserId()
bool exists() const const
static KGroupId fromName(const QString &name)
static QStringList allUserNames(uint maxCount=KCOREADDONS_UINT_MAX)
Represents a user on your system.
bool operator==(const KUser &user) const
Two KUser objects are equal if the userId() are identical.
static KUserId fromName(const QString &name)
QString fromLocal8Bit(const char *str, int size)
void append(const T &value)
QList< KUser > users(uint maxCount=KCOREADDONS_UINT_MAX) const
QString loginName() const
The login name of the user.
bool isEmpty() const const
const char * constData() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool operator==(const KUserGroup &group) const
Two KUserGroup objects are equal if their gid()s are identical.
KUserGroup & operator=(const KUserGroup &group)
Copies a group.
QStringList userNames(uint maxCount=KCOREADDONS_UINT_MAX) const
static KUserId currentEffectiveUserId()
QByteArray toLocal8Bit() const const
QString homeDir() const
The path to the user's home directory.
A platform independent group ID.
QString shell() const
The path to the user's login shell.
bool isSuperUser() const
Checks whether the user is the super user (root).
QStringList groupNames(uint maxCount=KCOREADDONS_UINT_MAX) const
QList< KUserGroup > groups(uint maxCount=KCOREADDONS_UINT_MAX) const
static QList< KUserGroup > allGroups(uint maxCount=KCOREADDONS_UINT_MAX)
K_GID gid() const
Returns the group id of the user.
KUser & operator=(const KUser &user)
Copies a user.
bool isValid() const
Returns true if the user is valid.
static QStringList allGroupNames(uint maxCount=KCOREADDONS_UINT_MAX)
QVarLengthArray::const_iterator cbegin() const const
KUser(UIDMode mode=UseEffectiveUID)
Creates an object that contains information about the current user.
QString faceIconPath() const
The path to the user's face file.
QString decodeName(const QByteArray &localFileName)
A platform independent user ID.