diff options
Diffstat (limited to 'kdesu/kdesud/kdesud.cpp')
-rw-r--r-- | kdesu/kdesud/kdesud.cpp | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/kdesu/kdesud/kdesud.cpp b/kdesu/kdesud/kdesud.cpp deleted file mode 100644 index d369aaf9b..000000000 --- a/kdesu/kdesud/kdesud.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * - * tdesud.cpp: KDE su daemon. Offers "keep password" functionality to kde su. - * - * The socket $KDEHOME/socket-$(HOSTNAME)/tdesud_$(display) is used for communication with - * client programs. - * - * The protocol: Client initiates the connection. All commands and responses - * are terminated by a newline. - * - * Client Server Description - * ------ ------ ----------- - * - * PASS <pass> <timeout> OK Set password for commands in - * this session. Password is - * valid for <timeout> seconds. - * - * USER <user> OK Set the target user [required] - * - * EXEC <command> OK Execute command <command>. If - * NO <command> has been executed - * before (< timeout) no PASS - * command is needed. - * - * DEL <command> OK Delete password for command - * NO <command>. - * - * PING OK Ping the server (diagnostics). - */ - - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <ctype.h> -#include <string.h> -#include <stdarg.h> -#include <signal.h> -#include <pwd.h> -#include <errno.h> - -#include <sys/prctl.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/resource.h> -#include <sys/wait.h> -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> // Needed on some systems. -#endif - -#include <tqptrvector.h> -#include <tqfile.h> -#include <tqregexp.h> - -#include <kinstance.h> -#include <kdebug.h> -#include <klocale.h> -#include <kcmdlineargs.h> -#include <kstandarddirs.h> -#include <kaboutdata.h> -#include <tdesu/client.h> -#include <tdesu/defaults.h> -#include <ksockaddr.h> - -#include "repo.h" -#include "handler.h" - -#include <X11/X.h> -#include <X11/Xlib.h> - -#ifndef SUN_LEN -#define SUN_LEN(ptr) ((kde_socklen_t) (((struct sockaddr_un *) 0)->sun_path) \ - + strlen ((ptr)->sun_path)) -#endif - -#define ERR strerror(errno) - -// Globals - -Repository *repo; -const char *Version = "1.01"; -TQCString sock; -Display *x11Display; -int pipeOfDeath[2]; - - -void tdesud_cleanup() -{ - unlink(sock); -} - - -// Borrowed from kdebase/kaudio/kaudioserver.cpp - -extern "C" int xio_errhandler(Display *); - -int xio_errhandler(Display *) -{ - kdError(1205) << "Fatal IO error, exiting...\n"; - tdesud_cleanup(); - exit(1); - return 1; //silence compilers -} - -int initXconnection() -{ - x11Display = XOpenDisplay(NULL); - if (x11Display != 0L) - { - XSetIOErrorHandler(xio_errhandler); - XCreateSimpleWindow(x11Display, DefaultRootWindow(x11Display), - 0, 0, 1, 1, 0, - BlackPixelOfScreen(DefaultScreenOfDisplay(x11Display)), - BlackPixelOfScreen(DefaultScreenOfDisplay(x11Display))); - return XConnectionNumber(x11Display); - } else - { - kdWarning(1205) << "Can't connect to the X Server.\n"; - kdWarning(1205) << "Might not terminate at end of session.\n"; - return -1; - } -} - -extern "C" { - void signal_exit(int); - void sigchld_handler(int); -} - -void signal_exit(int sig) -{ - kdDebug(1205) << "Exiting on signal " << sig << "\n"; - tdesud_cleanup(); - exit(1); -} - -void sigchld_handler(int) -{ - char c = ' '; - write(pipeOfDeath[1], &c, 1); -} - -/** - * Creates an AF_UNIX socket in socket resource, mode 0600. - */ - -int create_socket() -{ - int sockfd; - ksocklen_t addrlen; - struct stat s; - - TQCString display(getenv("DISPLAY")); - if (display.isEmpty()) - { - kdWarning(1205) << "$DISPLAY is not set\n"; - return -1; - } - - // strip the screen number from the display - display.replace(TQRegExp("\\.[0-9]+$"), ""); - - sock = TQFile::encodeName(locateLocal("socket", TQString("tdesud_%1").arg(static_cast<const char *>(display)))); - int stat_err=lstat(sock, &s); - if(!stat_err && S_ISLNK(s.st_mode)) { - kdWarning(1205) << "Someone is running a symlink attack on you\n"; - if(unlink(sock)) { - kdWarning(1205) << "Could not delete symlink\n"; - return -1; - } - } - - if (!access(sock, R_OK|W_OK)) - { - KDEsuClient client; - if (client.ping() == -1) - { - kdWarning(1205) << "stale socket exists\n"; - if (unlink(sock)) - { - kdWarning(1205) << "Could not delete stale socket\n"; - return -1; - } - } else - { - kdWarning(1205) << "tdesud is already running\n"; - return -1; - } - - } - - sockfd = socket(PF_UNIX, SOCK_STREAM, 0); - if (sockfd < 0) - { - kdError(1205) << "socket(): " << ERR << "\n"; - return -1; - } - - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1); - addr.sun_path[sizeof(addr.sun_path)-1] = '\000'; - addrlen = SUN_LEN(&addr); - if (bind(sockfd, (struct sockaddr *)&addr, addrlen) < 0) - { - kdError(1205) << "bind(): " << ERR << "\n"; - return -1; - } - - struct linger lin; - lin.l_onoff = lin.l_linger = 0; - if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &lin, - sizeof(linger)) < 0) - { - kdError(1205) << "setsockopt(SO_LINGER): " << ERR << "\n"; - return -1; - } - - int opt = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, - sizeof(opt)) < 0) - { - kdError(1205) << "setsockopt(SO_REUSEADDR): " << ERR << "\n"; - return -1; - } - opt = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, - sizeof(opt)) < 0) - { - kdError(1205) << "setsockopt(SO_KEEPALIVE): " << ERR << "\n"; - return -1; - } - chmod(sock, 0600); - return sockfd; -} - - -/** - * Main program - */ - -int main(int argc, char *argv[]) -{ - prctl(PR_SET_DUMPABLE, 0); - - KAboutData aboutData("tdesud", I18N_NOOP("KDE su daemon"), - Version, I18N_NOOP("Daemon used by tdesu"), - KAboutData::License_Artistic, - "Copyright (c) 1999,2000 Geert Jansen"); - aboutData.addAuthor("Geert Jansen", I18N_NOOP("Author"), - "jansen@kde.org", "http://www.stack.nl/~geertj/"); - KCmdLineArgs::init(argc, argv, &aboutData); - KInstance instance(&aboutData); - - // Set core dump size to 0 - struct rlimit rlim; - rlim.rlim_cur = rlim.rlim_max = 0; - if (setrlimit(RLIMIT_CORE, &rlim) < 0) - { - kdError(1205) << "setrlimit(): " << ERR << "\n"; - exit(1); - } - - // Create the Unix socket. - int sockfd = create_socket(); - if (sockfd < 0) - exit(1); - if (listen(sockfd, 1) < 0) - { - kdError(1205) << "listen(): " << ERR << "\n"; - tdesud_cleanup(); - exit(1); - } - int maxfd = sockfd; - - // Ok, we're accepting connections. Fork to the background. - pid_t pid = fork(); - if (pid == -1) - { - kdError(1205) << "fork():" << ERR << "\n"; - tdesud_cleanup(); - exit(1); - } - if (pid) - exit(0); - - // Make sure we exit when the display gets closed. - int x11Fd = initXconnection(); - maxfd = QMAX(maxfd, x11Fd); - - repo = new Repository; - TQPtrVector<ConnectionHandler> handler; - handler.setAutoDelete(true); - - pipe(pipeOfDeath); - maxfd = QMAX(maxfd, pipeOfDeath[0]); - - // Signal handlers - struct sigaction sa; - sa.sa_handler = signal_exit; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGHUP, &sa, 0L); - sigaction(SIGINT, &sa, 0L); - sigaction(SIGTERM, &sa, 0L); - sigaction(SIGQUIT, &sa, 0L); - - sa.sa_handler = sigchld_handler; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, 0L); - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, 0L); - - // Main execution loop - - ksocklen_t addrlen; - struct sockaddr_un clientname; - - fd_set tmp_fds, active_fds; - FD_ZERO(&active_fds); - FD_SET(sockfd, &active_fds); - FD_SET(pipeOfDeath[0], &active_fds); - if (x11Fd != -1) - FD_SET(x11Fd, &active_fds); - - while (1) - { - tmp_fds = active_fds; - if(x11Display) - XFlush(x11Display); - if (select(maxfd+1, &tmp_fds, 0L, 0L, 0L) < 0) - { - if (errno == EINTR) continue; - - kdError(1205) << "select(): " << ERR << "\n"; - exit(1); - } - repo->expire(); - for (int i=0; i<=maxfd; i++) - { - if (!FD_ISSET(i, &tmp_fds)) - continue; - - if (i == pipeOfDeath[0]) - { - char buf[101]; - read(pipeOfDeath[0], buf, 100); - pid_t result; - do - { - int status; - result = waitpid((pid_t)-1, &status, WNOHANG); - if (result > 0) - { - for(int j=handler.size(); j--;) - { - if (handler[j] && (handler[j]->m_pid == result)) - { - handler[j]->m_exitCode = WEXITSTATUS(status); - handler[j]->m_hasExitCode = true; - handler[j]->sendExitCode(); - handler[j]->m_pid = 0; - break; - } - } - } - } - while(result > 0); - } - - if (i == x11Fd) - { - // Discard X events - XEvent event_return; - if (x11Display) - while(XPending(x11Display)) - XNextEvent(x11Display, &event_return); - continue; - } - - if (i == sockfd) - { - // Accept new connection - int fd; - addrlen = 64; - fd = accept(sockfd, (struct sockaddr *) &clientname, &addrlen); - if (fd < 0) - { - kdError(1205) << "accept():" << ERR << "\n"; - continue; - } - if (fd+1 > (int) handler.size()) - handler.resize(fd+1); - handler.insert(fd, new ConnectionHandler(fd)); - maxfd = TQMAX(maxfd, fd); - FD_SET(fd, &active_fds); - continue; - } - - // handle alreay established connection - if (handler[i] && handler[i]->handle() < 0) - { - handler.remove(i); - FD_CLR(i, &active_fds); - } - } - } - kdWarning(1205) << "???\n"; -} - |