KDESu
13 #include "suprocess.h"
15 #include "kcookie_p.h"
16 #include "stubprocess_p.h"
17 #include <ksu_debug.h>
20 #include <QStandardPaths>
21 #include <qplatformdefs.h>
24 #include <KConfigGroup>
25 #include <KSharedConfig>
28 #if defined(KDESU_USE_SUDO_DEFAULT)
29 #define DEFAULT_SUPER_USER_COMMAND QStringLiteral("sudo")
30 #elif defined(KDESU_USE_DOAS_DEFAULT)
31 #define DEFAULT_SUPER_USER_COMMAND QStringLiteral("doas")
33 #define DEFAULT_SUPER_USER_COMMAND QStringLiteral("su")
38 using namespace KDESuPrivate;
40 class SuProcessPrivate :
public StubProcessPrivate
43 bool isPrivilegeEscalation()
const;
47 bool SuProcessPrivate::isPrivilegeEscalation()
const
53 : StubProcess(*new SuProcessPrivate)
62 d->superUserCommand = group.readEntry(
"super-user-command", DEFAULT_SUPER_USER_COMMAND);
64 if (!d->isPrivilegeEscalation() && d->superUserCommand !=
QLatin1String(
"su")) {
65 qCWarning(KSU_LOG) <<
"unknown super user command.";
66 d->superUserCommand = DEFAULT_SUPER_USER_COMMAND;
70 SuProcess::~SuProcess() =
default;
76 return d->superUserCommand;
83 if (d->isPrivilegeEscalation() && m_user ==
"root") {
93 return exec(password, Install);
98 return exec(
nullptr, NeedPassword);
104 int SuProcess::exec(
const char *password,
int check)
115 d->superUserCommand = QStringLiteral(
"su");
119 if (d->isPrivilegeEscalation()) {
123 if (m_scheduler != SchedNormal || m_priority > 50) {
135 const QString defaultPath = QStringLiteral(KDE_INSTALL_FULL_LIBEXECDIR_KF) + QStringLiteral(
"/kdesu_stub");
136 const QString kdesuStubPath = group.readEntry(
"kdesu_stub_path", defaultPath);
143 return check ? SuNotFound : -1;
147 return check ? SuNotFound : -1;
150 SuErrors ret = (SuErrors)converseSU(password);
154 qCCritical(KSU_LOG) <<
"[" << __FILE__ <<
":" << __LINE__ <<
"] "
155 <<
"Conversation with" << d->superUserCommand <<
"failed.";
159 if (check == NeedPassword) {
161 if (d->isPrivilegeEscalation()) {
165 if (kill(
m_pid, SIGKILL) < 0) {
181 memset(
const_cast<char *
>(password), 0, qstrlen(password));
185 kill(
m_pid, SIGKILL);
186 if (d->isPrivilegeEscalation()) {
189 return SuIncorrectPassword;
195 qCCritical(KSU_LOG) <<
"[" << __FILE__ <<
":" << __LINE__ <<
"] "
196 <<
"Conversation with kdesu_stub failed.";
199 }
else if (iret == 1) {
200 kill(
m_pid, SIGKILL);
202 return SuIncorrectPassword;
205 if (check == Install) {
218 int SuProcess::converseSU(
const char *password)
224 } state = WaitForPrompt;
233 if ((line.
contains(
':') && state != WaitForPrompt) || line.
isNull()) {
234 return (state == HandleStub ? notauthorized : error);
237 if (line ==
"kdesu_stub") {
243 case WaitForPrompt: {
252 const uint len = line.
length();
254 for (i = 0, j = 0, colon = 0; i < len; ++i) {
255 if (line[i] ==
':') {
260 if (!isspace(line[i])) {
264 if (colon == 1 && line[j] ==
':') {
265 if (password ==
nullptr) {
271 write(
fd(), password, strlen(password));
272 write(
fd(),
"\n", 1);
284 const bool starCond = std::any_of(s.
cbegin(), s.
cend(), [](
const char c) {
bool isNull() const const
QString fromUtf8(const char *str, int size)
int converseStub(int check)
Exchange all parameters with kdesu_stub.
static int waitMS(int fd, int ms)
Wait ms milliseconds (ie.
QByteArray trimmed() const const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString findExecutable(const QString &executableName, const QStringList &paths)
int checkNeedPassword()
Checks if a password is needed.
QByteArray readLine(bool block=true)
Reads a line from the program's standard out.
int exec(const QByteArray &command, const QList< QByteArray > &args)
Forks off and execute a command.
int waitForChild()
Waits for the child to exit.
QByteArray::const_iterator cend() const const
int waitSlave()
Waits until the pty has cleared the ECHO flag.
int m_pid
PID of child process.
KSharedConfigPtr config()
QString loginName() const
bool contains(char ch) const const
int checkInstall(const char *password)
Checks if the stub is installed and the password is correct.
bool isEmpty() const const
QByteArray::const_iterator cbegin() const const
void setTerminal(bool terminal)
Enables/disables terminal output.
QByteArray toLocal8Bit() const const
bool useUsersOwnPassword()
Checks whether or not the user's password is being asked for or another user's password.
int fd() const
Returns the filedescriptor of the process.
void virtual_hook(int id, void *data) override
Standard hack to add virtual methods in a BC way.
void virtual_hook(int id, void *data) override
Standard hack to add virtual methods in a BC way.
QString superUserCommand()
Checks what the default super user command is, e.g.
void unreadLine(const QByteArray &line, bool addNewline=true)
Puts back a line of input.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri May 20 2022 04:13:56 by
doxygen 1.8.17 written
by
Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.