mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
357 lines
12 KiB
C++
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"
|