summaryrefslogtreecommitdiffstats
path: root/kdesu/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdesu/client.cpp')
-rw-r--r--kdesu/client.cpp435
1 files changed, 0 insertions, 435 deletions
diff --git a/kdesu/client.cpp b/kdesu/client.cpp
deleted file mode 100644
index 18accc313..000000000
--- a/kdesu/client.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-/* vi: ts=8 sts=4 sw=4
- *
- * $Id$
- *
- * This file is part of the KDE project, module tdesu.
- * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
- *
- * This is free software; you can use this library under the GNU Library
- * General Public License, version 2. See the file "COPYING.LIB" for the
- * exact licensing terms.
- *
- * client.cpp: A client for tdesud.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <pwd.h>
-#include <errno.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-
-#include <tqglobal.h>
-#include <tqcstring.h>
-#include <tqfile.h>
-#include <tqregexp.h>
-
-#include <kdebug.h>
-#include <kstandarddirs.h>
-#include <kapplication.h>
-#include <kde_file.h>
-
-#include "client.h"
-
-class KDEsuClient::KDEsuClientPrivate {
-public:
- TQString daemon;
-};
-
-#ifndef SUN_LEN
-#define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \
- + strlen ((ptr)->sun_path))
-#endif
-
-KDEsuClient::KDEsuClient()
-{
- sockfd = -1;
-#ifdef Q_WS_X11
- TQCString display(getenv("DISPLAY"));
- if (display.isEmpty())
- {
- kdWarning(900) << k_lineinfo << "$DISPLAY is not set\n";
- return;
- }
-
- // strip the screen number from the display
- display.replace(TQRegExp("\\.[0-9]+$"), "");
-#else
- TQCString display("QWS");
-#endif
-
- sock = TQFile::encodeName(locateLocal("socket", TQString("tdesud_%1").arg(display.data())));
- d = new KDEsuClientPrivate;
- connect();
-}
-
-
-KDEsuClient::~KDEsuClient()
-{
- delete d;
- if (sockfd >= 0)
- close(sockfd);
-}
-
-int KDEsuClient::connect()
-{
- if (sockfd >= 0)
- close(sockfd);
- if (access(sock, R_OK|W_OK))
- {
- sockfd = -1;
- return -1;
- }
-
- sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sockfd < 0)
- {
- kdWarning(900) << k_lineinfo << "socket(): " << perror << "\n";
- return -1;
- }
- struct sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, sock);
-
- if (::connect(sockfd, (struct sockaddr *) &addr, SUN_LEN(&addr)) < 0)
- {
- kdWarning(900) << k_lineinfo << "connect():" << perror << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
-
-#if !defined(SO_PEERCRED) || !defined(HAVE_STRUCT_UCRED)
-# if defined(HAVE_GETPEEREID)
- uid_t euid;
- gid_t egid;
- // Security: if socket exists, we must own it
- if (getpeereid(sockfd, &euid, &egid) == 0)
- {
- if (euid != getuid())
- {
- kdWarning(900) << "socket not owned by me! socket uid = " << euid << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
- }
-# else
-# ifdef __GNUC__
-# warning "Using sloppy security checks"
-# endif
- // We check the owner of the socket after we have connected.
- // If the socket was somehow not ours an attacker will be able
- // to delete it after we connect but shouldn't be able to
- // create a socket that is owned by us.
- KDE_struct_stat s;
- if (KDE_lstat(sock, &s)!=0)
- {
- kdWarning(900) << "stat failed (" << sock << ")" << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
- if (s.st_uid != getuid())
- {
- kdWarning(900) << "socket not owned by me! socket uid = " << s.st_uid << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
- if (!S_ISSOCK(s.st_mode))
- {
- kdWarning(900) << "socket is not a socket (" << sock << ")" << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
-# endif
-#else
- struct ucred cred;
- socklen_t siz = sizeof(cred);
-
- // Security: if socket exists, we must own it
- if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0)
- {
- if (cred.uid != getuid())
- {
- kdWarning(900) << "socket not owned by me! socket uid = " << cred.uid << endl;
- close(sockfd); sockfd = -1;
- return -1;
- }
- }
-#endif
-
- return 0;
-}
-
-TQCString KDEsuClient::escape(const TQCString &str)
-{
- TQCString copy = str;
- int n = 0;
- while ((n = copy.find("\\", n)) != -1)
- {
- copy.insert(n, '\\');
- n += 2;
- }
- n = 0;
- while ((n = copy.find("\"", n)) != -1)
- {
- copy.insert(n, '\\');
- n += 2;
- }
- copy.prepend("\"");
- copy.append("\"");
- return copy;
-}
-
-int KDEsuClient::command(const TQCString &cmd, TQCString *result)
-{
- if (sockfd < 0)
- return -1;
-
- if (send(sockfd, cmd, cmd.length(), 0) != (int) cmd.length())
- return -1;
-
- char buf[1024];
- int nbytes = recv(sockfd, buf, 1023, 0);
- if (nbytes <= 0)
- {
- kdWarning(900) << k_lineinfo << "no reply from daemon\n";
- return -1;
- }
- buf[nbytes] = '\000';
-
- TQCString reply = buf;
- if (reply.left(2) != "OK")
- return -1;
-
- if (result)
- *result = reply.mid(3, reply.length()-4);
- return 0;
-}
-
-int KDEsuClient::setPass(const char *pass, int timeout)
-{
- TQCString cmd = "PASS ";
- cmd += escape(pass);
- cmd += " ";
- cmd += TQCString().setNum(timeout);
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::exec(const TQCString &prog, const TQCString &user, const TQCString &options, const QCStringList &env)
-{
- TQCString cmd;
- cmd = "EXEC ";
- cmd += escape(prog);
- cmd += " ";
- cmd += escape(user);
- if (!options.isEmpty() || !env.isEmpty())
- {
- cmd += " ";
- cmd += escape(options);
- for(QCStringList::ConstIterator it = env.begin();
- it != env.end(); ++it)
- {
- cmd += " ";
- cmd += escape(*it);
- }
- }
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::setHost(const TQCString &host)
-{
- TQCString cmd = "HOST ";
- cmd += escape(host);
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::setPriority(int prio)
-{
- TQCString cmd;
- cmd.sprintf("PRIO %d\n", prio);
- return command(cmd);
-}
-
-int KDEsuClient::setScheduler(int sched)
-{
- TQCString cmd;
- cmd.sprintf("SCHD %d\n", sched);
- return command(cmd);
-}
-
-int KDEsuClient::delCommand(const TQCString &key, const TQCString &user)
-{
- TQCString cmd = "DEL ";
- cmd += escape(key);
- cmd += " ";
- cmd += escape(user);
- cmd += "\n";
- return command(cmd);
-}
-int KDEsuClient::setVar(const TQCString &key, const TQCString &value, int timeout,
- const TQCString &group)
-{
- TQCString cmd = "SET ";
- cmd += escape(key);
- cmd += " ";
- cmd += escape(value);
- cmd += " ";
- cmd += escape(group);
- cmd += " ";
- cmd += TQCString().setNum(timeout);
- cmd += "\n";
- return command(cmd);
-}
-
-TQCString KDEsuClient::getVar(const TQCString &key)
-{
- TQCString cmd = "GET ";
- cmd += escape(key);
- cmd += "\n";
- TQCString reply;
- command(cmd, &reply);
- return reply;
-}
-
-TQValueList<TQCString> KDEsuClient::getKeys(const TQCString &group)
-{
- TQCString cmd = "GETK ";
- cmd += escape(group);
- cmd += "\n";
- TQCString reply;
- command(cmd, &reply);
- int index=0, pos;
- TQValueList<TQCString> list;
- if( !reply.isEmpty() )
- {
- // kdDebug(900) << "Found a matching entry: " << reply << endl;
- while (1)
- {
- pos = reply.find( '\007', index );
- if( pos == -1 )
- {
- if( index == 0 )
- list.append( reply );
- else
- list.append( reply.mid(index) );
- break;
- }
- else
- {
- list.append( reply.mid(index, pos-index) );
- }
- index = pos+1;
- }
- }
- return list;
-}
-
-bool KDEsuClient::findGroup(const TQCString &group)
-{
- TQCString cmd = "CHKG ";
- cmd += escape(group);
- cmd += "\n";
- if( command(cmd) == -1 )
- return false;
- return true;
-}
-
-int KDEsuClient::delVar(const TQCString &key)
-{
- TQCString cmd = "DELV ";
- cmd += escape(key);
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::delGroup(const TQCString &group)
-{
- TQCString cmd = "DELG ";
- cmd += escape(group);
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::delVars(const TQCString &special_key)
-{
- TQCString cmd = "DELS ";
- cmd += escape(special_key);
- cmd += "\n";
- return command(cmd);
-}
-
-int KDEsuClient::ping()
-{
- return command("PING\n");
-}
-
-int KDEsuClient::exitCode()
-{
- TQCString result;
- if (command("EXIT\n", &result) != 0)
- return -1;
-
- return result.toLong();
-}
-
-int KDEsuClient::stopServer()
-{
- return command("STOP\n");
-}
-
-static TQString findDaemon()
-{
- TQString daemon = locate("bin", "tdesud");
- if (daemon.isEmpty()) // if not in KDEDIRS, rely on PATH
- daemon = KStandardDirs::findExe("tdesud");
-
- if (daemon.isEmpty())
- {
- kdWarning(900) << k_lineinfo << "daemon not found\n";
- }
- return daemon;
-}
-
-bool KDEsuClient::isServerSGID()
-{
- if (d->daemon.isEmpty())
- d->daemon = findDaemon();
- if (d->daemon.isEmpty())
- return false;
-
- KDE_struct_stat sbuf;
- if (KDE_stat(TQFile::encodeName(d->daemon), &sbuf) < 0)
- {
- kdWarning(900) << k_lineinfo << "stat(): " << perror << "\n";
- return false;
- }
- return (sbuf.st_mode & S_ISGID);
-}
-
-int KDEsuClient::startServer()
-{
- if (d->daemon.isEmpty())
- d->daemon = findDaemon();
- if (d->daemon.isEmpty())
- return -1;
-
- if (!isServerSGID()) {
- kdWarning(900) << k_lineinfo << "tdesud not setgid!\n";
- }
-
- // tdesud only forks to the background after it is accepting
- // connections.
- // We start it via tdeinit to make sure that it doesn't inherit
- // any fd's from the parent process.
- int ret = kapp->tdeinitExecWait(d->daemon);
- connect();
- return ret;
-}