diff options
author | Martin Schulze <joey@infodrom.org> | 2003-12-21 19:46:24 +0100 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2011-09-03 14:05:24 +0200 |
commit | 67af36e4c38c4ee5fc23c1efb70ef91c7b2cd922 (patch) | |
tree | dd4d1f89fa9eadb079357d8a8f0dbf21fcecbef6 /attacher.c | |
parent | 0525fda03f3f0a67ed717562228d19f1161e2176 (diff) | |
parent | 0e9a09d7718f02726b12924f7ddb05a992202aa3 (diff) | |
download | screen-67af36e4c38c4ee5fc23c1efb70ef91c7b2cd922.tar.gz |
Imported Debian patch 3.9.11-5woody1debian/3.9.11-5woody1
Diffstat (limited to 'attacher.c')
-rw-r--r-- | attacher.c | 248 |
1 files changed, 166 insertions, 82 deletions
@@ -1,4 +1,4 @@ -/* Copyright (c) 1993 +/* Copyright (c) 1993-2002 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Copyright (c) 1987 Oliver Laumann @@ -33,12 +33,9 @@ RCS_ID("$Id: attacher.c,v 1.8 1994/05/31 12:31:32 mlschroe Exp $ FAU") #include "screen.h" #include "extern.h" -#ifdef USE_PAM -#include <security/pam_appl.h> -#endif /* USE_PAM */ - #include <pwd.h> +static int WriteMessage __P((int, struct msg *)); static sigret_t AttacherSigInt __P(SIGPROTOARG); #if defined(SIGWINCH) && defined(TIOCGWINSZ) static sigret_t AttacherWinch __P(SIGPROTOARG); @@ -62,6 +59,7 @@ extern struct passwd *ppp; extern char *attach_tty, *attach_term, *LoginName, *preselect; extern int xflag, dflag, rflag, quietflag, adaptflag; extern struct mode attach_Mode; +extern struct NewWindow nwin_options; extern int MasterPid; #ifdef MULTIUSER @@ -73,10 +71,6 @@ static int multipipe[2]; # endif #endif -#ifdef USE_PAM -static char *PAM_password; -static char *PAM_name; -#endif #ifdef MULTIUSER static int ContinuePlease; @@ -98,6 +92,26 @@ AttachSigCont SIGDEFARG * MSG_CONT, MSG_WINCH and nothing else! */ +static int +WriteMessage(s, m) +int s; +struct msg *m; +{ + int r, l = sizeof(*m); + + while(l > 0) + { + r = write(s, (char *)m + (sizeof(*m) - l), l); + if (r == -1 && errno == EINTR) + continue; + if (r == -1 || r == 0) + return -1; + l -= r; + } + return 0; +} + + int Attach(how) int how; @@ -149,8 +163,8 @@ int how; if (ret == SIG_POWER_BYE) { int ppid; - setuid(real_uid); setgid(real_gid); + setuid(real_uid); if ((ppid = getppid()) > 1) Kill(ppid, SIGHUP); exit(0); @@ -192,7 +206,7 @@ int how; { if ((lasts = MakeClientSocket(0)) >= 0) { - write(lasts, (char *)&m, sizeof(m)); + WriteMessage(lasts, &m); close(lasts); } return 0; @@ -293,8 +307,8 @@ int how; else # endif m.type = MSG_DETACH; - if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m)) - Panic(errno, "write"); + if (WriteMessage(lasts, &m)) + Panic(errno, "WriteMessage"); close(lasts); if (how != MSG_ATTACH) return 0; /* we detached it. jw. */ @@ -322,6 +336,7 @@ int how; m.m.attach.lines = atoi(s); if ((s = getenv("COLUMNS"))) m.m.attach.columns = atoi(s); + m.m.attach.encoding = nwin_options.encoding > 0 ? nwin_options.encoding + 1 : 0; #ifdef MULTIUSER /* setup CONT signal handler to repair the terminal mode */ @@ -329,8 +344,8 @@ int how; signal(SIGCONT, AttachSigCont); #endif - if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m)) - Panic(errno, "write"); + if (WriteMessage(lasts, &m)) + Panic(errno, "WriteMessage"); close(lasts); debug1("Attach(%d): sent\n", m.type); #ifdef MULTIUSER @@ -358,14 +373,14 @@ int how; #if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER) -static int AttacherPanic; +static int AttacherPanic = 0; #endif #ifdef DEBUG static sigret_t AttacherChld SIGDEFARG { - AttacherPanic=1; + AttacherPanic = 1; SIGRETURN; } #endif @@ -395,7 +410,7 @@ AttacherSigInt SIGDEFARG /* * Unfortunatelly this is also the SIGHUP handler, so we have to - * check, if the backend is already detached. + * check if the backend is already detached. */ sigret_t @@ -420,7 +435,7 @@ AttacherFinit SIGDEFARG m.protocol_revision = MSG_REVISION; if ((s = MakeClientSocket(0)) >= 0) { - write(s, (char *)&m, sizeof(m)); + WriteMessage(s, &m); close(s); } } @@ -445,12 +460,12 @@ AttacherFinitBye SIGDEFARG if (multiattach) exit(SIG_POWER_BYE); #endif + setgid(real_gid); #ifdef MULTIUSER setuid(own_uid); #else setuid(real_uid); #endif - setgid(real_gid); /* we don't want to disturb init (even if we were root), eh? jw */ if ((ppid = getppid()) > 1) Kill(ppid, SIGHUP); /* carefully say good bye. jw. */ @@ -565,14 +580,10 @@ Attacher() #if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER) if (AttacherPanic) { -# ifdef FORKDEBUG - exit(0); -# else fcntl(0, F_SETFL, 0); SetTTY(0, &attach_Mode); printf("\nSuddenly the Dungeon collapses!! - You die...\n"); eexit(1); -# endif } #endif #ifdef BSDJOBS @@ -630,12 +641,12 @@ static sigret_t LockHup SIGDEFARG { int ppid = getppid(); + setgid(real_gid); #ifdef MULTIUSER setuid(own_uid); #else setuid(real_uid); #endif - setgid(real_gid); if (ppid > 1) Kill(ppid, SIGHUP); exit(0); @@ -661,12 +672,12 @@ LockTerminal() if ((pid = fork()) == 0) { /* Child */ + setgid(real_gid); #ifdef MULTIUSER setuid(own_uid); #else setuid(real_uid); /* this should be done already */ #endif - setgid(real_gid); closeallfiles(0); /* important: /etc/shadow may be open */ execl(prg, "SCREEN-LOCK", NULL); exit(errno); @@ -731,66 +742,79 @@ LockTerminal() } /* LockTerminal */ #ifdef USE_PAM -static int PAM_conv (int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - void *appdata_ptr) { - int replies = 0; - struct pam_response *reply = NULL; - - reply = malloc(sizeof(struct pam_response)*num_msg); - if (!reply) return PAM_CONV_ERR; - #define COPY_STRING(s) (s) ? strdup(s) : NULL - - for (replies = 0; replies < num_msg; replies++) { - switch (msg[replies]->msg_style) { - case PAM_PROMPT_ECHO_OFF: - /* wants password */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - break; - case PAM_TEXT_INFO: - /* ignore the informational mesage */ - /* but first clear out any drek left by malloc */ - reply[replies].resp = NULL; - break; - case PAM_PROMPT_ECHO_ON: - /* user name given to PAM already */ - /* fall through */ - default: - /* unknown or PAM_ERROR_MSG */ - free (reply); - return PAM_CONV_ERR; - } + +/* + * PAM support by Pablo Averbuj <pablo@averbuj.com> + */ + +#include <security/pam_appl.h> + +static int PAM_conv __P((int, const struct pam_message **, struct pam_response **, void *)); + +static int +PAM_conv(num_msg, msg, resp, appdata_ptr) +int num_msg; +const struct pam_message **msg; +struct pam_response **resp; +void *appdata_ptr; +{ + int replies = 0; + struct pam_response *reply = NULL; + + reply = malloc(sizeof(struct pam_response)*num_msg); + if (!reply) + return PAM_CONV_ERR; + #define COPY_STRING(s) (s) ? strdup(s) : NULL + + for (replies = 0; replies < num_msg; replies++) + { + switch (msg[replies]->msg_style) + { + case PAM_PROMPT_ECHO_OFF: + /* wants password */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = appdata_ptr ? strdup((char *)appdata_ptr) : 0; + break; + case PAM_TEXT_INFO: + /* ignore the informational mesage */ + /* but first clear out any drek left by malloc */ + reply[replies].resp = NULL; + break; + case PAM_PROMPT_ECHO_ON: + /* user name given to PAM already */ + /* fall through */ + default: + /* unknown or PAM_ERROR_MSG */ + free(reply); + return PAM_CONV_ERR; + } } - *resp = reply; - return PAM_SUCCESS; + *resp = reply; + return PAM_SUCCESS; } static struct pam_conv PAM_conversation = { &PAM_conv, NULL }; -#endif +#endif + /* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */ static void screen_builtin_lck() { char fullname[100], *cp1, message[100 + 100]; - char *pass; #ifdef USE_PAM + pam_handle_t *pamh = 0; int pam_error; - pam_handle_t *pamh = NULL; #else - char mypass[9]; -#endif /* USE_PAM */ + char *pass, mypass[9]; +#endif +#ifndef USE_PAM pass = ppp->pw_passwd; - -#ifndef USE_PAM - /* if we're using PAM this will evaluate to true. which we don't want. */ if (pass == 0 || *pass == 0) { if ((pass = getpass("Key: "))) @@ -817,7 +841,7 @@ screen_builtin_lck() } pass = 0; } -#endif /* USE_PAM */ +#endif debug("screen_builtin_lck looking in gcos field\n"); strncpy(fullname, ppp->pw_gecos, sizeof(fullname) - 9); @@ -847,20 +871,15 @@ screen_builtin_lck() /* NOTREACHED */ } #ifdef USE_PAM - PAM_password=cp1; - PAM_name=ppp->pw_name; - - pam_error = pam_start("screen", PAM_name, &PAM_conversation, &pamh); - - if (pam_error == PAM_SUCCESS) { - pam_error = pam_authenticate(pamh, 0); - pam_end(pamh, PAM_SUCCESS); - if (pam_error == PAM_SUCCESS) { - memset(cp1,0,strlen(cp1)); - PAM_password = NULL; - break; - } - } + PAM_conversation.appdata_ptr = cp1; + pam_error = pam_start("screen", ppp->pw_name, &PAM_conversation, &pamh); + if (pam_error != PAM_SUCCESS) + AttacherFinit(SIGARG); /* goodbye */ + pam_error = pam_authenticate(pamh, 0); + pam_end(pamh, pam_error); + PAM_conversation.appdata_ptr = 0; + if (pam_error == PAM_SUCCESS) + break; #else if (pass) { @@ -874,8 +893,73 @@ screen_builtin_lck() } #endif debug("screen_builtin_lck: NO!!!!!\n"); + bzero(cp1, strlen(cp1)); } + bzero(cp1, strlen(cp1)); debug("password ok.\n"); } #endif /* LOCK */ + + +void +SendCmdMessage(sty, match, av) +char *sty; +char *match; +char **av; +{ + int i, s; + struct msg m; + char *p; + int len, n; + + if (sty == 0) + { + i = FindSocket(&s, (int *)0, (int *)0, match); + if (i == 0) + Panic(0, "No screen session found."); + if (i != 1) + Panic(0, "Use -S to specify a session."); + } + else + { +#ifdef NAME_MAX + if (strlen(sty) > NAME_MAX) + sty[NAME_MAX] = 0; +#endif + if (strlen(sty) > 2 * MAXSTR - 1) + sty[2 * MAXSTR - 1] = 0; + sprintf(SockPath + strlen(SockPath), "/%s", sty); + if ((s = MakeClientSocket(1)) == -1) + exit(1); + } + bzero((char *)&m, sizeof(m)); + m.type = MSG_COMMAND; + if (attach_tty) + { + strncpy(m.m_tty, attach_tty, sizeof(m.m_tty) - 1); + m.m_tty[sizeof(m.m_tty) - 1] = 0; + } + p = m.m.command.cmd; + n = 0; + for (; *av && n < MAXARGS - 1; ++av, ++n) + { + len = strlen(*av) + 1; + if (p + len >= m.m.command.cmd + sizeof(m.m.command.cmd) - 1) + break; + strcpy(p, *av); + p += len; + } + *p = 0; + m.m.command.nargs = n; + strncpy(m.m.attach.auser, LoginName, sizeof(m.m.attach.auser) - 1); + m.m.command.auser[sizeof(m.m.command.auser) - 1] = 0; + m.protocol_revision = MSG_REVISION; + strncpy(m.m.command.preselect, preselect ? preselect : "", sizeof(m.m.command.preselect) - 1); + m.m.command.preselect[sizeof(m.m.command.preselect) - 1] = 0; + m.m.command.apid = getpid(); + debug1("SendCommandMsg writing '%s'\n", m.m.command.cmd); + if (WriteMessage(s, &m)) + Msg(errno, "write"); + close(s); +} |