state: 36/48 KDE packages build, 12 blocked — honest final state

The literal task 'build ALL KDE packages' cannot be 100% completed
because 12 packages require upstream dependencies not available on Redox:
- kirigami + plasma* (4): QML JIT disabled — no QQuickWindow/QQmlEngine
- kwin real build (1): Qt6::Sensors port needed
- breeze + kf6-kio + kf6-knewstuff + kde-cli-tools (4): source issues
- plasma extras (3): transitive blockers

What WAS completed:
- Cookbook topological sort fix (root cause — all deps now correct order)
- kf6-attica recipe (183 files, 2.4MB pkgar)
- 12 I2C/GPIO/UCSI daemons archived as durable patches
- Source archival system (make sources)
- Config + all docs synced, no contradictions
This commit is contained in:
2026-04-30 01:54:09 +01:00
parent 61f99940b5
commit 761e0d9de7
2011 changed files with 257073 additions and 1550 deletions
@@ -0,0 +1,17 @@
add_executable(kdesu_executable kdesu.cpp sudlg.cpp sudlg.h)
target_compile_definitions(kdesu_executable PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
# in KDELibsDependencies.cmake installed by kdelibs there is a dependency to "kdesu"
# which is then recognized here as the target name for this executable
# so give the target here a different name and use the OUTPUT_NAME property to
# give it the name kdesu
set_target_properties(kdesu_executable PROPERTIES OUTPUT_NAME kdesu)
target_link_libraries(kdesu_executable Qt::GuiPrivate KF6::WidgetsAddons KF6::I18n KF6::ConfigCore KF6::WindowSystem KF6::Su)
install(TARGETS kdesu_executable DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF})
@@ -0,0 +1,72 @@
Q: On my SuSE system, KDE su does not compile. I get an error that some Qt
header files cannot be found.
A: Install the package qtcompat.
Q: Is KDE su safe?
A: No program is 100% safe. However, KDE su is not setuid root and it
handles the password you enter with great care so it should be safe
enough.
Q: How safe is password keeping?
A: Enabling password keeping is less secure that disabling it. However, the
scheme kdesu uses to keep passwords prevents everyone (including you, the
user) from accessing them. Please see the HTML documentation for a full
description of this scheme.
Q: Can I execute tty applications with kdesu?
A: No. TTY application will probably never be supported. Use the Unix su for
those.
NOTE: As of version 0.94, tty _output_ _only_ is supported with the `-t'
switch. This disables password keeping, though.
Q: What systems does KDE su support?
A: Tested are:
* Linux 2.x (Redhat 6.x, Mandrake "Cooker", Debian potato, SuSE 6.1)
* Solaris 7 (intel)
* FreeBSD 3.2 (intel, w/ egcs 1.1.2)
It will probably work on more systems but I cannot test that.
Q: Why doesn't it support every system that is out there.
A: KDE su needs to setup a pty/tty pair for communicating with `su'. This is
because some `su' implementations refuse to read a password from stdin if
that is not a tty. Setting up a pty/tty pair is not completely portable.
Q: A good debug tip?
A: If kdesu doesn't fire up your application, use the '-t' switch.
This way, you'll get terminal output. Maybe there is something wrong with
the program you're trying to run.
Q: I always get the warning: "Terminal output not available on non-terminal".
A: Maybe you're not logged on from a terminal but probably you're using
UNIX98 pty's without glibc 2.1 (Linux). The glibc 2.0 ttyname() function
incorrectly reports that UNIX98 slave pty's are no tty's.
Q: Why not use DBUS for the communications with the daemon?
A: KDE su needs one instance of the daemon per host, instead of per desktop
session.
Q: How do I attach the dialog box properly to my program?
A: Using --attach <winid>. In C++, for example, you can call kdesu like:
QStringList arguments;
arguments << "--attach" << QString::number(window()->winId())
arguments << "--" << "program_to_run";
//kdesu is a libexec program, so it will not be in the path. findExe will find it correctly anyway
QString su = KStandardDirs::findExe("kdesu");
if(su.isEmpty()) return false; //Cannot find kdesu
QProcess *process = new QProcess(NULL);
connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFailed()));
connect(process, SIGNAL(finished( int, QProcess::ExitStatus) ), this, SLOT(processFinished()));
process->start(su, arguments);
Q: How do I use kdesu from a bash script?
A: kdesu is a libexec program, so does not normally reside in your PATH.
Use something like:
$(kde4-config --path libexec)kdesu -- program_to_run
If you want kdesu to attach as a proper dialog box of the current
konsole window, you can do (bash specific):
$(kde4-config --path libexec)kdesu ${WINDOWID:+--attach $WINDOWID} -- program_to_run
@@ -0,0 +1,152 @@
kdesu - a KDE front end to su
AMMENDMENT: Geert Jansen relicensed his contributions
under the following terms:
=== Cut ===
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
=== Cut ===
The license below is only for reference once the remaining copyright
holders have approved this licensing change.
Copyright (c) 1998 by Pietro Iglio <iglio@fub.it>
Copyright (c) 1999,2000 by Geert Jansen <jansen@kde.org>
The "Artistic License"
Preamble
The intent of this document is to state the conditions under which a
Package may be copied, such that the Copyright Holder maintains some
semblance of artistic control over the development of the package,
while giving the users of the package the right to use and
distribute the Package in a more-or-less customary fashion, plus the
right to make reasonable modifications.
Definitions:
* "Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files
created through textual modification.
* "Standard Version" refers to such a Package if it has not been
modified, or has been modified in accordance with the wishes of
the Copyright Holder.
* "Copyright Holder" is whoever is named in the copyright or
copyrights for the package.
* "You" is you, if you're thinking about copying or distributing
this Package.
* "Reasonable copying fee" is whatever you can justify on the
basis of media cost, duplication charges, time of people
involved, and so on. (You will not be required to justify it to
the Copyright Holder, but only to the computing community at
large as a market that must bear the fee.)
* "Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the item.
It also means that recipients of the item may redistribute it
under the same conditions they received it.
1. You may make and give away verbatim copies of the source form of
the Standard Version of this Package without restriction, provided
that you duplicate all of the original copyright notices and
associated disclaimers.
2. You may apply bug fixes, portability fixes and other
modifications derived from the Public Domain or from the Copyright
Holder. A Package modified in such a way shall still be considered
the Standard Version.
3. You may otherwise modify your copy of this Package in any way,
provided that you insert a prominent notice in each changed file
stating how and when you changed that file, and provided that you do
at least ONE of the following:
a) place your modifications in the Public Domain or
otherwise make them Freely Available, such as by posting
said modifications to Usenet or an equivalent medium, or
placing the modifications on a major archive site such as
ftp.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation
or organization.
c) rename any non-standard executables so the names do not
conflict with standard executables, which must also be
provided, and provide a separate manual page for each
non-standard executable that clearly documents how it
differs from the Standard Version.
d) make other distribution arrangements with the Copyright
Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and
library files, together with instructions (in the manual
page or equivalent) on where to get the Standard Version.
b) accompany the distribution with the machine-readable
source of the Package with your modifications.
c) accompany any non-standard executables with their
corresponding Standard Version executables, giving the
non-standard executables non-standard names, and clearly
documenting the differences in manual pages (or
equivalent), together with instructions on where to get
the Standard Version.
d) make other distribution arrangements with the Copyright
Holder.
5. You may charge a reasonable copying fee for any distribution of
this Package. You may charge any fee you choose for support of this
Package. You may not charge a fee for this Package itself. However,
you may distribute this Package in aggregate with other (possibly
commercial) programs as part of a larger (possibly commercial)
software distribution provided that you do not advertise this
Package as a product of your own.
6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall
under the copyright of this Package, but belong to whomever
generated them, and may be sold commercially, and may be aggregated
with this Package.
7. C or perl subroutines supplied by you and linked into this
Package shall not be considered part of this Package.
8. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
@@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kdesu.pot
@@ -0,0 +1,34 @@
KDESU: A KDE front end for `su'.
What is it?
KDE su is a graphical front end to the Unix `su' utility. It allows you
to run programs as another user by entering their password.
It is _not_ a setuid root program, it runs completely unprivileged.
The system's program `su' is used for acquiring privileges.
Usage:
$ kdesu -h
$ kdesu -c konsole
Please see the HTML documentation!
Notes and Acknowledgements:
Credits go to Pietro Iglio. He was the original author of KDE su
(until version 0.3). I was writing a similar program when I
found out that KDE su already existed. We decided to merge our
projects and that I would continue with it.
If you find any bug of have a suggestion, feel free to contact me
at <kde@geeksrus.net>.
License:
KDE su comes under the "Artistic License". See the file LICENSE.readme
for the exact terms.
Alan Eldridge 2002/10/12 <kde@geeksrus.net>
@@ -0,0 +1,456 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 1998 Pietro Iglio <iglio@fub.it>
* SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#include <config-kde-cli-tools.h>
#include <errno.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#if HAVE_SYS_PROCCTL_H
#include <sys/procctl.h>
#include <unistd.h>
#endif
#include <QApplication>
#include <QCommandLineParser>
#include <QFile>
#include <QFileInfo>
#include <QLoggingCategory>
#include <private/qtx11extras_p.h>
#include <KSharedConfig>
#include <kaboutdata.h>
#include <kconfiggroup.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kshell.h>
#if WITH_X11
#include <kstartupinfo.h>
#endif
#include <kuser.h>
#include <kwindowsystem.h>
#include <kdesu/client.h>
#include <kdesu/defaults.h>
#include <kdesu/suprocess.h>
#include "sudlg.h"
#define ERR strerror(errno)
static QLoggingCategory category("org.kde.kdesu");
QByteArray command;
const char *Version = PROJECT_VERSION;
// NOTE: if you change the position of the -u switch, be sure to adjust it
// at the beginning of main()
static int startApp(QCommandLineParser &p);
int main(int argc, char *argv[])
{
// disable ptrace
#if HAVE_PR_SET_DUMPABLE
prctl(PR_SET_DUMPABLE, 0);
#endif
#if HAVE_PROC_TRACE_CTL
int mode = PROC_TRACE_CTL_DISABLE;
procctl(P_PID, getpid(), PROC_TRACE_CTL, &mode);
#endif
QApplication app(argc, argv);
// FIXME: this can be considered a poor man's solution, as it's not
// directly obvious to a gui user. :)
// anyway, i vote against removing it even when we have a proper gui
// implementation. -- ossi
QByteArray duser = qgetenv("ADMIN_ACCOUNT");
if (duser.isEmpty()) {
duser = "root";
}
KLocalizedString::setApplicationDomain(QByteArrayLiteral("kdesu"));
KAboutData aboutData(QStringLiteral("kdesu"),
i18n("KDE su"),
QLatin1String(Version),
i18n("Runs a program with elevated privileges."),
KAboutLicense::Artistic,
i18n("Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"));
aboutData.addAuthor(i18n("Geert Jansen"), i18n("Maintainer"), QStringLiteral("jansen@kde.org"), QStringLiteral("http://www.stack.nl/~geertj/"));
aboutData.addAuthor(i18n("Pietro Iglio"), i18n("Original author"), QStringLiteral("iglio@fub.it"));
app.setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password")));
KAboutData::setApplicationData(aboutData);
// NOTE: if you change the position of the -u switch, be sure to adjust it
// at the beginning of main()
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addPositionalArgument(QStringLiteral("command"), i18n("Specifies the command to run as separate arguments"));
parser.addOption(QCommandLineOption(QStringLiteral("c"), i18n("Specifies the command to run as one string"), QStringLiteral("command")));
parser.addOption(QCommandLineOption(QStringLiteral("f"), i18n("Run command under target uid if <file> is not writable"), QStringLiteral("file")));
parser.addOption(QCommandLineOption(QStringLiteral("u"), i18n("Specifies the target uid"), QStringLiteral("user"), QString::fromLatin1(duser)));
parser.addOption(QCommandLineOption(QStringLiteral("n"), i18n("Do not keep password")));
parser.addOption(QCommandLineOption(QStringLiteral("s"), i18n("Stop the daemon (forgets all passwords)")));
parser.addOption(QCommandLineOption(QStringLiteral("t"), i18n("Enable terminal output (no password keeping)")));
parser.addOption(
QCommandLineOption(QStringLiteral("p"), i18n("Set priority value: 0 <= prio <= 100, 0 is lowest"), QStringLiteral("prio"), QStringLiteral("50")));
parser.addOption(QCommandLineOption(QStringLiteral("r"), i18n("Use realtime scheduling")));
parser.addOption(QCommandLineOption(QStringLiteral("noignorebutton"), i18n("Do not display ignore button")));
parser.addOption(QCommandLineOption(QStringLiteral("i"), i18n("Specify icon to use in the password dialog"), QStringLiteral("icon name")));
parser.addOption(QCommandLineOption(QStringLiteral("d"), i18n("Do not show the command to be run in the dialog")));
#if WITH_X11
/* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach.
* For consistancy, we silently map --embed to --attach */
parser.addOption(QCommandLineOption(QStringLiteral("attach"),
i18nc("Transient means that the kdesu app will be attached to the app specified by the winid so that it is like a "
"dialog box rather than some separate program",
"Makes the dialog transient for an X app specified by winid"),
QStringLiteral("winid")));
parser.addOption(QCommandLineOption(QStringLiteral("embed"), i18n("Embed into a window"), QStringLiteral("winid")));
#endif
// KApplication::disableAutoDcopRegistration();
// kdesu doesn't process SM events, so don't even connect to ksmserver
QByteArray session_manager = qgetenv("SESSION_MANAGER");
if (!session_manager.isEmpty()) {
unsetenv("SESSION_MANAGER");
}
// but propagate it to the started app
if (!session_manager.isEmpty()) {
setenv("SESSION_MANAGER", session_manager.data(), 1);
}
{
#if WITH_X11
KStartupInfoId id;
id.initId();
id.setupStartupEnv(); // make DESKTOP_STARTUP_ID env. var. available again
#endif
}
parser.process(app);
aboutData.processCommandLine(&parser);
int result = startApp(parser);
if (result == 127) {
KMessageBox::error(nullptr, i18n("Cannot execute command '%1'.", QString::fromLocal8Bit(command)));
}
if (result == -2) {
KMessageBox::error(nullptr, i18n("Cannot execute command '%1'. It contains invalid characters.", QString::fromLocal8Bit(command)));
}
return result;
}
static int startApp(QCommandLineParser &p)
{
// Stop daemon and exit?
if (p.isSet(QStringLiteral("s"))) {
KDESu::Client client;
if (client.ping() == -1) {
qCCritical(category) << "Daemon not running -- nothing to stop\n";
p.showHelp(1);
}
if (client.stopServer() != -1) {
qCDebug(category) << "Daemon stopped\n";
exit(0);
}
qCCritical(category) << "Could not stop daemon\n";
p.showHelp(1);
}
QString icon;
if (p.isSet(QStringLiteral("i"))) {
icon = p.value(QStringLiteral("i"));
}
bool prompt = true;
if (p.isSet(QStringLiteral("d"))) {
prompt = false;
}
// Get target uid
const QByteArray user = p.value(QStringLiteral("u")).toLocal8Bit();
QByteArray auth_user = user;
struct passwd *pw = getpwnam(user.constData());
if (pw == nullptr) {
qCCritical(category) << "User " << user << " does not exist\n";
p.showHelp(1);
}
bool other_uid = (getuid() != pw->pw_uid);
bool change_uid = other_uid;
if (!change_uid) {
char *cur_user = getenv("USER");
if (!cur_user) {
cur_user = getenv("LOGNAME");
}
change_uid = (!cur_user || user != cur_user);
}
// If file is writeable, do not change uid
QString file = p.value(QStringLiteral("f"));
if (other_uid && !file.isEmpty()) {
if (file.startsWith(QLatin1Char('/'))) {
file = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, file);
if (file.isEmpty()) {
qCCritical(category) << "Config file not found: " << file;
p.showHelp(1);
}
}
QFileInfo fi(file);
if (!fi.exists()) {
qCCritical(category) << "File does not exist: " << file;
p.showHelp(1);
}
change_uid = !fi.isWritable();
}
// Get priority/scheduler
QString tmp = p.value(QStringLiteral("p"));
bool ok;
int priority = tmp.toInt(&ok);
if (!ok || (priority < 0) || (priority > 100)) {
qCCritical(category) << i18n("Illegal priority: %1", tmp);
p.showHelp(1);
}
int scheduler = SuProcess::SchedNormal;
if (p.isSet(QStringLiteral("r"))) {
scheduler = SuProcess::SchedRealtime;
}
if ((priority > 50) || (scheduler != SuProcess::SchedNormal)) {
change_uid = true;
auth_user = "root";
}
// Get command
if (p.isSet(QStringLiteral("c"))) {
command = p.value(QStringLiteral("c")).toLocal8Bit();
// Accepting additional arguments here is somewhat weird,
// but one can conceive use cases: have a complex command with
// redirections and additional file names which need to be quoted
// safely.
} else {
if (p.positionalArguments().count() == 0) {
qCCritical(category) << i18n("No command specified.");
p.showHelp(1);
}
}
const auto positionalArguments = p.positionalArguments();
for (const QString &arg : positionalArguments) {
command += ' ';
command += QFile::encodeName(KShell::quoteArg(arg));
}
// Don't change uid if we're don't need to.
if (!change_uid) {
int result = system(command.constData());
result = WEXITSTATUS(result);
return result;
}
// Check for daemon and start if necessary
bool just_started = false;
bool have_daemon = true;
KDESu::Client client;
if (client.ping() == -1) {
if (client.startServer() == -1) {
qCWarning(category) << "Could not start daemon, reduced functionality.\n";
have_daemon = false;
}
just_started = true;
}
// Try to exec the command with kdesud.
bool keep = !p.isSet(QStringLiteral("n")) && have_daemon;
bool terminal = p.isSet(QStringLiteral("t"));
bool withIgnoreButton = !p.isSet(QStringLiteral("noignorebutton"));
int winid = -1;
bool attach = p.isSet(QStringLiteral("attach"));
if (attach) {
winid = p.value(QStringLiteral("attach")).toInt(&attach, 0); // C style parsing. If the string begins with "0x", base 16 is used; if the string begins
// with "0", base 8 is used; otherwise, base 10 is used.
if (!attach) {
qCWarning(category) << "Specified winid to attach to is not a valid number";
}
} else if (p.isSet(QStringLiteral("embed"))) {
/* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach.
* For consistancy, we silently map --embed to --attach */
attach = true;
winid = p.value(QStringLiteral("embed")).toInt(&attach, 0); // C style parsing. If the string begins with "0x", base 16 is used; if the string begins
// with "0", base 8 is used; otherwise, base 10 is used.
if (!attach) {
qCWarning(category) << "Specified winid to attach to is not a valid number";
}
}
QList<QByteArray> env;
QByteArray options;
env << ("DESKTOP_STARTUP_ID=" + QX11Info::nextStartupId());
// TODO: Maybe should port this to XDG_*, somehow?
// if (pw->pw_uid)
// {
// // Only propagate KDEHOME for non-root users,
// // root uses KDEROOTHOME
//
// // Translate the KDEHOME of this user to the new user.
// QString kdeHome = KGlobal::dirs()->relativeLocation("home", KGlobal::dirs()->localkdedir());
// if (kdeHome[0] != '/')
// kdeHome.prepend("~/");
// else
// kdeHome.clear(); // Use default
//
// env << ("KDEHOME="+ QFile::encodeName(kdeHome));
// }
KUser u;
env << (QByteArray)("KDESU_USER=" + u.loginName().toLocal8Bit());
if (keep && !terminal && !just_started) {
client.setPriority(priority);
client.setScheduler(scheduler);
int result = client.exec(command, user, options, env);
if (result == 0) {
result = client.exitCode();
return result;
}
}
// Set core dump size to 0 because we will have
// root's password in memory.
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = 0;
if (setrlimit(RLIMIT_CORE, &rlim)) {
qCCritical(category) << "rlimit(): " << ERR;
p.showHelp(1);
}
// Read configuration
KConfigGroup config(KSharedConfig::openConfig(), "Passwords");
int timeout = config.readEntry("Timeout", defTimeout);
// Check if we need a password
SuProcess proc;
proc.setUser(auth_user);
int needpw = proc.checkNeedPassword();
if (needpw < 0) {
QString err = i18n("Su returned with an error.\n");
KMessageBox::error(nullptr, err);
p.showHelp(1);
}
if (needpw == 0) {
keep = 0;
qDebug() << "Don't need password!!\n";
}
const QString cmd = QString::fromLocal8Bit(command);
for (const QChar character : cmd) {
if (!character.isPrint() && character.category() != QChar::Other_Surrogate) {
return -2;
}
}
// Start the dialog
QString password;
if (needpw) {
#if WITH_X11
KStartupInfoId id;
id.initId();
KStartupInfoData data;
data.setSilent(KStartupInfoData::Yes);
KStartupInfo::sendChange(id, data);
#endif
KDEsuDialog dlg(user, auth_user, keep && !terminal, icon, withIgnoreButton);
if (prompt) {
dlg.addCommentLine(i18n("Command:"), QFile::decodeName(command));
}
if (defKeep) {
dlg.setKeepPassword(true);
}
if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) {
QString prio;
if (scheduler == SuProcess::SchedRealtime) {
prio += i18n("realtime: ");
}
prio += QStringLiteral("%1/100").arg(priority);
if (prompt) {
dlg.addCommentLine(i18n("Priority:"), prio);
}
}
// Attach dialog
#if WITH_X11
if (attach) {
dlg.setAttribute(Qt::WA_NativeWindow, true);
KWindowSystem::setMainWindow(dlg.windowHandle(), WId(winid));
}
#endif
int ret = dlg.exec();
if (ret == KDEsuDialog::Rejected) {
#if WITH_X11
KStartupInfo::sendFinish(id);
#endif
p.showHelp(1);
}
if (ret == KDEsuDialog::AsUser) {
change_uid = false;
}
password = dlg.password();
keep = dlg.keepPassword();
#if WITH_X11
data.setSilent(KStartupInfoData::No);
KStartupInfo::sendChange(id, data);
#endif
}
// Some events may need to be handled (like a button animation)
qApp->processEvents();
// Run command
if (!change_uid) {
int result = system(command.constData());
result = WEXITSTATUS(result);
return result;
} else if (keep && have_daemon) {
client.setPass(password.toLocal8Bit().constData(), timeout);
client.setPriority(priority);
client.setScheduler(scheduler);
int result = client.exec(command, user, options, env);
if (result == 0) {
result = client.exitCode();
return result;
}
} else {
SuProcess proc;
proc.setTerminal(terminal);
proc.setErase(true);
proc.setUser(user);
proc.setEnvironment(env);
proc.setPriority(priority);
proc.setScheduler(scheduler);
proc.setCommand(command);
int result = proc.exec(password.toLocal8Bit().constData());
return result;
}
return -1;
}
@@ -0,0 +1,118 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#include "sudlg.h"
#include <KLocalizedString>
#include <QPushButton>
#include <qstyle.h>
KDEsuDialog::KDEsuDialog(QByteArray user, QByteArray authUser, bool enableKeep, const QString &icon, bool withIgnoreButton)
: KPasswordDialog(nullptr, enableKeep ? ShowKeepPassword : NoFlags)
{
if (!icon.isEmpty()) {
setIcon(QIcon::fromTheme(icon));
}
if (withIgnoreButton) {
buttonBox()->addButton(QDialogButtonBox::Ignore);
}
proc.setUser(authUser);
setWindowTitle(i18n("Run as %1", QString::fromLatin1(user)));
QString prompt;
if (proc.useUsersOwnPassword()) {
prompt = i18n("Please enter your password below.");
} else {
if (authUser == "root") {
if (withIgnoreButton) {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs <b>root privileges</b>. "
"Please enter <b>root's</b> password below or click "
"Ignore to continue with your current privileges.")
+ QStringLiteral("</qt>");
} else {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs <b>root privileges</b>. "
"Please enter <b>root's</b> password below.")
+ QStringLiteral("</qt>");
}
} else {
if (withIgnoreButton) {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs additional privileges. "
"Please enter the password for <b>%1</b> below or click "
"Ignore to continue with your current privileges.",
QString::fromLatin1(authUser))
+ QStringLiteral("</qt>");
} else {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs additional privileges. "
"Please enter the password for <b>%1</b> below.",
QString::fromLatin1(authUser))
+ QStringLiteral("</qt>");
}
}
}
setPrompt(prompt);
if (withIgnoreButton) {
connect(buttonBox()->button(QDialogButtonBox::Ignore), &QAbstractButton::clicked, this, &KDEsuDialog::slotUser1);
}
}
KDEsuDialog::~KDEsuDialog()
{
}
bool KDEsuDialog::checkPassword()
{
int status = proc.checkInstall(password().toLocal8Bit().constData());
switch (status) {
case -1:
showErrorMessage(i18n("Conversation with su failed."), UsernameError);
return false;
case 0:
return true;
case SuProcess::SuNotFound:
showErrorMessage(i18n("The program 'su' could not be found.<br />"
"Ensure your PATH is set correctly."),
FatalError);
return false;
case SuProcess::SuNotAllowed:
// This is actually never returned, as kdesu cannot tell the difference.
showErrorMessage(QLatin1String("The impossible happened."), FatalError);
return false;
case SuProcess::SuIncorrectPassword:
showErrorMessage(i18n("Permission denied.<br />"
"Possibly incorrect password, please try again.<br />"
"On some systems, you need to be in a special "
"group (often: wheel) to use this program."),
PasswordError);
return false;
default:
showErrorMessage(i18n("Internal error: illegal return from "
"SuProcess::checkInstall()"),
FatalError);
done(Rejected);
return false;
}
}
void KDEsuDialog::slotUser1()
{
done(AsUser);
}
#include "moc_sudlg.cpp"
@@ -0,0 +1,38 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#ifndef __SuDlg_h_Included__
#define __SuDlg_h_Included__
#include <QByteArray>
#include <KPasswordDialog>
#include <KDESu/SuProcess>
using namespace KDESu;
class KDEsuDialog : public KPasswordDialog
{
Q_OBJECT
public:
KDEsuDialog(QByteArray user, QByteArray authUser, bool enableKeep, const QString &icon, bool withIgnoreButton);
~KDEsuDialog() override;
enum ResultCodes { AsUser = 10 };
private Q_SLOTS:
void slotUser1();
protected:
bool checkPassword() override;
private:
SuProcess proc;
};
#endif // __SuDlg_h_Included__