File indexing completed on 2025-01-12 12:26:25
0001 /* This file is part of the KDE project 0002 Copyright (c) 2001 David Faure <faure@kde.org> 0003 Copyright (c) 2001 Laurent Montel <lmontel@mandrakesoft.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License version 2 as published by the Free Software Foundation. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kfileshare.h" 0021 #include "kfileshare_p.h" 0022 #include <QDir> 0023 #include <QFile> 0024 #include <QProcess> 0025 #include <QDebug> 0026 #include <klocalizedstring.h> 0027 #include <qstandardpaths.h> 0028 #include <kdirwatch.h> 0029 #include <stdio.h> 0030 #include <stdlib.h> 0031 #include <errno.h> 0032 #include <kconfig.h> 0033 #include <kconfiggroup.h> 0034 #include <kuser.h> 0035 0036 static KFileShare::Authorization s_authorization = KFileShare::NotInitialized; 0037 Q_GLOBAL_STATIC(QStringList, s_shareList) 0038 static KFileShare::ShareMode s_shareMode; 0039 static bool s_sambaEnabled; 0040 static bool s_nfsEnabled; 0041 static bool s_restricted; 0042 static QString s_fileShareGroup; 0043 static bool s_sharingEnabled; 0044 0045 #define FILESHARECONF "/etc/security/fileshare.conf" 0046 0047 static QString findExe(const char *exeName) 0048 { 0049 // Normally fileshareset and filesharelist are installed in libexec/kf5; 0050 // allow distributions to move it somewhere else in the PATH or in /usr/sbin. 0051 QString exe = QStandardPaths::findExecutable(exeName); 0052 if (exe.isEmpty()) { 0053 exe = QStandardPaths::findExecutable(exeName, QStringList() << "/usr/sbin"); 0054 } 0055 if (exe.isEmpty()) { 0056 qWarning() << exeName << "not found in PATH nor in /usr/sbin"; 0057 } 0058 return exe; 0059 } 0060 0061 KFileSharePrivate::KFileSharePrivate() 0062 { 0063 KDirWatch::self()->addFile(FILESHARECONF); 0064 connect(KDirWatch::self(), SIGNAL(dirty(QString)), this, 0065 SLOT(slotFileChange(QString))); 0066 connect(KDirWatch::self(), SIGNAL(created(QString)), this, 0067 SLOT(slotFileChange(QString))); 0068 connect(KDirWatch::self(), SIGNAL(deleted(QString)), this, 0069 SLOT(slotFileChange(QString))); 0070 } 0071 0072 KFileSharePrivate::~KFileSharePrivate() 0073 { 0074 KDirWatch::self()->removeFile(FILESHARECONF); 0075 } 0076 0077 Q_GLOBAL_STATIC(KFileSharePrivate, _self) 0078 0079 KFileSharePrivate *KFileSharePrivate::self() 0080 { 0081 return _self(); 0082 } 0083 0084 void KFileSharePrivate::slotFileChange(const QString &file) 0085 { 0086 if (file == FILESHARECONF) { 0087 KFileShare::readConfig(); 0088 KFileShare::readShareList(); 0089 } 0090 } 0091 0092 KFileShare::ShareMode readEntry(const KConfigGroup &cg, const char *key, 0093 const KFileShare::ShareMode &aDefault) 0094 { 0095 const QByteArray data = cg.readEntry(key, QByteArray()); 0096 0097 if (!data.isEmpty()) { 0098 if (data.toLower() == "simple") { 0099 return KFileShare::Simple; 0100 } else if (data.toLower() == "advanced") { 0101 return KFileShare::Advanced; 0102 } 0103 } 0104 0105 return aDefault; 0106 } 0107 0108 void KFileShare::readConfig() // static 0109 { 0110 // Create KFileSharePrivate instance 0111 KFileSharePrivate::self(); 0112 KConfig config(QLatin1String(FILESHARECONF)); 0113 KConfigGroup group(&config, QString()); 0114 0115 s_sharingEnabled = group.readEntry("FILESHARING", true); 0116 s_restricted = group.readEntry("RESTRICT", true); 0117 s_fileShareGroup = group.readEntry("FILESHAREGROUP", "fileshare"); 0118 0119 if (!s_sharingEnabled) { 0120 s_authorization = UserNotAllowed; 0121 } else if (!s_restricted) { 0122 s_authorization = Authorized; 0123 } else { 0124 // check if current user is in fileshare group 0125 KUserGroup shareGroup(s_fileShareGroup); 0126 if (shareGroup.users().contains(KUser())) { 0127 s_authorization = Authorized; 0128 } else { 0129 s_authorization = UserNotAllowed; 0130 } 0131 } 0132 0133 s_shareMode = readEntry(group, "SHARINGMODE", Simple); 0134 0135 s_sambaEnabled = group.readEntry("SAMBA", true); 0136 s_nfsEnabled = group.readEntry("NFS", true); 0137 } 0138 0139 KFileShare::ShareMode KFileShare::shareMode() 0140 { 0141 if (s_authorization == NotInitialized) { 0142 readConfig(); 0143 } 0144 0145 return s_shareMode; 0146 } 0147 0148 bool KFileShare::sharingEnabled() 0149 { 0150 if (s_authorization == NotInitialized) { 0151 readConfig(); 0152 } 0153 0154 return s_sharingEnabled; 0155 } 0156 0157 bool KFileShare::isRestricted() 0158 { 0159 if (s_authorization == NotInitialized) { 0160 readConfig(); 0161 } 0162 0163 return s_restricted; 0164 } 0165 0166 QString KFileShare::fileShareGroup() 0167 { 0168 if (s_authorization == NotInitialized) { 0169 readConfig(); 0170 } 0171 0172 return s_fileShareGroup; 0173 } 0174 0175 bool KFileShare::sambaEnabled() 0176 { 0177 if (s_authorization == NotInitialized) { 0178 readConfig(); 0179 } 0180 0181 return s_sambaEnabled; 0182 } 0183 0184 bool KFileShare::nfsEnabled() 0185 { 0186 if (s_authorization == NotInitialized) { 0187 readConfig(); 0188 } 0189 0190 return s_nfsEnabled; 0191 } 0192 0193 void KFileShare::readShareList() 0194 { 0195 KFileSharePrivate::self(); 0196 s_shareList()->clear(); 0197 0198 QString exe = ::findExe("filesharelist"); 0199 if (exe.isEmpty()) { 0200 s_authorization = ErrorNotFound; 0201 return; 0202 } 0203 QProcess proc; 0204 proc.start(exe, QStringList()); 0205 if (!proc.waitForFinished()) { 0206 qWarning() << "Can't run" << exe; 0207 s_authorization = ErrorNotFound; 0208 return; 0209 } 0210 0211 // Reading code shamelessly stolen from khostname.cpp ;) 0212 while (!proc.atEnd()) { 0213 QString line = proc.readLine().trimmed(); 0214 int length = line.length(); 0215 if (length > 0) { 0216 if (line[length - 1] != '/') { 0217 line += '/'; 0218 } 0219 s_shareList()->append(line); 0220 //qDebug() << "Shared dir:" << line; 0221 } 0222 } 0223 } 0224 0225 bool KFileShare::isDirectoryShared(const QString &_path) 0226 { 0227 if (! s_shareList.exists()) 0228 readShareList(); 0229 0230 QString path(_path); 0231 if (path[path.length() - 1] != '/') { 0232 path += '/'; 0233 } 0234 return s_shareList()->contains(path); 0235 } 0236 0237 KFileShare::Authorization KFileShare::authorization() 0238 { 0239 // The app should do this on startup, but if it doesn't, let's do here. 0240 if (s_authorization == NotInitialized) { 0241 readConfig(); 0242 } 0243 return s_authorization; 0244 } 0245 0246 bool KFileShare::setShared(const QString &path, bool shared) 0247 { 0248 if (! KFileShare::sharingEnabled() || 0249 KFileShare::shareMode() == Advanced) { 0250 return false; 0251 } 0252 0253 //qDebug() << path << "," << shared; 0254 QString exe = ::findExe("fileshareset"); 0255 if (exe.isEmpty()) { 0256 return false; 0257 } 0258 0259 QStringList args; 0260 if (shared) { 0261 args << "--add"; 0262 } else { 0263 args << "--remove"; 0264 } 0265 args << path; 0266 int ec = QProcess::execute(exe, args); // should be ok, the perl script terminates fast 0267 //qDebug() << "exitCode=" << ec; 0268 bool ok = !ec; 0269 switch (ec) { 0270 case 1: 0271 // User is not authorized 0272 break; 0273 case 3: 0274 // Called script with --add, but path was already shared before. 0275 // Result is nevertheless what the client wanted, so 0276 // this is alright. 0277 ok = true; 0278 break; 0279 case 4: 0280 // Invalid mount point 0281 break; 0282 case 5: 0283 // Called script with --remove, but path was not shared before. 0284 // Result is nevertheless what the client wanted, so 0285 // this is alright. 0286 ok = true; 0287 break; 0288 case 6: 0289 // There is no export method 0290 break; 0291 case 7: 0292 // file sharing is disabled 0293 break; 0294 case 8: 0295 // advanced sharing is enabled 0296 break; 0297 case 255: 0298 // Abitrary error 0299 break; 0300 } 0301 0302 return ok; 0303 } 0304 0305 #include "moc_kfileshare_p.cpp" 0306