From 704ef230d5f26ebfb2d61d3753f289815b2d4eff Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Mon, 10 Oct 2022 20:51:06 +0300 Subject: [PATCH] generic: make use of KUser and KUserGroup eventually KUser and KUserGroup will use getpwnam_r(), getgrnam_r(), etc. for thread safety Signed-off-by: Ivailo Monev --- ConfigureChecks.cmake | 1 - config.h.cmake | 1 - kio/kfile/kacleditwidget.cpp | 21 ++---------- kio/kfile/kpropertiesdialog.cpp | 57 +++++++++------------------------ kio/kio/chmodjob.cpp | 15 ++++----- kio/kio/job.cpp | 24 ++++++-------- kio/kio/kacl.cpp | 46 ++++++++++---------------- kio/kio/kfileitem.cpp | 29 +++++++---------- kio/kio/kurlcompletion.cpp | 13 ++++---- kioslave/file/file.cpp | 21 ++++++------ kioslave/file/file_unix.cpp | 15 ++++----- kpty/kpty.cpp | 1 - 12 files changed, 86 insertions(+), 158 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index beee0278..9fd50188 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -41,7 +41,6 @@ kde4_bool_to_01(X11_XSync_FOUND HAVE_XSYNC) # kidletim # specific order. Refer to the man page for each symbol for which a # check is to be added to get the proper set of headers. check_symbol_exists(strtoll "stdlib.h" HAVE_STRTOLL) # kioslave -check_symbol_exists(getgrouplist "unistd.h;grp.h" HAVE_GETGROUPLIST) # kio check_symbol_exists(strmode "string.h" HAVE_STRMODE) # karchive check_function_exists(backtrace HAVE_BACKTRACE) # kdecore, kio diff --git a/config.h.cmake b/config.h.cmake index 6e6ccb5a..769224cb 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -21,7 +21,6 @@ #cmakedefine HAVE_SENDFILE 1 #cmakedefine HAVE_SETMNTENT 1 #cmakedefine HAVE_STRTOLL 1 -#cmakedefine HAVE_GETGROUPLIST 1 #cmakedefine HAVE_STRMODE 1 /* Define to 1 if you have the Xtest extension */ diff --git a/kio/kfile/kacleditwidget.cpp b/kio/kfile/kacleditwidget.cpp index b02af3a1..08b37137 100644 --- a/kio/kfile/kacleditwidget.cpp +++ b/kio/kfile/kacleditwidget.cpp @@ -43,15 +43,11 @@ #include #include #include +#include #ifdef HAVE_ACL_LIBACL_H # include #endif -extern "C" { -#include -#include -} -#include static struct { const char* label; @@ -617,19 +613,8 @@ KACLListView::KACLListView( QWidget* parent ) // fill the lists of all legal users and groups - struct passwd *user = 0; - setpwent(); - while ( ( user = getpwent() ) != 0 ) { - m_allUsers << QString::fromLatin1( user->pw_name ); - } - endpwent(); - - struct group *gr = 0; - setgrent(); - while ( ( gr = getgrent() ) != 0 ) { - m_allGroups << QString::fromLatin1( gr->gr_name ); - } - endgrent(); + m_allUsers = KUser::allUserNames(); + m_allGroups << KUserGroup::allGroupNames(); m_allUsers.sort(); m_allGroups.sort(); diff --git a/kio/kfile/kpropertiesdialog.cpp b/kio/kfile/kpropertiesdialog.cpp index dcacfffb..a82f752e 100644 --- a/kio/kfile/kpropertiesdialog.cpp +++ b/kio/kfile/kpropertiesdialog.cpp @@ -48,8 +48,6 @@ #include #include extern "C" { -#include -#include #include #include #include @@ -61,10 +59,10 @@ extern "C" { #include #include +#include #include #include #include -#include #include #include #include @@ -72,7 +70,6 @@ extern "C" { #include #include #include -#include #ifdef HAVE_POSIX_ACL #include @@ -119,6 +116,7 @@ extern "C" { #include #include #include +#include #include "ui_kpropertiesdesktopbase.h" #include "ui_kpropertiesdesktopadvbase.h" @@ -1542,7 +1540,7 @@ KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_pr QString fname = properties->kurl().fileName(); bool isLocal = properties->kurl().isLocalFile(); bool isTrash = ( properties->kurl().protocol().toLower() == "trash" ); - bool IamRoot = (geteuid() == 0); + bool IamRoot = (::geteuid() == 0); const KFileItem item = properties->item(); bool isLink = item.isLink(); @@ -1604,12 +1602,12 @@ KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_pr bool isMyFile = false; if (isLocal && !d->strOwner.isEmpty()) { // local files, and all owned by the same person - struct passwd *myself = getpwuid( geteuid() ); - if ( myself != 0L ) + const KUser kuser(KUser::UseEffectiveUID); + if ( kuser.isValid() ) { - isMyFile = (d->strOwner == QString::fromLocal8Bit(myself->pw_name)); + isMyFile = (d->strOwner == kuser.loginName()); } else - kWarning() << "I don't exist ?! geteuid=" << geteuid(); + kWarning() << "I don't exist ?! geteuid=" << ::geteuid(); } else { //We don't know, for remote files, if they are ours or not. //So we let the user change permissions, and @@ -1718,7 +1716,6 @@ KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_pr * OTOH, it is nice to offer this functionality for the standard user. */ int i, maxEntries = 1000; - struct passwd *user; /* File owner: For root, offer a KLineEdit with autocompletion. * For a user, who can never chown() a file, offer a QLabel. @@ -1728,10 +1725,9 @@ KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_pr d->usrEdit = new KLineEdit( gb ); KCompletion *kcom = d->usrEdit->completionObject(); kcom->setOrder(KCompletion::Sorted); - setpwent(); - for (i=0; ((user = getpwent()) != 0L) && (i < maxEntries); ++i) - kcom->addItem(QString::fromLatin1(user->pw_name)); - endpwent(); + const QStringList usernames = KUser::allUserNames(); + for (i = 0; i < usernames.size() && i < maxEntries; ++i) + kcom->addItem(usernames.at(i)); d->usrEdit->setCompletionMode((i < maxEntries) ? KGlobalSettings::CompletionAuto : KGlobalSettings::CompletionNone); d->usrEdit->setText(d->strOwner); @@ -1748,30 +1744,11 @@ KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_pr /*** Set Group ***/ QStringList groupList; - QByteArray strUser; - user = getpwuid(geteuid()); - if (user != 0L) { - strUser = user->pw_name; - -#ifdef HAVE_GETGROUPLIST + const KUser kuser(KUser::UseEffectiveUID); + if (kuser.isValid()) { // pick the groups to which the user belongs - int groupCount = 0; - QVarLengthArray groups; - if (getgrouplist(strUser, user->pw_gid, NULL, &groupCount) < 0) { - groups.resize(groupCount); - if (groups.data()) - getgrouplist(strUser, user->pw_gid, groups.data(), &groupCount); - else - groupCount = 0; - } - - for (i = 0; i < groupCount; i++) { - struct group *mygroup = getgrgid(groups[i]); - if (mygroup) - groupList += QString::fromLocal8Bit(mygroup->gr_name); - } + groupList = kuser.groupNames(); } -#endif // HAVE_GETGROUPLIST bool isMyGroup = groupList.contains(d->strGroup); @@ -3290,12 +3267,10 @@ void KDesktopPropsPlugin::slotAdvanced() // Provide username completion up to 1000 users. KCompletion *kcom = new KCompletion; kcom->setOrder(KCompletion::Sorted); - struct passwd *pw; int i, maxEntries = 1000; - setpwent(); - for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++) - kcom->addItem(QString::fromLatin1(pw->pw_name)); - endpwent(); + const QStringList usernames = KUser::allUserNames(); + for (i = 0; i < usernames.size() && i < maxEntries; i++) + kcom->addItem(usernames.at(i)); if (i < maxEntries) { w.suidEdit->setCompletionObject(kcom, true); diff --git a/kio/kio/chmodjob.cpp b/kio/kio/chmodjob.cpp index 3d3b578b..71710185 100644 --- a/kio/kio/chmodjob.cpp +++ b/kio/kio/chmodjob.cpp @@ -27,12 +27,11 @@ #include #include #include +#include #include #include -#include -#include #include #include #include @@ -272,20 +271,20 @@ ChmodJob *KIO::chmod( const KFileItemList& lstItems, int permissions, int mask, uid_t newOwnerID = uid_t(-1); // chown(2) : -1 means no change if ( !owner.isEmpty() ) { - struct passwd* pw = getpwnam(QFile::encodeName(owner)); - if ( pw == 0L ) + const KUser kuser(owner); + if ( !kuser.isValid() ) kError(250) << "No user" << owner; else - newOwnerID = pw->pw_uid; + newOwnerID = kuser.uid(); } gid_t newGroupID = gid_t(-1); // chown(2) : -1 means no change if ( !group.isEmpty() ) { - struct group* g = getgrnam(QFile::encodeName(group)); - if ( g == 0L ) + const KUserGroup kusergroup(group); + if ( kusergroup.isValid() ) kError(250) << "No group" << group; else - newGroupID = g->gr_gid; + newGroupID = kusergroup.gid(); } return ChmodJobPrivate::newJob(lstItems, permissions, mask, newOwnerID, newGroupID, recursive, flags); diff --git a/kio/kio/job.cpp b/kio/kio/job.cpp index 0f3eae72..06742b20 100644 --- a/kio/kio/job.cpp +++ b/kio/kio/job.cpp @@ -22,8 +22,14 @@ #include "job.h" #include "job_p.h" #include "clipboardupdater_p.h" - -#include +#include "jobuidelegate.h" +#include "kmimetype.h" +#include "slave.h" +#include "scheduler.h" +#include "kdirwatch.h" +#include "kprotocolinfo.h" +#include "kprotocolmanager.h" +#include "filejob.h" #include #include @@ -33,10 +39,7 @@ #include #include #include -extern "C" { -#include -#include -} + #include #include #include @@ -48,15 +51,6 @@ extern "C" { #include #include -#include "jobuidelegate.h" -#include "kmimetype.h" -#include "slave.h" -#include "scheduler.h" -#include "kdirwatch.h" -#include "kprotocolinfo.h" -#include "kprotocolmanager.h" -#include "filejob.h" - using namespace KIO; #define MAX_READ_BUF_SIZE (64 * 1024) // 64 KB at a time seems reasonable... diff --git a/kio/kio/kacl.cpp b/kio/kio/kacl.cpp index 29e1e8bf..3fb94176 100644 --- a/kio/kio/kacl.cpp +++ b/kio/kio/kacl.cpp @@ -22,20 +22,18 @@ #include -#include -#include -#include -#include -#ifdef HAVE_POSIX_ACL -#include -#include -#endif #include #include #include - #include +#include +#include +#include +#ifdef HAVE_POSIX_ACL +# include +# include +#endif class KACL::KACLPrivate { public: @@ -185,20 +183,12 @@ static void printACL( acl_t acl, const QString &comment ) static int getUidForName( const QString& name ) { - struct passwd *user = getpwnam( name.toLocal8Bit() ); - if ( user ) - return user->pw_uid; - else - return -1; + return KUser( name ).uid(); } static int getGidForName( const QString& name ) { - struct group *group = getgrnam( name.toLocal8Bit() ); - if ( group ) - return group->gr_gid; - else - return -1; + return KUserGroup( name ).gid(); } #endif // ------------------ begin API implementation ------------ @@ -626,12 +616,11 @@ QString KACL::asString() const QString KACL::KACLPrivate::getUserName( uid_t uid ) const { if ( !m_usercache.contains( uid ) ) { - struct passwd *user = getpwuid( uid ); - if ( user ) { - m_usercache.insert( uid, QString::fromLatin1(user->pw_name) ); - } - else + const KUser kuser( uid ); + if ( !kuser.isValid() ) { return QString::number( uid ); + } + m_usercache.insert( uid, kuser.loginName() ); } return m_usercache[uid]; } @@ -640,12 +629,11 @@ QString KACL::KACLPrivate::getUserName( uid_t uid ) const QString KACL::KACLPrivate::getGroupName( gid_t gid ) const { if ( !m_groupcache.contains( gid ) ) { - struct group *grp = getgrgid( gid ); - if ( grp ) { - m_groupcache.insert( gid, QString::fromLatin1(grp->gr_name) ); - } - else + const KUserGroup kusergroup( gid ); + if ( !kusergroup.isValid() ) { return QString::number( gid ); + } + m_groupcache.insert( gid, kusergroup.name() ); } return m_groupcache[gid]; } diff --git a/kio/kio/kfileitem.cpp b/kio/kio/kfileitem.cpp index dc9fb8b3..408193f4 100644 --- a/kio/kio/kfileitem.cpp +++ b/kio/kio/kfileitem.cpp @@ -23,11 +23,8 @@ #include #include -#include -#include #include #include -#include #include #include @@ -50,6 +47,7 @@ #include #include #include +#include #include static bool isKDirShare(const QString &dirpath) @@ -682,10 +680,9 @@ QString KFileItemPrivate::user() const KDE_struct_stat buff; if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link { - struct passwd *pwuser = getpwuid( buff.st_uid ); - if ( pwuser != 0 ) { - userName = QString::fromLocal8Bit(pwuser->pw_name); - m_entry.insert( KIO::UDSEntry::UDS_USER, userName ); + const KUser kuser( buff.st_uid ); + if ( kuser.isValid() ) { + m_entry.insert( KIO::UDSEntry::UDS_USER, kuser.loginName() ); } } } @@ -708,14 +705,12 @@ QString KFileItemPrivate::group() const KDE_struct_stat buff; if ( KDE::lstat( m_url.toLocalFile( KUrl::RemoveTrailingSlash ), &buff ) == 0) // get uid/gid of the link, if it's a link { - struct group *ge = getgrgid( buff.st_gid ); - if ( ge != 0 ) { - groupName = QString::fromLocal8Bit(ge->gr_name); - if (groupName.isEmpty()) - groupName.sprintf("%d",ge->gr_gid); + const KUserGroup kusergroup( buff.st_gid ); + if ( kusergroup.isValid() ) { + groupName = kusergroup.name(); } - else - groupName.sprintf("%d",buff.st_gid); + if (groupName.isEmpty()) + groupName = QString::number(buff.st_gid); m_entry.insert( KIO::UDSEntry::UDS_GROUP, groupName ); } } @@ -1045,8 +1040,7 @@ bool KFileItem::isReadable() const return false; /* - struct passwd * user = getpwuid( geteuid() ); - bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); + bool isMyFile = (KUser(KUser::UseEffectiveUID).loginName() == d->m_user); // This gets ugly for the group.... // Maybe we want a static QString for the user and a static QStringList // for the groups... then we need to handle the deletion properly... @@ -1075,8 +1069,7 @@ bool KFileItem::isWritable() const return false; /* - struct passwd * user = getpwuid( geteuid() ); - bool isMyFile = (QString::fromLocal8Bit(user->pw_name) == d->m_user); + bool isMyFile = (KUser(KUser::UseEffectiveUID).loginName() == d->m_user); // This gets ugly for the group.... // Maybe we want a static QString for the user and a static QStringList // for the groups... then we need to handle the deletion properly... diff --git a/kio/kio/kurlcompletion.cpp b/kio/kio/kurlcompletion.cpp index 63d56ae0..6e9c5ec4 100644 --- a/kio/kio/kurlcompletion.cpp +++ b/kio/kio/kurlcompletion.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -56,7 +57,6 @@ #include #include #include -#include #include #include @@ -255,11 +255,12 @@ protected: // we don't need to handle prepend here, right? ~user is always at pos 0 assert(m_prepend.isEmpty()); - struct passwd* pw; - ::setpwent(); - while ((pw = ::getpwent()) && !terminationRequested()) - addMatch(tilde + QString::fromLocal8Bit(pw->pw_name)); - ::endpwent(); + foreach (const QString &user, KUser::allUserNames()) { + if (terminationRequested()) { + break; + } + addMatch(tilde + user); + } addMatch(QString(tilde)); diff --git a/kioslave/file/file.cpp b/kioslave/file/file.cpp index 7a9bd53e..160c0abb 100644 --- a/kioslave/file/file.cpp +++ b/kioslave/file/file.cpp @@ -40,8 +40,6 @@ #include #include #include -#include -#include #include #include #include @@ -74,6 +72,7 @@ #include #include #include +#include using namespace KIO; @@ -731,12 +730,11 @@ void FileProtocol::put( const KUrl& url, int _mode, KIO::JobFlags _flags ) QString FileProtocol::getUserName( uid_t uid ) const { if ( !mUsercache.contains( uid ) ) { - struct passwd *user = getpwuid( uid ); - if ( user ) { - mUsercache.insert( uid, QString::fromLatin1(user->pw_name) ); - } - else + const KUser kuser( uid ); + if ( !kuser.isValid() ) { return QString::number( uid ); + } + mUsercache.insert( uid, kuser.loginName() ); } return mUsercache[uid]; } @@ -744,12 +742,11 @@ QString FileProtocol::getUserName( uid_t uid ) const QString FileProtocol::getGroupName( gid_t gid ) const { if ( !mGroupcache.contains( gid ) ) { - struct group *grp = getgrgid( gid ); - if ( grp ) { - mGroupcache.insert( gid, QString::fromLatin1(grp->gr_name) ); - } - else + const KUserGroup kusergroup( gid ); + if ( !kusergroup.isValid() ) { return QString::number( gid ); + } + mGroupcache.insert( gid, kusergroup.name() ); } return mGroupcache[gid]; } diff --git a/kioslave/file/file_unix.cpp b/kioslave/file/file_unix.cpp index ec731834..e562062e 100644 --- a/kioslave/file/file_unix.cpp +++ b/kioslave/file/file_unix.cpp @@ -37,14 +37,13 @@ #include #include #include +#include #include #include #include #include -#include #include -#include #include //sendfile has different semantics in different platforms @@ -567,28 +566,28 @@ void FileProtocol::chown( const KUrl& url, const QString& owner, const QString& // get uid from given owner { - struct passwd *p = ::getpwnam(owner.toLatin1()); + const KUser kuser(owner); - if ( ! p ) { + if ( ! kuser.isValid() ) { error( KIO::ERR_SLAVE_DEFINED, i18n( "Could not get user id for given user name %1", owner ) ); return; } - uid = p->pw_uid; + uid = kuser.uid(); } // get gid from given group { - struct group *p = ::getgrnam(group.toLatin1()); + const KUserGroup kusergroup(group); - if ( ! p ) { + if ( ! kusergroup.isValid() ) { error( KIO::ERR_SLAVE_DEFINED, i18n( "Could not get group id for given group name %1", group ) ); return; } - gid = p->gr_gid; + gid = kusergroup.gid(); } if ( ::chown(_path, uid, gid) == -1 ) { diff --git a/kpty/kpty.cpp b/kpty/kpty.cpp index 3cf43c4f..0288b124 100644 --- a/kpty/kpty.cpp +++ b/kpty/kpty.cpp @@ -39,7 +39,6 @@ #include #include #include -#include #if defined(HAVE_PTY_H) # include