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 <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-10-10 20:51:06 +03:00
parent 10ec136182
commit 704ef230d5
12 changed files with 86 additions and 158 deletions

View file

@ -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

View file

@ -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 */

View file

@ -43,15 +43,11 @@
#include <kdialog.h>
#include <khbox.h>
#include <kstandarddirs.h>
#include <kuser.h>
#ifdef HAVE_ACL_LIBACL_H
# include <acl/libacl.h>
#endif
extern "C" {
#include <pwd.h>
#include <grp.h>
}
#include <assert.h>
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();

View file

@ -48,8 +48,6 @@
#include <config.h>
#include <config-acl.h>
extern "C" {
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
@ -61,10 +59,10 @@ extern "C" {
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QCheckBox>
#include <QtCore/qstringlist.h>
#include <QtCore/QTextStream>
#include <QtGui/QPainter>
#include <QtGui/QLayout>
@ -72,7 +70,6 @@ extern "C" {
#include <QtGui/QProgressBar>
#include <QVector>
#include <QFileInfo>
#include <QtCore/qvarlengtharray.h>
#ifdef HAVE_POSIX_ACL
#include <sys/acl.h>
@ -119,6 +116,7 @@ extern "C" {
#include <kshell.h>
#include <kcapacitybar.h>
#include <kfileitemlistproperties.h>
#include <kuser.h>
#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<gid_t> 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);

View file

@ -27,12 +27,11 @@
#include <klocale.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kuser.h>
#include <QtCore/QFile>
#include <config.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
@ -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);

View file

@ -22,8 +22,14 @@
#include "job.h"
#include "job_p.h"
#include "clipboardupdater_p.h"
#include <config.h>
#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 <sys/types.h>
#include <sys/wait.h>
@ -33,10 +39,7 @@
#include <stdio.h>
#include <time.h>
#include <unistd.h>
extern "C" {
#include <pwd.h>
#include <grp.h>
}
#include <QtCore/QList>
#include <QtCore/QTimer>
#include <QtCore/QFile>
@ -48,15 +51,6 @@ extern "C" {
#include <kde_file.h>
#include <kdirnotify.h>
#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...

View file

@ -22,20 +22,18 @@
#include <config-acl.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#ifdef HAVE_POSIX_ACL
#include <sys/acl.h>
#include <acl/libacl.h>
#endif
#include <QHash>
#include <QList>
#include <QPair>
#include <kdebug.h>
#include <kuser.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_POSIX_ACL
# include <sys/acl.h>
# include <acl/libacl.h>
#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];
}

View file

@ -23,11 +23,8 @@
#include <config.h>
#include <sys/time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <unistd.h>
#include <QtCore/qdatetime.h>
@ -50,6 +47,7 @@
#include <kdesktopfile.h>
#include <kmountpoint.h>
#include <kconfiggroup.h>
#include <kuser.h>
#include <kfilesystemtype_p.h>
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...

View file

@ -48,6 +48,7 @@
#include <kde_file.h>
#include <kconfiggroup.h>
#include <kshell.h>
#include <kuser.h>
#include <stdlib.h>
#include <assert.h>
@ -56,7 +57,6 @@
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <pwd.h>
#include <time.h>
#include <sys/param.h>
@ -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));

View file

@ -40,8 +40,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
@ -74,6 +72,7 @@
#include <kde_file.h>
#include <kglobal.h>
#include <kmimetype.h>
#include <kuser.h>
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];
}

View file

@ -37,14 +37,13 @@
#include <kdebug.h>
#include <kconfiggroup.h>
#include <kmountpoint.h>
#include <kuser.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <utime.h>
#include <pwd.h>
#include <stdlib.h>
//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 ) {

View file

@ -39,7 +39,6 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <grp.h>
#if defined(HAVE_PTY_H)
# include <pty.h>