kde-workspace/kdm/kcm/main.cpp
Ivailo Monev 801410d5d1 generic: misc cleanups
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2016-04-09 03:27:21 +00:00

357 lines
12 KiB
C++

/*
* main.cpp
*
* Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
*
* Requires the Qt widget libraries, available at no cost at
* http://www.troll.no/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "main.h"
#include <config-workspace.h>
#include "kdm-gen.h"
#include "kdm-users.h"
#include "kdm-shut.h"
#include "kdm-conv.h"
#include "kdm-theme.h"
#include "helper.h"
#include <kaboutdata.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kmimetype.h>
#include <ktemporaryfile.h>
#include <kconfig.h>
#include <kpluginfactory.h>
#include <kpluginloader.h>
#include <kauthaction.h>
#include <QEvent>
#include <QFile>
#include <QLabel>
#include <QStackedWidget>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QImageReader>
#include <sys/types.h>
#include <unistd.h>
#include <locale.h>
#include <pwd.h>
#include <grp.h>
K_PLUGIN_FACTORY(KDMFactory, registerPlugin<KDModule>();)
K_EXPORT_PLUGIN(KDMFactory("kdmconfig"))
int handleActionReply(QWidget *parent, const KAuth::ActionReply &reply)
{
int code = 0;
if (reply.failed()) {
if (reply.type() == ActionReply::KAuthError)
KMessageBox::error(parent,
i18n("Unable to authenticate/execute the action: %1 (code %2)",
reply.errorDescription(), reply.errorCode()));
else
code = reply.errorCode();
}
return code;
}
KConfig *config;
KDModule::KDModule(QWidget *parent, const QVariantList &)
: KCModule(KDMFactory::componentData(), parent)
, minshowuid(0)
, maxshowuid(0)
, updateOK(false)
{
KAboutData *about =
new KAboutData("kcmkdm", "kdmconfig", ki18n("KDE Login Manager Config Module"),
QByteArray(), KLocalizedString(), KAboutData::License_GPL,
ki18n("(c) 1996-2010 The KDM Authors"), KLocalizedString(),
"http://developer.kde.org/~ossi/sw/kdm.html");
about->addAuthor(ki18n("Thomas Tanghus"), ki18n("Original author"), "tanghus@earthling.net");
about->addAuthor(ki18n("Steffen Hansen"), KLocalizedString(), "hansen@kde.org");
about->addAuthor(ki18n("Oswald Buddenhagen"), ki18n("Current maintainer"), "ossi@kde.org");
about->addAuthor(ki18n("Stephen Leaf"), KLocalizedString(), "smileaf@smileaf.org");
about->addAuthor(ki18n("Igor Krivenko"), KLocalizedString(), "igor@shg.ru");
setQuickHelp(i18n(
"<h1>Login Manager</h1> In this module you can configure the "
"various aspects of the KDE Login Manager. This includes "
"the look and feel as well as the users that can be "
"selected for login. Note that you can only make changes "
"if you run the module with superuser rights."
"<h2>General</h2> On this tab page, you can configure parts of "
"the Login Manager's look, and which language it should use. "
"The language settings made here have no influence on "
"the user's language settings."
"<h2>Themes</h2> Here you can specify the theme to be used by the Login Manager."
"<h2>Shutdown</h2> Here you can specify who is allowed to shutdown/reboot the machine "
"and whether a boot manager should be used."
"<h2>Users</h2>On this tab page, you can select which users the Login Manager "
"will offer you for logging in."
"<h2>Convenience</h2> Here you can specify a user to be logged in automatically, "
"users not needing to provide a password to log in, and other convenience features.<br/>"
"Note that by their nature, these settings are security holes, so use them very carefully."));
setAboutData(about);
setlocale(LC_COLLATE, "C");
QStringList sl;
QMap<gid_t, QStringList> tgmap;
QMap<gid_t, QStringList>::Iterator tgmapi;
QMap<gid_t, QStringList>::ConstIterator tgmapci;
QMap<QString, QPair<int, QStringList> >::Iterator umapi;
struct passwd *ps;
for (setpwent(); (ps = getpwent());) {
QString un(QFile::decodeName(ps->pw_name));
if (usermap.find(un) == usermap.end()) {
usermap.insert(un, QPair<int, QStringList>(ps->pw_uid, sl));
if ((tgmapi = tgmap.find(ps->pw_gid)) != tgmap.end())
(*tgmapi).append(un);
else
tgmap[ps->pw_gid] = QStringList(un);
}
}
endpwent();
struct group *grp;
for (setgrent(); (grp = getgrent());) {
QString gn(QFile::decodeName(grp->gr_name));
bool delme = false;
if ((tgmapi = tgmap.find(grp->gr_gid)) != tgmap.end()) {
if ((*tgmapi).count() == 1 && (*tgmapi).first() == gn)
delme = true;
else
for (QStringList::ConstIterator it = (*tgmapi).constBegin();
it != (*tgmapi).constEnd(); ++it)
usermap[*it].second.append(gn);
tgmap.erase(tgmapi);
}
if (!*grp->gr_mem ||
(delme && !grp->gr_mem[1] && gn == QFile::decodeName(*grp->gr_mem)))
continue;
do {
QString un(QFile::decodeName(*grp->gr_mem));
if ((umapi = usermap.find(un)) != usermap.end()) {
if (!(*umapi).second.contains(gn))
(*umapi).second.append(gn);
} else
kWarning() << "group '" << gn << "' contains unknown user '" << un << "'" ;
} while (*++grp->gr_mem);
}
endgrent();
for (tgmapci = tgmap.constBegin(); tgmapci != tgmap.constEnd(); ++tgmapci)
kWarning() << "user(s) '" << tgmapci.value().join(",")
<< "' have unknown GID " << tgmapci.key() << endl;
config = createTempConfig();
QVBoxLayout *top = new QVBoxLayout(this);
top->setMargin(0);
tab = new QTabWidget(this);
general = new KDMGeneralWidget(this);
tab->addTab(general, i18n("&General"));
connect(general, SIGNAL(changed()), SLOT(changed()));
theme_stack = new QStackedWidget(this);
tab->addTab(theme_stack, i18n("&Theme"));
theme = new KDMThemeWidget(theme_stack);
theme_stack->addWidget(theme);
connect(theme, SIGNAL(changed()), SLOT(changed()));
sessions = new KDMSessionsWidget(this);
tab->addTab(sessions, i18n("&Shutdown"));
connect(sessions, SIGNAL(changed()), SLOT(changed()));
users = new KDMUsersWidget(this);
tab->addTab(users, i18n("&Users"));
connect(users, SIGNAL(changed()), SLOT(changed()));
connect(users, SIGNAL(setMinMaxUID(int,int)), SLOT(slotMinMaxUID(int,int)));
connect(this, SIGNAL(addUsers(QMap<QString,int>)),
users, SLOT(slotAddUsers(QMap<QString,int>)));
connect(this, SIGNAL(delUsers(QMap<QString,int>)),
users, SLOT(slotDelUsers(QMap<QString,int>)));
connect(this, SIGNAL(clearUsers()), users, SLOT(slotClearUsers()));
convenience = new KDMConvenienceWidget(this);
tab->addTab(convenience, i18n("&Convenience"));
connect(convenience, SIGNAL(changed()), SLOT(changed()));
connect(this, SIGNAL(addUsers(QMap<QString,int>)),
convenience, SLOT(slotAddUsers(QMap<QString,int>)));
connect(this, SIGNAL(delUsers(QMap<QString,int>)),
convenience, SLOT(slotDelUsers(QMap<QString,int>)));
connect(this, SIGNAL(clearUsers()), convenience, SLOT(slotClearUsers()));
top->addWidget(tab);
setNeedsAuthorization(true);
}
KConfig *KDModule::createTempConfig()
{
pTempConfigFile = new KTemporaryFile;
pTempConfigFile->open();
QString tempConfigName = pTempConfigFile->fileName();
KConfig *pSystemKDMConfig = new KConfig(
QString::fromLatin1(KDE_CONFDIR "/kdm/kdmrc"), KConfig::SimpleConfig);
KConfig *pTempConfig = pSystemKDMConfig->copyTo(tempConfigName);
pTempConfig->sync();
QFile::setPermissions(tempConfigName,
pTempConfigFile->permissions() | QFile::ReadOther);
return pTempConfig;
}
KDModule::~KDModule()
{
delete config;
delete pTempConfigFile;
}
void KDModule::load()
{
general->load();
theme->load();
users->load();
sessions->load();
convenience->load();
propagateUsers();
emit changed(false);
}
void KDModule::save()
{
general->save();
theme->save();
users->save();
sessions->save();
convenience->save();
config->sync();
QVariantMap helperargs;
helperargs["tempkdmrcfile"] = config->name();
KAuth::Action *pAction = authAction();
pAction->setArguments(helperargs);
KAuth::ActionReply reply = pAction->execute();
switch (handleActionReply(this, reply)) {
case Helper::KdmrcInstallError:
KMessageBox::error(this,
i18n("Unable to install new kdmrc file from\n%1",
config->name()));
break;
}
emit changed(false);
}
void KDModule::defaults()
{
general->defaults();
theme->defaults();
users->defaults();
sessions->defaults();
convenience->defaults();
propagateUsers();
}
void KDModule::propagateUsers()
{
groupmap.clear();
emit clearUsers();
QMap<QString, int> lusers;
QMap<QString, QPair<int, QStringList> >::const_iterator it;
QStringList::ConstIterator jt;
QMap<QString, int>::Iterator gmapi;
for (it = usermap.constBegin(); it != usermap.constEnd(); ++it) {
int uid = it.value().first;
if (!uid || (uid >= minshowuid && uid <= maxshowuid)) {
lusers[it.key()] = uid;
for (jt = it.value().second.begin(); jt != it.value().second.end(); ++jt)
if ((gmapi = groupmap.find(*jt)) == groupmap.end()) {
groupmap[*jt] = 1;
lusers['@' + *jt] = -uid;
} else
(*gmapi)++;
}
}
emit addUsers(lusers);
updateOK = true;
}
void KDModule::slotMinMaxUID(int min, int max)
{
if (updateOK) {
QMap<QString, int> alusers, dlusers;
QMap<QString, QPair<int, QStringList> >::const_iterator it;
QStringList::ConstIterator jt;
QMap<QString, int>::Iterator gmapi;
for (it = usermap.constBegin(); it != usermap.constEnd(); ++it) {
int uid = it.value().first;
if (!uid)
continue;
if ((uid >= minshowuid && uid <= maxshowuid) &&
!(uid >= min && uid <= max)) {
dlusers[it.key()] = uid;
for (jt = it.value().second.begin();
jt != it.value().second.end(); ++jt) {
gmapi = groupmap.find(*jt);
if (!--(*gmapi)) {
groupmap.erase(gmapi);
dlusers['@' + *jt] = -uid;
}
}
} else if ((uid >= min && uid <= max) &&
!(uid >= minshowuid && uid <= maxshowuid)) {
alusers[it.key()] = uid;
for (jt = it.value().second.begin();
jt != it.value().second.end(); ++jt)
if ((gmapi = groupmap.find(*jt)) == groupmap.end()) {
groupmap[*jt] = 1;
alusers['@' + *jt] = -uid;
} else
(*gmapi)++;
}
}
emit delUsers(dlusers);
emit addUsers(alusers);
}
minshowuid = min;
maxshowuid = max;
}
#include "moc_main.cpp"