File indexing completed on 2022-10-04 17:30:20

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