From b529f046c9a64ac5fcfa60747af940cf972b3ebc Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 6 Nov 2011 15:56:34 -0600 Subject: Actually move the kde files that were renamed in the last commit --- tdesu/tdesu/tdesu.cpp | 431 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 tdesu/tdesu/tdesu.cpp (limited to 'tdesu/tdesu/tdesu.cpp') diff --git a/tdesu/tdesu/tdesu.cpp b/tdesu/tdesu/tdesu.cpp new file mode 100644 index 000000000..d6aeebc6f --- /dev/null +++ b/tdesu/tdesu/tdesu.cpp @@ -0,0 +1,431 @@ +/* vi: ts=8 sts=4 sw=4 + * + * This file is part of the KDE project, module tdesu. + * Copyright (C) 1998 Pietro Iglio + * Copyright (C) 1999,2000 Geert Jansen + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#if defined(HAVE_SYS_WAIT_H) +#include +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sudlg.h" + +#define ERR strerror(errno) + +TQCString command; +const char *Version = "1.0"; + +// NOTE: if you change the position of the -u switch, be sure to adjust it +// at the beginning of main() +static KCmdLineOptions options[] = { + { "+command", I18N_NOOP("Specifies the command to run"), 0 }, + { "c ", I18N_NOOP("Specifies the command to run"), "" }, + { "f ", I18N_NOOP("Run command under target uid if is not writable"), "" }, + { "u ", I18N_NOOP("Specifies the target uid"), "root" }, + { "n", I18N_NOOP("Do not keep password"), 0 }, + { "s", I18N_NOOP("Stop the daemon (forgets all passwords)"), 0 }, + { "t", I18N_NOOP("Enable terminal output (no password keeping)"), 0 }, + { "p ", I18N_NOOP("Set priority value: 0 <= prio <= 100, 0 is lowest"), "50" }, + { "r", I18N_NOOP("Use realtime scheduling"), 0 }, + { "newdcop", I18N_NOOP("Create a new dcopserver instance (this can break your current TDE session)"), 0 }, + { "noignorebutton", I18N_NOOP("Do not display ignore button"), 0 }, + { "i ", I18N_NOOP("Specify icon to use in the password dialog"), 0}, + { "d", I18N_NOOP("Do not show the command to be run in the dialog"), 0}, + KCmdLineLastOption +}; + + +TQCString dcopNetworkId() +{ + TQCString result; + result.resize(1025); + TQFile file(DCOPClient::dcopServerFile()); + if (!file.open(IO_ReadOnly)) + return ""; + int i = file.readLine(result.data(), 1024); + if (i <= 0) + return ""; + result.data()[i-1] = '\0'; // strip newline + return result; +} + +static int startApp(); + +int main(int argc, char *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 + const char *duser = ::getenv("ADMIN_ACCOUNT"); + if (duser && duser[0]) + options[3].def = duser; + + KAboutData aboutData("tdesu", I18N_NOOP("KDE su"), + Version, I18N_NOOP("Runs a program with elevated privileges."), + KAboutData::License_Artistic, + "Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"); + aboutData.addAuthor("Geert Jansen", I18N_NOOP("Maintainer"), + "jansen@kde.org", "http://www.stack.nl/~geertj/"); + aboutData.addAuthor("Pietro Iglio", I18N_NOOP("Original author"), + "iglio@fub.it"); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + KApplication::disableAutoDcopRegistration(); + // tdesu doesn't process SM events, so don't even connect to ksmserver + TQCString session_manager = getenv( "SESSION_MANAGER" ); + unsetenv( "SESSION_MANAGER" ); + KApplication app; + // but propagate it to the started app + if (session_manager.data()) + { + setenv( "SESSION_MANAGER", session_manager.data(), 1 ); + } + + { + KStartupInfoId id; + id.initId( kapp->startupId()); + id.setupStartupEnv(); // make DESKTOP_STARTUP_ID env. var. available again + } + + int result = startApp(); + + if (result == 127) + { + KMessageBox::sorry(0, i18n("Command '%1' not found.").arg(static_cast(command))); + } + + return result; +} + +static int startApp() +{ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + // Stop daemon and exit? + if (args->isSet("s")) + { + KDEsuClient client; + if (client.ping() == -1) + { + kdError(1206) << "Daemon not running -- nothing to stop\n"; + exit(1); + } + if (client.stopServer() != -1) + { + kdDebug(1206) << "Daemon stopped\n"; + exit(0); + } + kdError(1206) << "Could not stop daemon\n"; + exit(1); + } + + TQString icon; + if ( args->isSet("i")) + icon = args->getOption("i"); + + bool prompt = true; + if ( args->isSet("d")) + prompt = false; + + // Get target uid + TQCString user = args->getOption("u"); + TQCString auth_user = user; + struct passwd *pw = getpwnam(user); + if (pw == 0L) + { + kdError(1206) << "User " << user << " does not exist\n"; + exit(1); + } + bool change_uid = (getuid() != pw->pw_uid); + + // If file is writeable, do not change uid + TQString file = TQFile::decodeName(args->getOption("f")); + if (change_uid && !file.isEmpty()) + { + if (file.tqat(0) != '/') + { + KStandardDirs dirs; + dirs.addKDEDefaults(); + file = dirs.findResource("config", file); + if (file.isEmpty()) + { + kdError(1206) << "Config file not found: " << file << "\n"; + exit(1); + } + } + TQFileInfo fi(file); + if (!fi.exists()) + { + kdError(1206) << "File does not exist: " << file << "\n"; + exit(1); + } + change_uid = !fi.isWritable(); + } + + // Get priority/scheduler + TQCString tmp = args->getOption("p"); + bool ok; + int priority = tmp.toInt(&ok); + if (!ok || (priority < 0) || (priority > 100)) + { + KCmdLineArgs::usage(i18n("Illegal priority: %1").arg(static_cast(tmp))); + exit(1); + } + int scheduler = SuProcess::SchedNormal; + if (args->isSet("r")) + scheduler = SuProcess::SchedRealtime; + if ((priority > 50) || (scheduler != SuProcess::SchedNormal)) + { + change_uid = true; + auth_user = "root"; + } + + // Get command + if (args->isSet("c")) + { + command = args->getOption("c"); + for (int i=0; icount(); i++) + { + TQString arg = TQFile::decodeName(args->arg(i)); + KRun::shellQuote(arg); + command += " "; + command += TQFile::encodeName(arg); + } + } + else + { + if( args->count() == 0 ) + { + KCmdLineArgs::usage(i18n("No command specified.")); + exit(1); + } + command = args->arg(0); + for (int i=1; icount(); i++) + { + TQString arg = TQFile::decodeName(args->arg(i)); + KRun::shellQuote(arg); + command += " "; + command += TQFile::encodeName(arg); + } + } + + // Don't change uid if we're don't need to. + if (!change_uid) + { + int result = system(command); + result = WEXITSTATUS(result); + return result; + } + + // Check for daemon and start if necessary + bool just_started = false; + bool have_daemon = true; + KDEsuClient client; + if (!client.isServerSGID()) + { + kdWarning(1206) << "Daemon not safe (not sgid), not using it.\n"; + have_daemon = false; + } + else if (client.ping() == -1) + { + if (client.startServer() == -1) + { + kdWarning(1206) << "Could not start daemon, reduced functionality.\n"; + have_daemon = false; + } + just_started = true; + } + + // Try to exec the command with tdesud. + bool keep = !args->isSet("n") && have_daemon; + bool terminal = true; + bool new_dcop = args->isSet("newdcop"); + bool withIgnoreButton = args->isSet("ignorebutton"); + + QCStringList env; + TQCString options; + env << ( "DESKTOP_STARTUP_ID=" + kapp->startupId()); + + if (pw->pw_uid) + { + // Only propagate KDEHOME for non-root users, + // root uses KDEROOTHOME + + // Translate the KDEHOME of this user to the new user. + TQString kdeHome = KGlobal::dirs()->relativeLocation("home", KGlobal::dirs()->localkdedir()); + if (kdeHome[0] != '/') + kdeHome.prepend("~/"); + else + kdeHome=TQString::null; // Use default + + env << ("KDEHOME="+ TQFile::encodeName(kdeHome)); + } + + KUser u; + env << (TQCString) ("KDESU_USER=" + u.loginName().local8Bit()); + + if (!new_dcop) + { + TQCString ksycoca = "KDESYCOCA="+TQFile::encodeName(locateLocal("cache", "ksycoca")); + env << ksycoca; + + options += "xf"; // X-only, dcop forwarding enabled. + } + + 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)) + { + kdError(1206) << "rlimit(): " << ERR << "\n"; + exit(1); + } + + // Read configuration + KConfig *config = KGlobal::config(); + config->setGroup("Passwords"); + int timeout = config->readNumEntry("Timeout", defTimeout); + + // Check if we need a password + SuProcess proc; + proc.setUser(auth_user); + int needpw = proc.checkNeedPassword(); + if (needpw < 0) + { + TQString err = i18n("Su returned with an error.\n"); + KMessageBox::error(0L, err); + exit(1); + } + if (needpw == 0) + { + keep = 0; + kdDebug() << "Don't need password!!\n"; + } + + // Start the dialog + TQCString password; + if (needpw) + { + KStartupInfoId id; + id.initId( kapp->startupId()); + KStartupInfoData data; + data.setSilent( KStartupInfoData::Yes ); + KStartupInfo::sendChange( id, data ); + KDEsuDialog dlg(user, auth_user, keep && !terminal,icon, withIgnoreButton); + if (prompt) + dlg.addLine(i18n("Command:"), command); + if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) + { + TQString prio; + if (scheduler == SuProcess::SchedRealtime) + prio += i18n("realtime: "); + prio += TQString("%1/100").arg(priority); + if (prompt) + dlg.addLine(i18n("Priority:"), prio); + } + int ret = dlg.exec(); + if (ret == KDEsuDialog::Rejected) + { + KStartupInfo::sendFinish( id ); + exit(0); + } + if (ret == KDEsuDialog::AsUser) + change_uid = false; + password = dlg.password(); + keep = dlg.keep(); + KConfigGroup(config,"Passwords").writeEntry("Keep", keep); + data.setSilent( KStartupInfoData::No ); + KStartupInfo::sendChange( id, data ); + } + + // Some events may need to be handled (like a button animation) + kapp->processEvents(); + + // Run command + if (!change_uid) + { + int result = system(command); + result = WEXITSTATUS(result); + return result; + } + else if (keep && have_daemon) + { + client.setPass(password, 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); + if (!new_dcop) + { + proc.setXOnly(true); + proc.setDCOPForwarding(true); + } + proc.setEnvironment(env); + proc.setPriority(priority); + proc.setScheduler(scheduler); + proc.setCommand(command); + int result = proc.exec(password); + return result; + } + return -1; +} + -- cgit v1.2.3