diff options
Diffstat (limited to 'crypto/openssh/session.c')
-rw-r--r-- | crypto/openssh/session.c | 482 |
1 files changed, 222 insertions, 260 deletions
diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c index 3cd12d4..6169f33 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/session.c @@ -34,7 +34,6 @@ #include "includes.h" RCSID("$OpenBSD: session.c,v 1.138 2002/06/20 23:05:55 markus Exp $"); -RCSID("$FreeBSD$"); #include "ssh.h" #include "ssh1.h" @@ -59,15 +58,10 @@ RCSID("$FreeBSD$"); #include "session.h" #include "monitor_wrap.h" -#ifdef __FreeBSD__ -#define _PATH_CHPASS "/usr/bin/passwd" -#endif /* __FreeBSD__ */ - -#if defined(HAVE_LOGIN_CAP) || defined(USE_PAM) -#include <libgen.h> -#endif -#ifdef HAVE_LOGIN_CAP -#include <login_cap.h> +#ifdef HAVE_CYGWIN +#include <windows.h> +#include <sys/cygwin.h> +#define is_winnt (GetVersion() < 0x80000000) #endif /* func */ @@ -81,6 +75,9 @@ void do_exec_pty(Session *, const char *); void do_exec_no_pty(Session *, const char *); void do_exec(Session *, const char *); void do_login(Session *, const char *); +#ifdef LOGIN_NEEDS_UTMPX +static void do_pre_login(Session *s); +#endif void do_child(Session *, const char *); void do_motd(void); int check_quietlogin(Session *, const char *); @@ -106,6 +103,10 @@ const char *original_command = NULL; #define MAX_SESSIONS 10 Session sessions[MAX_SESSIONS]; +#ifdef WITH_AIXAUTHENTICATE +char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + #ifdef HAVE_LOGIN_CAP login_cap_t *lc; #endif @@ -209,6 +210,14 @@ do_authenticated(Authctxt *authctxt) close(startup_pipe); startup_pipe = -1; } +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(authctxt->user, + get_canonical_hostname(options.verify_reverse_mapping), + "ssh", &aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); @@ -451,8 +460,12 @@ do_exec_no_pty(Session *s, const char *command) session_proctitle(s); -#ifdef USE_PAM - do_pam_setcred(); +#if defined(USE_PAM) + do_pam_session(s->pw->pw_name, NULL); + do_pam_setcred(1); + if (is_pam_password_change_required()) + packet_disconnect("Password change required but no " + "TTY available"); #endif /* USE_PAM */ /* Fork the child. */ @@ -508,6 +521,10 @@ do_exec_no_pty(Session *s, const char *command) do_child(s, command); /* NOTREACHED */ } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -561,10 +578,10 @@ do_exec_pty(Session *s, const char *command) ptyfd = s->ptyfd; ttyfd = s->ttyfd; -#ifdef USE_PAM - do_pam_session(s->pw->pw_name, basename(s->tty)); - do_pam_setcred(); -#endif /* USE_PAM */ +#if defined(USE_PAM) + do_pam_session(s->pw->pw_name, s->tty); + do_pam_setcred(1); +#endif /* Fork the child. */ if ((pid = fork()) == 0) { @@ -589,13 +606,23 @@ do_exec_pty(Session *s, const char *command) close(ttyfd); /* record login, etc. similar to login(1) */ +#ifndef HAVE_OSF_SIA if (!(options.use_login && command == NULL)) do_login(s, command); +# ifdef LOGIN_NEEDS_UTMPX + else + do_pre_login(s); +# endif +#endif /* Do common processing for the child, such as execing the command. */ do_child(s, command); /* NOTREACHED */ } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -628,6 +655,34 @@ do_exec_pty(Session *s, const char *command) } } +#ifdef LOGIN_NEEDS_UTMPX +static void +do_pre_login(Session *s) +{ + socklen_t fromlen; + struct sockaddr_storage from; + pid_t pid = getpid(); + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + + record_utmp_only(pid, s->tty, s->pw->pw_name, + get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), + (struct sockaddr *)&from); +} +#endif + /* * This is called to fork and execute a command. If another command is * to be forced, execute that instead. @@ -654,24 +709,12 @@ do_exec(Session *s, const char *command) void do_login(Session *s, const char *command) { -#ifndef USE_PAM char *time_string; -#endif socklen_t fromlen; struct sockaddr_storage from; struct passwd * pw = s->pw; pid_t pid = getpid(); -#ifdef __FreeBSD__ -#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ - struct timeval tv; - time_t warntime = DEFAULT_WARN; -#endif /* __FreeBSD__ */ -#ifdef USE_PAM - /* - * Let PAM handle utmp / wtmp. - */ -#else /* * Get IP address of client. If the connection is not a socket, let * the address be 0.0.0.0. @@ -685,104 +728,38 @@ do_login(Session *s, const char *command) fatal_cleanup(); } } -#endif + + /* Record that there was a login on that tty from the remote host. */ + if (!use_privsep) + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, + get_remote_name_or_ip(utmp_len, + options.verify_reverse_mapping), + (struct sockaddr *)&from); #ifdef USE_PAM /* * If password change is needed, do it now. * This needs to occur before the ~/.hushlogin check. */ - if (pam_password_change_required()) { + if (is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); } #endif -#ifdef __FreeBSD__ - if (pw->pw_change || pw->pw_expire) - (void)gettimeofday(&tv, NULL); -#ifdef HAVE_LOGIN_CAP - warntime = login_getcaptime(lc, "warnpassword", - DEFAULT_WARN, DEFAULT_WARN); -#endif /* HAVE_LOGIN_CAP */ -#ifndef USE_PAM - /* - * If the password change time is set and has passed, give the - * user a password expiry notice and chance to change it. - */ - if (pw->pw_change != 0) { - if (tv.tv_sec >= pw->pw_change) { - (void)printf( - "Sorry -- your password has expired.\n"); - log("%s Password expired - forcing change", - pw->pw_name); - if (newcommand != NULL) - xfree(newcommand); - newcommand = xstrdup(_PATH_CHPASS); - } else if (pw->pw_change - tv.tv_sec < warntime && - !check_quietlogin(s, command)) - (void)printf( - "Warning: your password expires on %s", - ctime(&pw->pw_change)); - } -#endif -#ifdef HAVE_LOGIN_CAP - warntime = login_getcaptime(lc, "warnexpire", - DEFAULT_WARN, DEFAULT_WARN); -#endif /* HAVE_LOGIN_CAP */ -#ifndef USE_PAM - if (pw->pw_expire) { - if (tv.tv_sec >= pw->pw_expire) { - (void)printf( - "Sorry -- your account has expired.\n"); - log( - "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s", - pw->pw_name, get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping), s->tty); - exit(254); - } else if (pw->pw_expire - tv.tv_sec < warntime && - !check_quietlogin(s, command)) - (void)printf( - "Warning: your account expires on %s", - ctime(&pw->pw_expire)); - } -#endif /* !USE_PAM */ -#endif /* __FreeBSD__ */ -#ifdef HAVE_LOGIN_CAP - if (!auth_ttyok(lc, basename(s->tty))) { - (void)printf("Permission denied.\n"); - log( - "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s", - pw->pw_name, get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping), s->tty); - exit(254); - } -#endif /* HAVE_LOGIN_CAP */ - /* Record that there was a login on that tty from the remote host. */ - if (!use_privsep) - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, - get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping), - (struct sockaddr *)&from); + if (check_quietlogin(s, command)) + return; #ifdef USE_PAM - if (command == NULL && options.print_lastlog && - !check_quietlogin(s, command) && - !options.use_login && !pam_password_change_required()) + if (!is_pam_password_change_required()) print_pam_messages(); -#else /* !USE_PAM */ - /* - * If the user has logged in before, display the time of last - * login. However, don't display anything extra if a command - * has been specified (so that ssh can be used to execute - * commands on a remote machine without users knowing they - * are going to another machine). Login(1) will do this for - * us as well, so check if login(1) is used - */ +#endif /* USE_PAM */ +#ifdef WITH_AIXAUTHENTICATE + if (aixloginmsg && *aixloginmsg) + printf("%s\n", aixloginmsg); +#endif /* WITH_AIXAUTHENTICATE */ - if (command == NULL && options.print_lastlog && - s->last_login_time != 0 && !check_quietlogin(s, command) && - !options.use_login) { + if (options.print_lastlog && s->last_login_time != 0) { time_string = ctime(&s->last_login_time); if (strchr(time_string, '\n')) *strchr(time_string, '\n') = 0; @@ -792,35 +769,8 @@ do_login(Session *s, const char *command) printf("Last login: %s from %s\r\n", time_string, s->hostname); } -#endif /* !USE_PAM */ - if (command == NULL && !check_quietlogin(s, command) && - !options.use_login) { -#ifdef HAVE_LOGIN_CAP - const char *fname; - char buf[256]; - FILE *f; - - fname = login_getcapstr(lc, "copyright", NULL, NULL); - if (fname != NULL && (f = fopen(fname, "r")) != NULL) { - while (fgets(buf, sizeof(buf), f) != NULL) - fputs(buf, stdout); - fclose(f); - } else -#endif /* HAVE_LOGIN_CAP */ - (void)printf("%s\n\t%s %s\n", - "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", - "The Regents of the University of California. ", - "All rights reserved."); - (void)printf("\n"); - /* - * Print /etc/motd unless a command was specified or printing - * it was disabled in server options or login(1) will be - * used. Note that some machines appear to print it in - * /etc/profile or similar. - */ - do_motd(); - } + do_motd(); } /* @@ -952,76 +902,83 @@ read_environment_file(char ***env, u_int *envsize, fclose(f); } -#ifdef USE_PAM -/* - * Sets any environment variables which have been specified by PAM - */ -static void -do_pam_environment(char ***env, u_int *envsize) +void copy_environment(char **source, char ***env, u_int *envsize) { - char *equals, var_name[512], var_val[512]; - char **pam_env; + char *var_name, *var_val; int i; - if ((pam_env = fetch_pam_environment()) == NULL) + if (source == NULL) return; - - for(i = 0; pam_env[i] != NULL; i++) { - if ((equals = strstr(pam_env[i], "=")) == NULL) - continue; - - if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) { - memset(var_name, '\0', sizeof(var_name)); - memset(var_val, '\0', sizeof(var_val)); - strncpy(var_name, pam_env[i], equals - pam_env[i]); - strcpy(var_val, equals + 1); - - child_set_env(env, envsize, var_name, var_val); + for(i = 0; source[i] != NULL; i++) { + var_name = xstrdup(source[i]); + if ((var_val = strstr(var_name, "=")) == NULL) { + xfree(var_name); + continue; } + *var_val++ = '\0'; + + debug3("Copy environment: %s=%s", var_name, var_val); + child_set_env(env, envsize, var_name, var_val); + + xfree(var_name); } } -#endif /* USE_PAM */ static char ** -do_setup_env(char **env, Session *s, const char *shell) +do_setup_env(Session *s, const char *shell) { char buf[256]; u_int i, envsize; + char **env; struct passwd *pw = s->pw; - if (env == NULL) { - /* Initialize the environment. */ - envsize = 100; - env = xmalloc(envsize * sizeof(char *)); - env[0] = NULL; - } else { - for (envsize = 0; env[envsize] != NULL; ++envsize) - ; - envsize = (envsize < 100) ? 100 : envsize + 50; - env = xrealloc(env, envsize * sizeof(char *)); - } + /* Initialize the environment. */ + envsize = 100; + env = xmalloc(envsize * sizeof(char *)); + env[0] = NULL; + +#ifdef HAVE_CYGWIN + /* + * The Windows environment contains some setting which are + * important for a running system. They must not be dropped. + */ + copy_environment(environ, &env, &envsize); +#endif if (!options.use_login) { /* Set basic environment. */ child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&env, &envsize, "HOME", pw->pw_dir); -#ifndef HAVE_LOGIN_CAP +#ifdef HAVE_LOGIN_CAP + (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); + child_set_env(&env, &envsize, "PATH", getenv("PATH")); +#else /* HAVE_LOGIN_CAP */ +# ifndef HAVE_CYGWIN + /* + * There's no standard path on Windows. The path contains + * important components pointing to the system directories, + * needed for loading shared libraries. So the path better + * remains intact here. + */ +# ifdef SUPERUSER_PATH + child_set_env(&env, &envsize, "PATH", + s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); +# else child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +# endif /* SUPERUSER_PATH */ +# endif /* HAVE_CYGWIN */ +#endif /* HAVE_LOGIN_CAP */ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); child_set_env(&env, &envsize, "MAIL", buf); -#endif /* !HAVE_LOGIN_CAP */ /* Normal systems set SHELL by default. */ child_set_env(&env, &envsize, "SHELL", shell); } if (getenv("TZ")) -#ifdef HAVE_LOGIN_CAP - if (options.use_login) -#endif /* HAVE_LOGIN_CAP */ child_set_env(&env, &envsize, "TZ", getenv("TZ")); /* Set custom environment options from RSA authentication. */ @@ -1055,6 +1012,18 @@ do_setup_env(char **env, Session *s, const char *shell) if (original_command) child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", original_command); + +#ifdef _AIX + { + char *cp; + + if ((cp = getenv("AUTHSTATE")) != NULL) + child_set_env(&env, &envsize, "AUTHSTATE", cp); + if ((cp = getenv("KRB5CCNAME")) != NULL) + child_set_env(&env, &envsize, "KRB5CCNAME", cp); + read_environment_file(&env, &envsize, "/etc/environment"); + } +#endif #ifdef KRB4 if (s->authctxt->krb4_ticket_file) child_set_env(&env, &envsize, "KRBTKFILE", @@ -1065,10 +1034,9 @@ do_setup_env(char **env, Session *s, const char *shell) child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ticket_file); #endif - #ifdef USE_PAM /* Pull in any environment variables that may have been set by PAM. */ - do_pam_environment(&env, &envsize); + copy_environment(fetch_pam_environment(), &env, &envsize); #endif /* USE_PAM */ if (auth_sock_name != NULL) @@ -1181,47 +1149,30 @@ do_nologin(struct passwd *pw) } /* Set login name, uid, gid, and groups. */ -char ** +void do_setusercontext(struct passwd *pw) { - char **env = NULL; +#ifdef HAVE_CYGWIN + if (is_winnt) { +#else /* HAVE_CYGWIN */ + if (getuid() == 0 || geteuid() == 0) { +#endif /* HAVE_CYGWIN */ +#ifdef HAVE_SETPCRED + setpcred(pw->pw_name); +#endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP - char buf[256]; - char **tmpenv; - u_int envsize; - extern char **environ; - - /* Initialize the environment. */ - envsize = 100; - env = xmalloc(envsize * sizeof(char *)); - env[0] = NULL; - - child_set_env(&env, &envsize, "PATH", - (pw->pw_uid == 0) ? - _PATH_STDPATH : _PATH_DEFPATH); - - snprintf(buf, sizeof buf, "%.200s/%.50s", - _PATH_MAILDIR, pw->pw_name); - child_set_env(&env, &envsize, "MAIL", buf); - - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); - - /* Save parent environment */ - tmpenv = environ; - /* Switch to env */ - environ = env; - - if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0) - fatal("setusercontext failed: %s", strerror(errno)); - - /* NOTE: Modified environment now passed to env! */ - env = environ; - /* Restore parent environment */ - environ = tmpenv; + if (setusercontext(lc, pw, pw->pw_uid, + (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { + perror("unable to set user context"); + exit(1); + } +#else +# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID) + /* Sets login uid for accounting */ + if (getluid() == -1 && setluid(pw->pw_uid) == -1) + error("setluid: %s", strerror(errno)); +# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */ -#else /* !HAVE_LOGIN_CAP */ - if (getuid() == 0 || geteuid() == 0) { if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { @@ -1234,14 +1185,23 @@ do_setusercontext(struct passwd *pw) exit(1); } endgrent(); - +# ifdef USE_PAM + /* + * PAM credentials may take the form of supplementary groups. + * These will have been wiped by the above initgroups() call. + * Reestablish them here. + */ + do_pam_setcred(0); +# endif /* USE_PAM */ +# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) + irix_setusercontext(pw); +# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); +#endif } if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); -#endif /* HAVE_LOGIN_CAP */ - return env; } static void @@ -1249,8 +1209,15 @@ launch_login(struct passwd *pw, const char *hostname) { /* Launch login(1). */ - execl("/usr/bin/login", "login", "-h", hostname, + execl(LOGIN_PROGRAM, "login", "-h", hostname, +#ifdef xxxLOGIN_NEEDS_TERM + (s->term ? s->term : "unknown"), +#endif /* LOGIN_NEEDS_TERM */ +#ifdef LOGIN_NO_ENDOPT + "-p", "-f", pw->pw_name, (char *)NULL); +#else "-p", "-f", "--", pw->pw_name, (char *)NULL); +#endif /* Login couldn't be executed, die. */ @@ -1267,15 +1234,11 @@ void do_child(Session *s, const char *command) { extern char **environ; - char **env = NULL; + char **env; char *argv[10]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; u_int i; - int ttyfd = s->ttyfd; -#ifdef HAVE_LOGIN_CAP - int lc_requirehome, lc_nocheckmail; -#endif /* remove hostkey from the child's memory */ destroy_sensitive_data(); @@ -1289,8 +1252,17 @@ do_child(Session *s, const char *command) * switch, so we let login(1) to this for us. */ if (!options.use_login) { +#ifdef HAVE_OSF_SIA + session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty); + if (!check_quietlogin(s, command)) + do_motd(); +#else /* HAVE_OSF_SIA */ do_nologin(pw); - env = do_setusercontext(pw); +# ifdef _AIX + aix_usrinfo(pw, s->tty, s->ttyfd); +# endif /* _AIX */ + do_setusercontext(pw); +#endif /* HAVE_OSF_SIA */ } /* @@ -1302,7 +1274,7 @@ do_child(Session *s, const char *command) shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); #endif - env = do_setup_env(env, s, shell); + env = do_setup_env(s, shell); /* we have to stash the hostname before we close our socket. */ if (options.use_login) @@ -1334,19 +1306,13 @@ do_child(Session *s, const char *command) */ endpwent(); -#ifdef HAVE_LOGIN_CAP - lc_requirehome = login_getcapbool(lc, "requirehome", 0); - lc_nocheckmail = login_getcapbool(lc, "nocheckmail", 0); - login_close(lc); -#endif - /* * Close any extra open file descriptors so that we don\'t have them * hanging around in clients. Note that we want to do this after * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. */ - for (i = 3; i < getdtablesize(); i++) + for (i = 3; i < 64; i++) close(i); /* @@ -1372,7 +1338,7 @@ do_child(Session *s, const char *command) fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); #ifdef HAVE_LOGIN_CAP - if (lc_requirehome) + if (login_getcapbool(lc, "requirehome", 0)) exit(1); #endif } @@ -1412,29 +1378,6 @@ do_child(Session *s, const char *command) exit(1); } - /* - * Check for mail if we have a tty and it was enabled - * in server options. - */ - if (ttyfd != -1 && options.check_mail -#ifdef HAVE_LOGIN_CAP - && !lc_nocheckmail -#endif - ) { - char *mailbox; - struct stat mailstat; - - mailbox = getenv("MAIL"); - if (mailbox != NULL) { - if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0) - ; - else if (mailstat.st_mtime < mailstat.st_atime) - printf("You have mail.\n"); - else - printf("You have new mail.\n"); - } - } - /* Execute the shell. */ argv[0] = argv0; argv[1] = NULL; @@ -1818,7 +1761,7 @@ session_pty_cleanup2(void *session) /* Record that the user has logged out. */ if (s->pid != 0) - record_logout(s->pid, s->tty); + record_logout(s->pid, s->tty, s->pw->pw_name); /* Release the pseudo-tty. */ if (getuid() == 0) @@ -1860,7 +1803,11 @@ session_exit_message(Session *s, int status) } else if (WIFSIGNALED(status)) { channel_request_start(s->chanid, "exit-signal", 0); packet_put_int(WTERMSIG(status)); +#ifdef WCOREDUMP packet_put_char(WCOREDUMP(status)); +#else /* WCOREDUMP */ + packet_put_char(0); +#endif /* WCOREDUMP */ packet_put_cstring(""); packet_put_cstring(""); packet_send(); @@ -2046,8 +1993,23 @@ session_setup_x11fwd(Session *s) s->display = xstrdup(display); s->auth_display = xstrdup(auth_display); } else { +#ifdef IPADDR_IN_DISPLAY + struct hostent *he; + struct in_addr my_addr; + + he = gethostbyname(hostname); + if (he == NULL) { + error("Can't get IP address for X11 DISPLAY."); + packet_send_debug("Can't get IP address for X11 DISPLAY."); + return 0; + } + memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); + snprintf(display, sizeof display, "%.50s:%d.%d", inet_ntoa(my_addr), + s->display_number, s->screen); +#else snprintf(display, sizeof display, "%.400s:%d.%d", hostname, s->display_number, s->screen); +#endif s->display = xstrdup(display); s->auth_display = xstrdup(display); } |