diff options
Diffstat (limited to 'kdesu/kdesu_stub.c')
-rw-r--r-- | kdesu/kdesu_stub.c | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/kdesu/kdesu_stub.c b/kdesu/kdesu_stub.c deleted file mode 100644 index 5e1f09c24..000000000 --- a/kdesu/kdesu_stub.c +++ /dev/null @@ -1,432 +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> - * - * tdesu_stub.c: KDE su executes this stub through su or ssh. This stub in turn - * executes the target program. Before that, startup parameters - * are sent through stdin. - * - * - * Available parameters: - * - * Parameter Description Format (csl = comma separated list) - * - * - tdesu_stub Header "ok" | "stop" - * - display X11 display string - * - display_auth X11 authentication "type cookie" pair - * - dcopserver KDE dcopserver csl of netids - * - dcop_auth DCOP authentication csl of "type cookie" pairs for DCOP - * - ice_auth ICE authentication csl of "type cookie" pairs for ICE - * - command Command to run string - * - path PATH env. var string - * - build_sycoca Rebuild sycoca? "yes" | "no" - * - user Target user string - * - priority Process priority 0 <= int <= 100 - * - scheduler Process scheduler "fifo" | "normal" - * - app_startup_id DESKTOP_STARTUP_ID string - * - environment Additional envvars strings, last one is empty - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <pwd.h> -#include <termios.h> -#include <signal.h> - -#ifdef HAVE_INITGROUPS -#include <grp.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> - -#ifdef POSIX1B_SCHEDULING -#include <sched.h> -#endif - -/** - * Params sent by the peer. - */ - -struct param_struct -{ - const char *name; - char *value; -}; - -struct param_struct params[] = -{ - { "tdesu_stub", 0L }, - { "display", 0L }, - { "display_auth", 0L }, - { "dcopserver", 0L }, - { "dcop_auth", 0L }, - { "ice_auth", 0L }, - { "command", 0L }, - { "path", 0L }, - { "xwindows_only", 0L }, - { "user", 0L }, - { "priority", 0L }, - { "scheduler", 0L }, -/* obsoleted by app_startup_id { "app_start_pid", 0L } */ - { "app_startup_id", 0L } -}; - -#define P_HEADER 0 -#define P_DISPLAY 1 -#define P_DISPLAY_AUTH 2 -#define P_DCOPSERVER 3 -#define P_DCOP_AUTH 4 -#define P_ICE_AUTH 5 -#define P_COMMAND 6 -#define P_PATH 7 -#define P_XWIN_ONLY 8 -#define P_USER 9 -#define P_PRIORITY 10 -#define P_SCHEDULER 11 -#define P_APP_STARTUP_ID 12 -#define P_LAST 13 - -/* Prototypes */ -char *xmalloc(size_t); -char *xrealloc(char *ptr, int size); -int xsetenv(const char *name, const char *value); -char *xstrdup(char *src); -char **xstrsep(char *str); - -/** - * Safe malloc functions. - */ -char *xmalloc(size_t size) -{ - char *ptr = malloc(size); - if (ptr) return ptr; - perror("malloc()"); - exit(1); -} - - -char *xrealloc(char *ptr, int size) -{ - ptr = realloc(ptr, size); - if (ptr) return ptr; - perror("realloc()"); - exit(1); -} - - -/** - * Solaris does not have a setenv()... - */ -int xsetenv(const char *name, const char *value) -{ - char *s = malloc(strlen(name)+strlen(value)+2); - if (!s) return -1; - strcpy(s, name); - strcat(s, "="); - strcat(s, value); - return putenv(s); /* yes: no free()! */ -} - -/** - * Safe strdup and strip newline - */ -char *xstrdup(char *src) -{ - int len = strlen(src); - char *dst = xmalloc(len+1); - strcpy(dst, src); - if (dst[len-1] == '\n') - dst[len-1] = '\000'; - return dst; -} - -/** - * Split comma separated list. - */ -char **xstrsep(char *str) -{ - int i = 0, size = 10; - char **list = (char **) xmalloc(size * sizeof(char *)); - char *ptr = str, *nptr; - while ((nptr = strchr(ptr, ',')) != 0L) - { - if (i > size-2) - list = realloc(list, (size *= 2) * sizeof(char *)); - *nptr = '\000'; - list[i++] = ptr; - ptr = nptr+1; - } - if (*ptr != '\000') - list[i++] = ptr; - list[i] = 0L; - return list; -} - -#define BUFSIZE 8192 - -/** - * The main program - */ - -int main() -{ - char buf[BUFSIZE+1]; -#ifndef QWS - char xauthority[200]; -#endif - char iceauthority[200]; - char **host, **auth; - int i/*, res, sycoca*/, prio; - pid_t pid; - FILE *fout; - struct passwd *pw; - const char* tdesu_lc_all; - - /* Get startup parameters. */ - - for (i=0; i<P_LAST; i++) - { - printf("%s\n", params[i].name); - fflush(stdout); - if (fgets(buf, BUFSIZE, stdin) == 0L) - { - printf("end\n"); fflush(stdout); - perror("tdesu_stub: fgets()"); - exit(1); - } - params[i].value = xstrdup(buf); - /* Installation check? */ - if ((i == 0) && !strcmp(params[i].value, "stop")) - { - printf("end\n"); - exit(0); - } - } - printf("environment\n"); - fflush(stdout); - for(;;) - { - char* tmp; - if (fgets(buf, BUFSIZE, stdin) == 0L) - { - printf("end\n"); fflush(stdout); - perror("tdesu_stub: fgets()"); - exit(1); - } - tmp = xstrdup( buf ); - if( tmp[ 0 ] == '\0' ) /* terminator */ - break; - putenv( xstrdup( buf )); - } - - printf("end\n"); - fflush(stdout); - - xsetenv("PATH", params[P_PATH].value); - xsetenv("DESKTOP_STARTUP_ID", params[P_APP_STARTUP_ID].value); - - tdesu_lc_all = getenv( "KDESU_LC_ALL" ); - if( tdesu_lc_all != NULL ) - xsetenv("LC_ALL",tdesu_lc_all); - else - unsetenv("LC_ALL"); - - /* Do we need to change uid? */ - - pw = getpwnam(params[P_USER].value); - if (pw == 0L) - { - printf("tdesu_stub: user %s does not exist!\n", params[P_USER].value); - exit(1); - } - xsetenv("HOME", pw->pw_dir); - - /* Set scheduling/priority */ - - prio = atoi(params[P_PRIORITY].value); - if (!strcmp(params[P_SCHEDULER].value, "realtime")) - { -#ifdef POSIX1B_SCHEDULING - struct sched_param sched; - int min = sched_get_priority_min(SCHED_FIFO); - int max = sched_get_priority_max(SCHED_FIFO); - sched.sched_priority = min + (int) (((double) prio) * (max - min) / 100 + 0.5); - sched_setscheduler(0, SCHED_FIFO, &sched); -#else - printf("tdesu_stub: realtime scheduling not supported\n"); -#endif - } else - { -#ifdef HAVE_SETPRIORITY - int val = 20 - (int) (((double) prio) * 40 / 100 + 0.5); - setpriority(PRIO_PROCESS, getpid(), val); -#endif - } - - /* Drop privileges (this is permanent) */ - - if (getuid() != pw->pw_uid) - { - if (setgid(pw->pw_gid) == -1) - { - perror("tdesu_stub: setgid()"); - exit(1); - } -#ifdef HAVE_INITGROUPS - if (initgroups(pw->pw_name, pw->pw_gid) == -1) - { - perror("tdesu_stub: initgroups()"); - exit(1); - } -#endif - if (setuid(pw->pw_uid) == -1) - { - perror("tdesu_stub: setuid()"); - exit(1); - } - xsetenv("HOME", pw->pw_dir); - } - - /* Handle display */ - - if (strcmp(params[P_DISPLAY].value, "no")) - { -#ifndef QWS - xsetenv("DISPLAY", params[P_DISPLAY].value); - if (params[P_DISPLAY_AUTH].value[0]) - { - int fd2; - /* - ** save umask and set to 077, so we create those files only - ** readable for root. (if someone else could read them, we - ** are in deep shit). - */ - int oldumask = umask(077); - const char *disp = params[P_DISPLAY].value; - if (strncmp(disp, "localhost:", 10) == 0) - disp += 9; - - strcpy(xauthority, "/tmp/xauth.XXXXXXXXXX"); - fd2 = mkstemp(xauthority); - umask(oldumask); - - if (fd2 == -1) { - perror("tdesu_stub: mkstemp()"); - exit(1); - } else - close(fd2); - xsetenv("XAUTHORITY", xauthority); - - fout = popen("xauth >/dev/null 2>&1","w"); - if (fout == NULL) - { - perror("tdesu_stub: popen(xauth)"); - exit(1); - } - fprintf(fout, "add %s %s\n", disp, - params[P_DISPLAY_AUTH].value); - pclose(fout); - } -#else - xsetenv("DISPLAY", params[P_DISPLAY].value); -#endif - } - - - /* Handle DCOP */ - - if (strcmp(params[P_DCOPSERVER].value, "no")) - { - xsetenv("DCOPSERVER", params[P_DCOPSERVER].value); - host = xstrsep(params[P_DCOPSERVER].value); - auth = xstrsep(params[P_ICE_AUTH].value); - if (host[0]) - { - int fd; - int oldumask = umask(077); - - strcpy(iceauthority, "/tmp/iceauth.XXXXXXXXXX"); - fd = mkstemp(iceauthority); - umask(oldumask); - if (fd == -1) { - perror("tdesu_stub: mkstemp()"); - exit(1); - } else - close(fd); - xsetenv("ICEAUTHORITY", iceauthority); - - fout = popen("iceauth >/dev/null 2>&1", "w"); - if (!fout) { - perror("tdesu_stub: popen iceauth"); - exit(1); - } - for (i=0; host[i]; i++) - fprintf(fout, "add ICE \"\" %s %s\n", host[i], auth[i]); - auth = xstrsep(params[P_DCOP_AUTH].value); - for (i=0; host[i]; i++) - fprintf(fout, "add DCOP \"\" %s %s\n", host[i], auth[i]); - pclose(fout); - } - } - - /* Rebuild the sycoca and start tdeinit? */ - - if (strcmp(params[P_XWIN_ONLY].value, "no")) - { - system("tdeinit --suicide"); - } - - /* Execute the command */ - - pid = fork(); - if (pid == -1) - { - perror("tdesu_stub: fork()"); - exit(1); - } - if (pid) - { - /* Parent: wait for child, delete tempfiles and return. */ - int ret, state, xit = 1; - while (1) - { - ret = waitpid(pid, &state, 0); - if (ret == -1) - { - if (errno == EINTR) - continue; - if (errno != ECHILD) - perror("tdesu_stub: waitpid()"); - break; - } - if (WIFEXITED(state)) - xit = WEXITSTATUS(state); - } - -#ifndef QWS - unlink(xauthority); -#endif - unlink(iceauthority); - exit(xit); - } else - { - setsid(); - /* Child: exec command. */ - sprintf(buf, "%s", params[P_COMMAND].value); - execl("/bin/sh", "sh", "-c", buf, (void *)0); - perror("tdesu_stub: exec()"); - _exit(1); - } -} |