File indexing completed on 2024-04-21 16:32:34

0001 /***************************************************************************
0002                       permissionsplugin.cpp  -  description
0003                              -------------------
0004     begin                : Sun Mar 9 2008
0005     copyright            : (C) 2002 by Dominik Seichter
0006     email                : domseichter@web.de
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "permissionsplugin.h"
0019 
0020 #ifndef Q_OS_WIN
0021 
0022 #include <kiconloader.h>
0023 
0024 #include "ui_permissionspluginwidget.h"
0025 
0026 #include <QDialog>
0027 #include <QDialogButtonBox>
0028 #include <QUrl>
0029 
0030 // OS includes
0031 #include <stdio.h>
0032 #include <pwd.h>
0033 #include <sys/types.h>
0034 #include <sys/stat.h>
0035 #include <grp.h>
0036 #include <unistd.h>
0037 
0038 // Only maxentries users are listed in the plugin
0039 // increase if you need more
0040 #define MAXENTRIES 1000
0041 
0042 PermissionsPlugin::PermissionsPlugin(PluginLoader *loader)
0043     : QObject(nullptr), Plugin(loader), m_curPermission(S_IRUSR | S_IWUSR | S_IRGRP)
0044 {
0045     m_widget = new Ui::PermissionsPluginWidget();
0046 
0047     int i;
0048     uid_t uid = getuid();
0049 
0050     // Get all users on the system
0051     struct passwd *user;
0052     setpwent();
0053     for (i = 0; ((user = getpwent()) != 0L) && (i < MAXENTRIES); ++i) {
0054         if (uid == 0 || uid == user->pw_uid) {
0055             m_users.append(QString::fromLatin1(user->pw_name));
0056         }
0057     }
0058     endpwent();
0059 
0060     // Get all groups on the system
0061     struct group *ge;
0062     user = getpwuid(uid);
0063     setgrent();
0064     for (i = 0; ((ge = getgrent()) != 0L) && (i < MAXENTRIES); ++i) {
0065         if (uid == 0) {
0066             // Add all groups if we are run as root
0067             m_groups.append(QString::fromLatin1(ge->gr_name));
0068         } else {
0069             // If the current user is member of this group: add it
0070             char **members = ge->gr_mem;
0071             char *member;
0072 
0073             while ((member = *members) != 0L) {
0074                 if (strcmp(user->pw_name, member) == 0) {
0075                     m_groups.append(QString::fromLatin1(ge->gr_name));
0076                     break;
0077                 }
0078 
0079                 ++members;
0080             }
0081         }
0082     }
0083     endgrent();
0084 
0085     // add the users group
0086     ge = getgrgid(user->pw_gid);
0087     if (ge) {
0088         QString name = QString::fromLatin1(ge->gr_name);
0089         if (name.isEmpty()) {
0090             name.setNum(ge->gr_gid);
0091         }
0092 
0093         m_groups.append(name);
0094     }
0095 
0096     // sort both lists
0097     m_users.sort();
0098     m_groups.sort();
0099 }
0100 
0101 PermissionsPlugin::~PermissionsPlugin()
0102 {
0103     delete m_widget;
0104 }
0105 
0106 const QString PermissionsPlugin::name() const
0107 {
0108     return i18n("Permissions");
0109 }
0110 
0111 const QPixmap PermissionsPlugin::icon() const
0112 {
0113     return KIconLoader::global()->loadIcon("document-properties", KIconLoader::NoGroup, KIconLoader::SizeSmall);
0114 }
0115 
0116 QString PermissionsPlugin::processFile(BatchRenamer *, int, const QString &filenameOrToken, EPluginType)
0117 {
0118     const QString &filename = filenameOrToken;
0119 
0120     if (!QUrl(filename).isLocalFile()) {
0121         return i18n("PermissionsPlugin works only with local files. %1 is a remote file.", filename);
0122     }
0123 
0124     if (m_widget->checkPermissions->isChecked()) {
0125         if (chmod(filename.toUtf8().data(), (mode_t)m_curPermission) == -1) {
0126             return i18n("Cannot chmod %1.", filename);
0127         }
0128     }
0129 
0130     if (m_widget->checkOwner->isChecked()) {
0131         uid_t uid = getUid(m_widget->comboUser->currentText());
0132         gid_t gid = getGid(m_widget->comboGroup->currentText());
0133 
0134         if (chown(filename.toUtf8().data(), uid, gid)) {
0135             return i18n("Cannot chown %1.", filename);
0136         }
0137     }
0138 
0139     return QString();
0140 }
0141 
0142 void PermissionsPlugin::createUI(QWidget *parent) const
0143 {
0144     m_widget->setupUi(parent);
0145 
0146     m_widget->labelAdvanced->setVisible(false);
0147 
0148     m_widget->comboUser->insertItems(0, m_users);
0149     m_widget->comboGroup->insertItems(0, m_groups);
0150 
0151     m_widget->comboPermOwner->setCurrentIndex(2);
0152     m_widget->comboPermGroup->setCurrentIndex(1);
0153     m_widget->comboPermOthers->setCurrentIndex(0);
0154 
0155     connect(m_widget->checkOwner, &QCheckBox::clicked,
0156             this, &PermissionsPlugin::slotEnableControls);
0157     connect(m_widget->checkPermissions, &QCheckBox::clicked,
0158             this, &PermissionsPlugin::slotEnableControls);
0159     connect(m_widget->pushButton, &QPushButton::clicked,
0160             this, &PermissionsPlugin::slotAdvancedPermissions);
0161     connect(m_widget->comboPermOwner, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
0162             this, &PermissionsPlugin::slotUpdatePermissions);
0163     connect(m_widget->comboPermGroup, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
0164             this, &PermissionsPlugin::slotUpdatePermissions);
0165     connect(m_widget->comboPermOthers, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
0166             this, &PermissionsPlugin::slotUpdatePermissions);
0167     connect(m_widget->checkFolder, &QCheckBox::clicked,
0168             this, &PermissionsPlugin::slotUpdatePermissions);
0169 }
0170 
0171 void PermissionsPlugin::slotEnableControls()
0172 {
0173     m_widget->groupOwner->setEnabled(m_widget->checkOwner->isChecked());
0174     m_widget->groupPermissions->setEnabled(m_widget->checkPermissions->isChecked());
0175 }
0176 
0177 void PermissionsPlugin::slotAdvancedPermissions()
0178 {
0179     QDialog dialog;
0180 
0181     QLabel *la, *cl[3];
0182     QGridLayout *gl;
0183     QCheckBox *permBox[3][4];
0184 
0185     QVBoxLayout *layout = new QVBoxLayout(&dialog);
0186     QGroupBox *groupPermission = new QGroupBox(i18n("Access permissions"), &dialog);
0187 
0188     gl = new QGridLayout(groupPermission);
0189     //gl->addRowSpacing(0, 10);
0190 
0191     la = new QLabel(i18n("Class"), groupPermission);
0192     gl->addWidget(la, 1, 0);
0193 
0194     la = new QLabel(i18n("Read"), groupPermission);
0195     gl->addWidget(la, 1, 1);
0196 
0197     la = new QLabel(i18n("Write"), groupPermission);
0198     gl->addWidget(la, 1, 2);
0199 
0200     la = new QLabel(i18n("Exec"), groupPermission);
0201     QSize size = la->sizeHint();
0202     size.setWidth(size.width() + 15);
0203     la->setFixedSize(size);
0204     gl->addWidget(la, 1, 3);
0205 
0206     la = new QLabel(i18n("Special"), groupPermission);
0207     gl->addWidget(la, 1, 4);
0208 
0209     cl[0] = new QLabel(i18n("User"), groupPermission);
0210     gl->addWidget(cl[0], 2, 0);
0211 
0212     cl[1] = new QLabel(i18n("Group"), groupPermission);
0213     gl->addWidget(cl[1], 3, 0);
0214 
0215     cl[2] = new QLabel(i18n("Others"), groupPermission);
0216     gl->addWidget(cl[2], 4, 0);
0217 
0218     la = new QLabel(i18n("UID"), groupPermission);
0219     gl->addWidget(la, 2, 5);
0220 
0221     la = new QLabel(i18n("GID"), groupPermission);
0222     gl->addWidget(la, 3, 5);
0223 
0224     la = new QLabel(i18n("Sticky"), groupPermission);
0225     gl->addWidget(la, 4, 5);
0226 
0227     int fperm[3][4] = {
0228         {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID},
0229         {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID},
0230         {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX}
0231     };
0232 
0233     for (int row = 0; row < 3 ; ++row) {
0234         for (int col = 0; col < 4; ++col) {
0235             QCheckBox *cb = new QCheckBox(groupPermission);
0236             permBox[row][col] = cb;
0237             gl->addWidget(permBox[row][col], row + 2, col + 1);
0238 
0239             cb->setChecked(fperm[row][col] & m_curPermission);
0240         }
0241     }
0242 
0243     QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
0244     connect(box, &QDialogButtonBox::accepted,
0245             &dialog, &QDialog::accept);
0246     connect(box, &QDialogButtonBox::rejected,
0247             &dialog, &QDialog::reject);
0248 
0249     layout->addWidget(groupPermission);
0250     layout->addWidget(box);
0251 
0252     if (dialog.exec() == QDialog::Accepted) {
0253         m_curPermission = 0;
0254         for (int row = 0; row < 3; ++row) {
0255             for (int col = 0; col < 4; ++col) {
0256                 if (permBox[row][col]->isChecked()) {
0257                     m_curPermission |= fperm[row][col];
0258                 }
0259             }
0260         }
0261 
0262         //setCurrentPermissions( m_curPermission );
0263         m_widget->labelAdvanced->setVisible(true);
0264         m_widget->comboPermOwner->setEnabled(false);
0265         m_widget->comboPermGroup->setEnabled(false);
0266         m_widget->comboPermOthers->setEnabled(false);
0267         m_widget->checkFolder->setEnabled(false);
0268     }
0269 }
0270 
0271 void PermissionsPlugin::slotUpdatePermissions()
0272 {
0273     int fpermUser [3] = { 0, S_IRUSR, S_IRUSR | S_IWUSR };
0274     int fpermGroup[3] = { 0, S_IRGRP, S_IRGRP | S_IWGRP };
0275     int fpermOther[3] = { 0, S_IROTH, S_IROTH | S_IWOTH };
0276 
0277     m_curPermission = 0;
0278     m_curPermission |= (fpermUser[m_widget->comboPermOwner->currentIndex()]);
0279     m_curPermission |= (fpermGroup[m_widget->comboPermGroup->currentIndex()]);
0280     m_curPermission |= (fpermOther[m_widget->comboPermOthers->currentIndex()]);
0281 
0282     m_widget->checkFolder->setTristate(false);
0283     if (m_widget->checkFolder->isChecked()) {
0284         m_widget->checkFolder->setChecked(true);
0285         m_curPermission |= S_IXUSR;
0286         m_curPermission |= S_IXGRP;
0287         m_curPermission |= S_IXOTH;
0288     }
0289 }
0290 
0291 int PermissionsPlugin::getGid(const QString &group) const
0292 {
0293     int i, r = 0;
0294     struct group *ge;
0295     setgrent();
0296     for (i = 0; ((ge = getgrent()) != 0L) && (i < MAXENTRIES); i++)
0297         if (!strcmp(ge->gr_name, group.toUtf8().data())) {
0298             r = ge->gr_gid;
0299             break;
0300         }
0301 
0302     endgrent();
0303     return r;
0304 }
0305 
0306 int PermissionsPlugin::getUid(const QString &owner) const
0307 {
0308     int i, r = 0;
0309     struct passwd *user;
0310     setpwent();
0311     for (i = 0; ((user = getpwent()) != 0L) && (i < MAXENTRIES); i++)
0312         if (!strcmp(user->pw_name, owner.toUtf8().data())) {
0313             r = user->pw_uid;
0314             break;
0315         }
0316 
0317     endpwent();
0318     return r;
0319 }
0320 
0321 /*
0322 void PermissionsPlugin::setCurrentPermissions( int perm )
0323 {
0324     m_widget->comboPermOwner->setCurrentIndex( 0 );
0325     m_widget->comboPermGroup->setCurrentIndex( 0 );
0326     m_widget->comboPermOthers->setCurrentIndex( 0 );
0327 
0328     int fpermUser [3] = { 0, S_IRUSR, S_IRUSR | S_IWUSR };
0329     int fpermGroup[3] = { 0, S_IRGRP, S_IRGRP | S_IWGRP };
0330     int fpermOther[3] = { 0, S_IROTH, S_IROTH | S_IWOTH };
0331 
0332     int i;
0333     for( i=2; i>=0; i-- )
0334     {
0335         if( (fpermUser[i] & perm) )
0336         {
0337             m_widget->comboPermOwner->setCurrentIndex( i );
0338             break;
0339         }
0340     }
0341 
0342     for( i=2; i>=0; i-- )
0343     {
0344         if( (fpermGroup[i] & perm) )
0345         {
0346             m_widget->comboPermGroup->setCurrentIndex( i );
0347             break;
0348         }
0349     }
0350 
0351     for( i=2; i>=0; i-- )
0352     {
0353         if( (fpermOther[i] & perm) )
0354         {
0355             m_widget->comboPermOthers->setCurrentIndex( i );
0356             break;
0357         }
0358     }
0359 
0360     if( (perm & S_IXUSR) &&
0361         (perm & S_IXGRP) &&
0362         (perm & S_IXOTH) )
0363     {
0364         m_widget->checkFolder->setTristate( false );
0365         m_widget->checkFolder->setChecked( true );
0366     }
0367     else
0368     {
0369         if( (perm & S_IXUSR) ||
0370             (perm & S_IXGRP) ||
0371             (perm & S_IXOTH) )
0372             m_widget->checkFolder->setCheckState( Qt::PartiallyChecked );
0373     }
0374 
0375     m_curPermission = perm;
0376 }
0377 */
0378 #endif // Q_OS_WIN