KDELibs4Support

kfileshare.cpp
1 /* This file is part of the KDE project
2  Copyright (c) 2001 David Faure <[email protected]>
3  Copyright (c) 2001 Laurent Montel <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kfileshare.h"
21 #include "kfileshare_p.h"
22 #include <QDir>
23 #include <QFile>
24 #include <QProcess>
25 #include <QDebug>
26 #include <klocalizedstring.h>
27 #include <qstandardpaths.h>
28 #include <kdirwatch.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <kconfig.h>
33 #include <kconfiggroup.h>
34 #include <kuser.h>
35 
36 static KFileShare::Authorization s_authorization = KFileShare::NotInitialized;
37 Q_GLOBAL_STATIC(QStringList, s_shareList)
38 static KFileShare::ShareMode s_shareMode;
39 static bool s_sambaEnabled;
40 static bool s_nfsEnabled;
41 static bool s_restricted;
42 static QString s_fileShareGroup;
43 static bool s_sharingEnabled;
44 
45 #define FILESHARECONF "/etc/security/fileshare.conf"
46 
47 static QString findExe(const char *exeName)
48 {
49  // Normally fileshareset and filesharelist are installed in libexec/kf5;
50  // allow distributions to move it somewhere else in the PATH or in /usr/sbin.
52  if (exe.isEmpty()) {
53  exe = QStandardPaths::findExecutable(exeName, QStringList() << "/usr/sbin");
54  }
55  if (exe.isEmpty()) {
56  qWarning() << exeName << "not found in PATH nor in /usr/sbin";
57  }
58  return exe;
59 }
60 
61 KFileSharePrivate::KFileSharePrivate()
62 {
63  KDirWatch::self()->addFile(FILESHARECONF);
64  connect(KDirWatch::self(), SIGNAL(dirty(QString)), this,
65  SLOT(slotFileChange(QString)));
66  connect(KDirWatch::self(), SIGNAL(created(QString)), this,
67  SLOT(slotFileChange(QString)));
68  connect(KDirWatch::self(), SIGNAL(deleted(QString)), this,
69  SLOT(slotFileChange(QString)));
70 }
71 
72 KFileSharePrivate::~KFileSharePrivate()
73 {
74  KDirWatch::self()->removeFile(FILESHARECONF);
75 }
76 
77 Q_GLOBAL_STATIC(KFileSharePrivate, _self)
78 
79 KFileSharePrivate *KFileSharePrivate::self()
80 {
81  return _self();
82 }
83 
84 void KFileSharePrivate::slotFileChange(const QString &file)
85 {
86  if (file == FILESHARECONF) {
89  }
90 }
91 
92 KFileShare::ShareMode readEntry(const KConfigGroup &cg, const char *key,
93  const KFileShare::ShareMode &aDefault)
94 {
95  const QByteArray data = cg.readEntry(key, QByteArray());
96 
97  if (!data.isEmpty()) {
98  if (data.toLower() == "simple") {
99  return KFileShare::Simple;
100  } else if (data.toLower() == "advanced") {
101  return KFileShare::Advanced;
102  }
103  }
104 
105  return aDefault;
106 }
107 
108 void KFileShare::readConfig() // static
109 {
110  // Create KFileSharePrivate instance
111  KFileSharePrivate::self();
112  KConfig config(QLatin1String(FILESHARECONF));
113  KConfigGroup group(&config, QString());
114 
115  s_sharingEnabled = group.readEntry("FILESHARING", true);
116  s_restricted = group.readEntry("RESTRICT", true);
117  s_fileShareGroup = group.readEntry("FILESHAREGROUP", "fileshare");
118 
119  if (!s_sharingEnabled) {
120  s_authorization = UserNotAllowed;
121  } else if (!s_restricted) {
122  s_authorization = Authorized;
123  } else {
124  // check if current user is in fileshare group
125  KUserGroup shareGroup(s_fileShareGroup);
126  if (shareGroup.users().contains(KUser())) {
127  s_authorization = Authorized;
128  } else {
129  s_authorization = UserNotAllowed;
130  }
131  }
132 
133  s_shareMode = readEntry(group, "SHARINGMODE", Simple);
134 
135  s_sambaEnabled = group.readEntry("SAMBA", true);
136  s_nfsEnabled = group.readEntry("NFS", true);
137 }
138 
140 {
141  if (s_authorization == NotInitialized) {
142  readConfig();
143  }
144 
145  return s_shareMode;
146 }
147 
149 {
150  if (s_authorization == NotInitialized) {
151  readConfig();
152  }
153 
154  return s_sharingEnabled;
155 }
156 
158 {
159  if (s_authorization == NotInitialized) {
160  readConfig();
161  }
162 
163  return s_restricted;
164 }
165 
167 {
168  if (s_authorization == NotInitialized) {
169  readConfig();
170  }
171 
172  return s_fileShareGroup;
173 }
174 
176 {
177  if (s_authorization == NotInitialized) {
178  readConfig();
179  }
180 
181  return s_sambaEnabled;
182 }
183 
185 {
186  if (s_authorization == NotInitialized) {
187  readConfig();
188  }
189 
190  return s_nfsEnabled;
191 }
192 
194 {
195  KFileSharePrivate::self();
196  s_shareList()->clear();
197 
198  QString exe = ::findExe("filesharelist");
199  if (exe.isEmpty()) {
200  s_authorization = ErrorNotFound;
201  return;
202  }
203  QProcess proc;
204  proc.start(exe, QStringList());
205  if (!proc.waitForFinished()) {
206  qWarning() << "Can't run" << exe;
207  s_authorization = ErrorNotFound;
208  return;
209  }
210 
211  // Reading code shamelessly stolen from khostname.cpp ;)
212  while (!proc.atEnd()) {
213  QString line = proc.readLine().trimmed();
214  int length = line.length();
215  if (length > 0) {
216  if (line[length - 1] != '/') {
217  line += '/';
218  }
219  s_shareList()->append(line);
220  //qDebug() << "Shared dir:" << line;
221  }
222  }
223 }
224 
226 {
227  if (! s_shareList.exists())
228  readShareList();
229 
230  QString path(_path);
231  if (path[path.length() - 1] != '/') {
232  path += '/';
233  }
234  return s_shareList()->contains(path);
235 }
236 
237 KFileShare::Authorization KFileShare::authorization()
238 {
239  // The app should do this on startup, but if it doesn't, let's do here.
240  if (s_authorization == NotInitialized) {
241  readConfig();
242  }
243  return s_authorization;
244 }
245 
246 bool KFileShare::setShared(const QString &path, bool shared)
247 {
248  if (! KFileShare::sharingEnabled() ||
249  KFileShare::shareMode() == Advanced) {
250  return false;
251  }
252 
253  //qDebug() << path << "," << shared;
254  QString exe = ::findExe("fileshareset");
255  if (exe.isEmpty()) {
256  return false;
257  }
258 
259  QStringList args;
260  if (shared) {
261  args << "--add";
262  } else {
263  args << "--remove";
264  }
265  args << path;
266  int ec = QProcess::execute(exe, args); // should be ok, the perl script terminates fast
267  //qDebug() << "exitCode=" << ec;
268  bool ok = !ec;
269  switch (ec) {
270  case 1:
271  // User is not authorized
272  break;
273  case 3:
274  // Called script with --add, but path was already shared before.
275  // Result is nevertheless what the client wanted, so
276  // this is alright.
277  ok = true;
278  break;
279  case 4:
280  // Invalid mount point
281  break;
282  case 5:
283  // Called script with --remove, but path was not shared before.
284  // Result is nevertheless what the client wanted, so
285  // this is alright.
286  ok = true;
287  break;
288  case 6:
289  // There is no export method
290  break;
291  case 7:
292  // file sharing is disabled
293  break;
294  case 8:
295  // advanced sharing is enabled
296  break;
297  case 255:
298  // Abitrary error
299  break;
300  }
301 
302  return ok;
303 }
304 
305 #include "moc_kfileshare_p.cpp"
306 
int execute(const QString &program, const QStringList &arguments)
virtual bool atEnd() const const override
QString & append(QChar ch)
static KDirWatch * self()
Common functionality for the file sharing (communication with the backend)
Definition: kfileshare.h:31
void readShareList()
Reads the list of shared folders.
Definition: kfileshare.cpp:193
void addFile(const QString &file)
QByteArray toLower() const const
bool sharingEnabled()
Returns whether sharing is enabled If this is false, file sharing is disabled and nobody can share fi...
Definition: kfileshare.cpp:148
bool isEmpty() const const
QString findExecutable(const QString &executableName, const QStringList &paths)
bool isDirectoryShared(const QString &path)
Call this to know if a directory is currently shared.
Definition: kfileshare.cpp:225
bool setShared(const QString &path, bool shared)
Uses a suid perl script to share the given path with NFS and Samba.
Definition: kfileshare.cpp:246
ShareMode shareMode()
Returns the configured share mode.
Definition: kfileshare.cpp:139
bool isRestricted()
Returns whether file sharing is restricted.
Definition: kfileshare.cpp:157
QString fileShareGroup()
Returns the group that is used for file sharing.
Definition: kfileshare.cpp:166
QList< KUser > users(uint maxCount=KCOREADDONS_UINT_MAX) const
bool isEmpty() const const
bool nfsEnabled()
Returns whether NFS is enabled.
Definition: kfileshare.cpp:184
Authorization authorization()
Call this to know if the current user is authorized to share directories.
Definition: kfileshare.cpp:237
ShareMode
The used share mode.
Definition: kfileshare.h:70
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
void readConfig()
Reads the file share configuration file.
Definition: kfileshare.cpp:108
int length() const const
bool sambaEnabled()
Returns whether Samba is enabled.
Definition: kfileshare.cpp:175
void removeFile(const QString &file)
T readEntry(const QString &key, const T &aDefault) const
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode)
qint64 readLine(char *data, qint64 maxSize)
bool waitForFinished(int msecs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jan 27 2021 22:57:48 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.