4
* Copyright (C) 2010 Igor Krivenko <igor@shg.ru>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
A helper that's run using KAuth and does the system modifications.
30
#include <config-workspace.h>
35
#include <KConfigGroup>
36
#include <KStandardDirs>
38
bool secureCopy(const QString &from, const QString &to)
41
if (!srcFile.open(QIODevice::ReadOnly))
44
// Security check: we don't want to expose contents of files like /etc/shadow
45
if (!(srcFile.permissions() & QFile::ReadOther))
49
if (!dstFile.open(QIODevice::WriteOnly))
52
const quint64 maxBlockSize = 102400;
53
while (!srcFile.atEnd())
54
if (dstFile.write(srcFile.read(maxBlockSize)) == -1)
57
if (!dstFile.setPermissions(
58
QFile::WriteUser | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther))
64
bool createDir(const QString &path)
67
return (testDir.exists()) || (testDir.mkpath(path));
70
bool removeDirTree(const QString &rootDir)
73
foreach (const QFileInfo &entry, dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot))
75
removeDirTree(entry.absoluteFilePath());
77
dir.remove(entry.fileName());
79
return dir.rmdir(rootDir);
82
bool installDirTree(const QString &srcRootDir, const QString &dstRootDir)
84
QDir srcDir(srcRootDir);
85
QDir dstDir(dstRootDir);
87
if (!dstDir.mkdir(dstRootDir))
90
if (!QFile::setPermissions(dstRootDir,
91
QFile::WriteUser | QFile::ReadUser | QFile::ExeUser |
92
QFile::ReadGroup | QFile::ExeGroup |
93
QFile::ReadOther | QFile::ExeOther))
97
foreach (const QFileInfo &entry, srcDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
98
QString srcFilePath = entry.absoluteFilePath();
99
QString dstFilePath = dstDir.absolutePath() + '/' + entry.fileName();
102
if (!installDirTree(srcFilePath, dstFilePath))
105
if (!secureCopy(srcFilePath, dstFilePath))
112
ActionReply Helper::createReply(int code, const QVariantMap *returnData)
117
reply = ActionReply::HelperError;
118
reply.setErrorCode(code);
120
reply = ActionReply::SuccessReply;
124
reply.setData(*returnData);
129
ActionReply Helper::save(const QVariantMap &args)
131
QString tempConfigName = args.value("tempkdmrcfile").toString();
132
QString tempBackgroundConfigName = args.value("tempbackgroundrcfile").toString();
134
QString systemConfigName = QString::fromLatin1(KDE_CONFDIR "/kdm/kdmrc");
135
QString systemBackgroundConfigName = KConfig(systemConfigName, KConfig::SimpleConfig)
136
.group("X-*-Greeter").readEntry("BackgroundCfg", KDE_CONFDIR "/kdm/backgroundrc");
140
if (!secureCopy(tempConfigName, systemConfigName))
141
code |= KdmrcInstallError;
142
if (!secureCopy(tempBackgroundConfigName, systemBackgroundConfigName))
143
code |= BackgroundrcInstallError;
145
return createReply(code);
148
bool Helper::removeFace(const QString &facesDir, const QString &user)
151
if (user.contains('/'))
154
return QFile::remove(facesDir + user + ".face.icon");
157
bool Helper::installFace(const QString &facesDir, const QString &user, const QString &sourceFile)
160
if (user.contains('/'))
163
return secureCopy(sourceFile, facesDir + user + ".face.icon");
166
ActionReply Helper::managefaces(const QVariantMap &args)
168
int subaction = args.value("subaction").toInt();
170
KConfig(QString::fromLatin1(KDE_CONFDIR "/kdm/kdmrc"), KConfig::SimpleConfig)
171
.group("X-*-Greeter").readEntry("FaceDir",
172
KStandardDirs::installPath("data") + "kdm/faces") + '/';
178
code = (createDir(facesDir) ? 0 : CreateFacesDirError);
181
code = (removeFace(facesDir, args.value("user").toString())
182
? 0 : RemoveFaceError);
185
code = (installFace(facesDir,
186
args.value("user").toString(),
187
args.value("sourcefile").toString())
188
? 0 : InstallFaceError);
191
return ActionReply::HelperError;
194
return createReply(code);
197
bool Helper::removeThemes(const QString &themesDir, QStringList &themes)
199
QDir testDir(themesDir);
200
if (!testDir.exists())
204
for (QStringList::iterator theme = themes.begin(); theme < themes.end(); ++theme) {
205
QFileInfo info(*theme);
207
if (info.absoluteDir() != QDir(themesDir) || !info.exists()) {
212
if (removeDirTree(info.absoluteFilePath()))
221
bool Helper::installThemes(const QString &themesDir, QStringList &themes)
223
QDir testDir(themesDir);
224
if (!testDir.exists())
228
for (QStringList::iterator theme = themes.begin(); theme < themes.end(); ) {
229
QFileInfo info(*theme);
231
if (!info.exists()) {
237
if (installDirTree(info.absoluteFilePath(), themesDir + info.fileName() + '/')) {
238
theme = themes.erase(theme);
248
ActionReply Helper::managethemes(const QVariantMap &args)
250
int subaction = args.value("subaction").toInt();
251
QString themesDir = KStandardDirs::installPath("data") + "kdm/themes/";
256
case CreateThemesDir:
257
code = (createDir(themesDir) ? 0 : CreateThemesDirError);
258
return createReply(code);
260
QStringList themes = args.value("themes").toStringList();
261
code = (removeThemes(themesDir, themes) ? 0 : RemoveThemesError);
263
QVariantMap returnData;
264
returnData["themes"] = themes;
265
return createReply(code, &returnData);
267
case InstallThemes: {
268
QStringList themes = args.value("themes").toStringList();
269
code = (installThemes(themesDir, themes) ? 0 : InstallThemesError);
271
QVariantMap returnData;
272
returnData["failedthemes"] = themes;
273
return createReply(code, &returnData);
276
return ActionReply::HelperError;
280
KDE4_AUTH_HELPER_MAIN("org.kde.kcontrol.kcmkdm", Helper)