diff options
author | George Lebl <jirka@5z.com> | 2003-07-03 21:58:58 +0000 |
---|---|---|
committer | George Lebl <jirka@src.gnome.org> | 2003-07-03 21:58:58 +0000 |
commit | 626ecb2f47471043bcf45ac01bd2b72da7476c87 (patch) | |
tree | 36165dd0002e82762fd903aa6d13d043c4a92457 | |
parent | 9f9f9c473c75568d9ad628619cc7e02cff90e312 (diff) | |
download | gdm-626ecb2f47471043bcf45ac01bd2b72da7476c87.tar.gz |
the details file is read first, capped at 500 lines, and so now we can run
Thu Jul 03 14:57:38 2003 George Lebl <jirka@5z.com>
* daemon/errorgui.c: the details file is read first, capped at 500
lines, and so now we can run the errorbox as the gdm user meaning
no more gtk code as root.
* daemon/gdm.h, daemon/misc.[ch], daemon/xdmcp.c, daemon/slave.c,
daemon/auth.c: Apparently gethostbyaddr can return a dot in the
name field meaning unknown host which is kind of crap, so handle
that. In fact make our own saner gdm_gethostby{addr,name} that
handle such cases and cache last result for 5 seconds. This way we
do a lot less dns lookups since we used to do 1 or 2 (or even 3)
per every xdmcp packet (if tcpwrappers were on). Also instead of
resolving ip to name and back to ip, keep the list of addresses of
the host in the display structure. This all should speed up
XDMCP in general and fix XDMCP for places without proper DNS.
* daemon/errorgui.c, daemon/slave.c, daemon/server.c: /tmp is a much
better choice for fallback HOME then / and /bin/sh is a much better
fallback then /bin/bash.
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | daemon/auth.c | 44 | ||||
-rw-r--r-- | daemon/display.c | 4 | ||||
-rw-r--r-- | daemon/errorgui.c | 91 | ||||
-rw-r--r-- | daemon/gdm.h | 6 | ||||
-rw-r--r-- | daemon/misc.c | 138 | ||||
-rw-r--r-- | daemon/misc.h | 15 | ||||
-rw-r--r-- | daemon/server.c | 2 | ||||
-rw-r--r-- | daemon/slave.c | 35 | ||||
-rw-r--r-- | daemon/xdmcp.c | 84 |
10 files changed, 332 insertions, 108 deletions
@@ -1,3 +1,24 @@ +Thu Jul 03 14:57:38 2003 George Lebl <jirka@5z.com> + + * daemon/errorgui.c: the details file is read first, capped at 500 + lines, and so now we can run the errorbox as the gdm user meaning + no more gtk code as root. + + * daemon/gdm.h, daemon/misc.[ch], daemon/xdmcp.c, daemon/slave.c, + daemon/auth.c: Apparently gethostbyaddr can return a dot in the + name field meaning unknown host which is kind of crap, so handle + that. In fact make our own saner gdm_gethostby{addr,name} that + handle such cases and cache last result for 5 seconds. This way we + do a lot less dns lookups since we used to do 1 or 2 (or even 3) + per every xdmcp packet (if tcpwrappers were on). Also instead of + resolving ip to name and back to ip, keep the list of addresses of + the host in the display structure. This all should speed up + XDMCP in general and fix XDMCP for places without proper DNS. + + * daemon/errorgui.c, daemon/slave.c, daemon/server.c: /tmp is a much + better choice for fallback HOME then / and /bin/sh is a much better + fallback then /bin/bash. + 2003-07-02 Jordi Mallach <jordi@sindominio.net> * gui/*.desktop.in: Fix Terminal entries and add StartupNotify diff --git a/daemon/auth.c b/daemon/auth.c index c0fdb9ac..d1c86117 100644 --- a/daemon/auth.c +++ b/daemon/auth.c @@ -145,8 +145,7 @@ gboolean gdm_auth_secure_display (GdmDisplay *d) { FILE *af, *af_gdm; - struct hostent *hentry = NULL; - struct in_addr *ia = NULL; + gboolean is_local = FALSE; const char lo[] = {127,0,0,1}; guint i; const GList *local_addys = NULL; @@ -258,23 +257,22 @@ gdm_auth_secure_display (GdmDisplay *d) d->hostname = g_strdup (hostname); } local_addys = gdm_peek_local_address_list (); - } else { - /* Find FQDN or IP of display host */ - hentry = gethostbyname (d->hostname); - if (hentry == NULL) { - gdm_error ("gdm_auth_secure_display: Error getting hentry for %s", d->hostname); - /* eeek, there will be nothing to add */ - return FALSE; - } else { - /* first addy, would be loopback in case of local */ - ia = (struct in_addr *) hentry->h_addr_list[0]; + is_local = TRUE; + } else { + is_local = FALSE; + if (gdm_is_local_addr (&(d->addr))) + is_local = TRUE; + for (i = 0; ! is_local && i < d->addr_count; i++) { + if (gdm_is_local_addr (&(d->addrs[i]))) { + is_local = TRUE; + break; + } } } /* Local access also in case the host is very local */ - if (SERVER_IS_LOCAL (d) || - (ia != NULL && gdm_is_local_addr (ia))) { + if (is_local) { gdm_debug ("gdm_auth_secure_display: Setting up socket access"); if ( ! add_auth_entry (d, af, af_gdm, FamilyLocal, @@ -310,14 +308,22 @@ gdm_auth_secure_display (GdmDisplay *d) } gdm_debug ("gdm_auth_secure_display: Setting up network access"); + + if ( ! SERVER_IS_LOCAL (d)) { + /* we should write out an entry for d->addr since + possibly it is not in d->addrs */ + if ( ! add_auth_entry (d, af, af_gdm, FamilyInternet, + (char *)&(d->addr), 4)) + return FALSE; + } /* Network access: Write out an authentication entry for each of * this host's official addresses */ - for (i = 0 ; hentry != NULL && i < hentry->h_length ; i++) { - ia = (struct in_addr *) hentry->h_addr_list[i]; + for (i = 0; i < d->addr_count; i++) { + struct in_addr *ia = &(d->addrs[i]); - if (ia == NULL) - break; + if (memcmp (ia, &(d->addr), sizeof (struct in_addr)) == 0) + continue; if ( ! add_auth_entry (d, af, af_gdm, FamilyInternet, (char *)&ia->s_addr, 4)) @@ -327,7 +333,7 @@ gdm_auth_secure_display (GdmDisplay *d) /* Network access: Write out an authentication entry for each of * this host's local addresses if any */ for (; local_addys != NULL; local_addys = local_addys->next) { - ia = (struct in_addr *) local_addys->data; + struct in_addr *ia = (struct in_addr *) local_addys->data; if (ia == NULL) break; diff --git a/daemon/display.c b/daemon/display.c index 54c0a668..b67fe3a0 100644 --- a/daemon/display.c +++ b/daemon/display.c @@ -389,6 +389,10 @@ gdm_display_dispose (GdmDisplay *d) g_free (d->hostname); d->hostname = NULL; + g_free (d->addrs); + d->addrs = NULL; + d->addr_count = 0; + g_free (d->authfile); d->authfile = NULL; diff --git a/daemon/errorgui.c b/daemon/errorgui.c index b0f4090f..3ea63432 100644 --- a/daemon/errorgui.c +++ b/daemon/errorgui.c @@ -29,6 +29,7 @@ #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> +#include <sys/stat.h> #include "gdm.h" #include "misc.h" @@ -121,23 +122,11 @@ center_window (GtkWidget *window) static void show_errors (GtkWidget *button, gpointer data) { - const char *file = data; - FILE *fp; + const char *details = data; GtkWidget *sw; GtkWidget *label; GtkWidget *dlg = gtk_widget_get_toplevel (button); GtkWidget *parent = button->parent; - GString *gs = g_string_new (NULL); - - fp = fopen (file, "r"); - if (fp != NULL) { - char buf[256]; - while (fgets (buf, sizeof (buf), fp)) - g_string_append (gs, buf); - fclose (fp); - } else { - g_string_printf (gs, _("%s could not be opened"), file); - } gtk_widget_destroy (button); @@ -155,18 +144,23 @@ show_errors (GtkWidget *button, gpointer data) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); - label = gtk_label_new (gs->str); + label = gtk_label_new (ve_sure_string (details)); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), label); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (parent), sw, TRUE, TRUE, 0); - g_string_free (gs, TRUE); - center_window (dlg); } +gboolean g_file_get_contents (const gchar *filename, + gchar **contents, + gsize *length, + GError **error); + + + void gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, const char *details_label, const char *details_file) @@ -184,6 +178,42 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, char *loc; char *display; char *xauthority; + char *details; + + /* First read the details if they exist */ + if (details_file) { + FILE *fp; + struct stat s; + GString *gs = g_string_new (NULL); + + fp = NULL; + if (stat (details_file, &s) == 0) { + if (S_ISREG (s.st_mode)) + fp = fopen (details_file, "r"); + else + g_string_printf (gs, _("%s not a regular file!\n"), details_file); + } + if (fp != NULL) { + char buf[256]; + int lines = 0; + while (fgets (buf, sizeof (buf), fp)) { + g_string_append (gs, buf); + /* cap the lines at 500, that's already + a possibility of 128k of crap */ + if (lines ++ > 500) { + g_string_append (gs, _("\n... File too long to display ...\n")); + break; + } + } + fclose (fp); + } else { + g_string_append_printf (gs, _("%s could not be opened"), details_file); + } + + details = g_string_free (gs, FALSE); + } else { + details = NULL; + } closelog (); @@ -195,14 +225,9 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - /* because details_file may not be readable, we must run as root */ - /* FIXME: we should read in the details file here so that we don't - have to touch the disk again */ - if (details_file == NULL) { - setgid (GdmGroupId); - initgroups (GdmUser, GdmGroupId); - setuid (GdmUserId); - } + setgid (GdmGroupId); + initgroups (GdmUser, GdmGroupId); + setuid (GdmUserId); gdm_desetuid (); @@ -217,8 +242,8 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, if (xauthority != NULL) gnome_setenv ("XAUTHORITY", xauthority, TRUE); /* sanity env stuff */ - gnome_setenv ("SHELL", "/bin/bash", TRUE); - gnome_setenv ("HOME", "/", TRUE); + gnome_setenv ("SHELL", "/bin/sh", TRUE); + gnome_setenv ("HOME", "/tmp", TRUE); openlog ("gdm", LOG_PID, LOG_DAEMON); @@ -250,7 +275,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, G_CALLBACK (show_errors), /* leak? who cares we exit right * away */ - g_strdup (details_file)); + details); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), button, FALSE, FALSE, 3); @@ -362,8 +387,8 @@ gdm_failsafe_question (GdmDisplay *d, if (xauthority != NULL) gnome_setenv ("XAUTHORITY", xauthority, TRUE); /* sanity env stuff */ - gnome_setenv ("SHELL", "/bin/bash", TRUE); - gnome_setenv ("HOME", "/", TRUE); + gnome_setenv ("SHELL", "/bin/sh", TRUE); + gnome_setenv ("HOME", "/tmp", TRUE); openlog ("gdm", LOG_PID, LOG_DAEMON); @@ -507,8 +532,8 @@ gdm_failsafe_yesno (GdmDisplay *d, if (xauthority != NULL) gnome_setenv ("XAUTHORITY", xauthority, TRUE); /* sanity env stuff */ - gnome_setenv ("SHELL", "/bin/bash", TRUE); - gnome_setenv ("HOME", "/", TRUE); + gnome_setenv ("SHELL", "/bin/sh", TRUE); + gnome_setenv ("HOME", "/tmp", TRUE); openlog ("gdm", LOG_PID, LOG_DAEMON); @@ -637,8 +662,8 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, if (xauthority != NULL) gnome_setenv ("XAUTHORITY", xauthority, TRUE); /* sanity env stuff */ - gnome_setenv ("SHELL", "/bin/bash", TRUE); - gnome_setenv ("HOME", "/", TRUE); + gnome_setenv ("SHELL", "/bin/sh", TRUE); + gnome_setenv ("HOME", "/tmp", TRUE); openlog ("gdm", LOG_PID, LOG_DAEMON); diff --git a/daemon/gdm.h b/daemon/gdm.h index bb254a60..1cfbb822 100644 --- a/daemon/gdm.h +++ b/daemon/gdm.h @@ -309,6 +309,12 @@ struct _GdmDisplay { gchar *name; gchar *hostname; struct in_addr addr; + struct in_addr *addrs; /* array of addresses */ + int addr_count; /* number of addresses in array */ + /* Note that the above may in fact be empty even though + addr is set, these are just extra addresses + (it could also contain addr for all we know) */ + guint8 dispstat; guint16 dispnum; guint8 servstat; diff --git a/daemon/misc.c b/daemon/misc.c index e7d1fc4b..3a5c8624 100644 --- a/daemon/misc.c +++ b/daemon/misc.c @@ -1144,6 +1144,144 @@ gdm_locale_from_utf8 (const char *text) return out; } +static GdmHostent * +fillout_hostent (struct hostent *he_, struct in_addr *ia, const char *name) +{ + GdmHostent *he; + + he = g_new0 (GdmHostent, 1); + + he->addrs = NULL; + he->addr_count = 0; + + /* Sometimes if we can't look things up, we could end + up with a dot in the name field which would screw + us up. Weird but apparently possible */ + if (he_ != NULL && + he_->h_name != NULL && + he_->h_name[0] != '\0' && + strcmp (he_->h_name, ".") != 0) { + he->hostname = g_strdup (he_->h_name); + he->not_found = FALSE; + } else { + he->not_found = TRUE; + if (name != NULL) + he->hostname = g_strdup (name); + else /* either ia or name is set */ + he->hostname = g_strdup (inet_ntoa (*ia)); + } + + if (he_ != NULL && he_->h_addrtype == AF_INET) { + int i; + for (i = 0; ; i++) { + struct in_addr *ia_ = (struct in_addr *) (he_->h_addr_list[i]); + if (ia_ == NULL) + break; + } + he->addrs = g_new0 (struct in_addr, i); + he->addr_count = i; + for (i = 0; ; i++) { + struct in_addr *ia_ = (struct in_addr *) he_->h_addr_list[i]; + if (ia_ == NULL) + break; + (he->addrs)[i] = *ia_; + } + } + return he; +} + +GdmHostent * +gdm_gethostbyname (const char *name) +{ + struct hostent *he_; + + /* the cached address */ + static GdmHostent *he = NULL; + static time_t last_time = 0; + static char *cached_hostname = NULL; + + if (cached_hostname != NULL && + strcmp (cached_hostname, name) == 0) { + /* don't check more then every 5 seconds */ + if (last_time + 5 > time (NULL)) + return gdm_hostent_copy (he); + } + + /* Find client hostname */ + he_ = gethostbyname (name); + g_free (cached_hostname); + cached_hostname = g_strdup (name); + + gdm_hostent_free (he); + he = fillout_hostent (he_, NULL, name); + + last_time = time (NULL); + return gdm_hostent_copy (he); +} + +GdmHostent * +gdm_gethostbyaddr (struct in_addr *ia) +{ + struct hostent *he_; + + /* the cached address */ + static GdmHostent *he = NULL; + static time_t last_time = 0; + static struct in_addr cached_addr; + + if (last_time != 0 && + memcmp (&cached_addr, ia, sizeof (struct in_addr)) == 0) { + /* don't check more then every 5 seconds */ + if (last_time + 5 > time (NULL)) + return gdm_hostent_copy (he); + } + + /* Find client hostname */ + he_ = gethostbyaddr ((gchar *) ia, sizeof (struct in_addr), AF_INET); + cached_addr = *ia; + + gdm_hostent_free (he); + he = fillout_hostent (he_, ia, NULL); + + last_time = time (NULL); + return gdm_hostent_copy (he); +} + +GdmHostent * +gdm_hostent_copy (GdmHostent *he) +{ + GdmHostent *cpy; + + if (he == NULL) + return NULL; + + cpy = g_new0 (GdmHostent, 1); + cpy->not_found = he->not_found; + cpy->hostname = g_strdup (he->hostname); + if (he->addr_count == 0) { + cpy->addr_count = 0; + cpy->addrs = NULL; + } else { + cpy->addr_count = he->addr_count; + cpy->addrs = g_new0 (struct in_addr, he->addr_count); + memcpy (cpy->addrs, he->addrs, sizeof (struct in_addr) * he->addr_count); + } + return cpy; +} +void +gdm_hostent_free (GdmHostent *he) +{ + if (he == NULL) + return; + g_free (he->hostname); + he->hostname = NULL; + + g_free (he->addrs); + he->addrs = NULL; + he->addr_count = 0; + + g_free (he); +} /* EOF */ diff --git a/daemon/misc.h b/daemon/misc.h index e84e5436..bc360cbd 100644 --- a/daemon/misc.h +++ b/daemon/misc.h @@ -67,6 +67,21 @@ const GList * gdm_peek_local_address_list (void); gboolean gdm_is_local_addr (struct in_addr *ia); gboolean gdm_is_loopback_addr (struct in_addr *ia); +typedef struct { + gboolean not_found; /* hostname below set to fallback, + as gethostbyaddr/name failed */ + char *hostname; /* never a bogus dot, if + invalid/unknown, then set to the + ip address in string form */ + struct in_addr *addrs; /* array */ + int addr_count; +} GdmHostent; + +GdmHostent * gdm_gethostbyname (const char *name); +GdmHostent * gdm_gethostbyaddr (struct in_addr *ia); +GdmHostent * gdm_hostent_copy (GdmHostent *he); +void gdm_hostent_free (GdmHostent *he); + gboolean gdm_setup_gids (const char *login, gid_t gid); void gdm_desetuid (void); diff --git a/daemon/server.c b/daemon/server.c index 7c67ebdd..a9a4af1e 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -1059,7 +1059,7 @@ gdm_server_spawn (GdmDisplay *d, const char *vtarg) g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) gnome_setenv ("HOME", pwent->pw_dir, TRUE); else - gnome_setenv ("HOME", "/", TRUE); /* Hack */ + gnome_setenv ("HOME", "/tmp", TRUE); /* Hack */ gnome_setenv ("SHELL", pwent->pw_shell, TRUE); gnome_unsetenv ("MAIL"); diff --git a/daemon/slave.c b/daemon/slave.c index 1a9ca161..fc0cb420 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -1737,10 +1737,10 @@ gdm_slave_greeter (void) g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) gnome_setenv ("HOME", pwent->pw_dir, TRUE); else - gnome_setenv ("HOME", "/", TRUE); /* Hack */ + gnome_setenv ("HOME", "/tmp", TRUE); /* Hack */ gnome_setenv ("SHELL", pwent->pw_shell, TRUE); } else { - gnome_setenv ("HOME", "/", TRUE); /* Hack */ + gnome_setenv ("HOME", "/tmp", TRUE); /* Hack */ gnome_setenv ("SHELL", "/bin/sh", TRUE); } gnome_setenv ("PATH", GdmDefaultPath, TRUE); @@ -1989,18 +1989,23 @@ send_chosen_host (GdmDisplay *disp, const char *hostname) { int fd; char *fifopath; - struct hostent *host; + GdmHostent *host; uid_t old; + struct in_addr ia; - host = gethostbyname (hostname); + host = gdm_gethostbyname (hostname); - if (host == NULL) { + if (host->addrs == NULL) { gdm_error ("Cannot get address of host '%s'", hostname); + gdm_hostent_free (host); return; } + /* take first address */ + ia = host->addrs[0]; + gdm_hostent_free (host); gdm_debug ("Sending chosen host address (%s) %s", - hostname, inet_ntoa (*(struct in_addr *)host->h_addr_list[0])); + hostname, inet_ntoa (ia)); fifopath = g_strconcat (GdmServAuthDir, "/.gdmfifo", NULL); @@ -2021,7 +2026,7 @@ send_chosen_host (GdmDisplay *disp, const char *hostname) gdm_fdprintf (fd, "\n%s %d %s\n", GDM_SOP_CHOSEN, disp->indirect_id, - inet_ntoa (*((struct in_addr *)host->h_addr_list[0]))); + inet_ntoa (ia)); close (fd); } @@ -2112,10 +2117,10 @@ gdm_slave_chooser (void) if (g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) gnome_setenv ("HOME", pwent->pw_dir, TRUE); else - gnome_setenv ("HOME", "/", TRUE); /* Hack */ + gnome_setenv ("HOME", "/tmp", TRUE); /* Hack */ gnome_setenv ("SHELL", pwent->pw_shell, TRUE); } else { - gnome_setenv ("HOME", "/", TRUE); /* Hack */ + gnome_setenv ("HOME", "/tmp", TRUE); /* Hack */ gnome_setenv ("SHELL", "/bin/sh", TRUE); } gnome_setenv ("PATH", GdmDefaultPath, TRUE); @@ -3864,9 +3869,9 @@ gdm_slave_exec_script (GdmDisplay *d, const gchar *dir, const char *login, } if (pwent != NULL) { if (ve_string_empty (pwent->pw_dir)) { - gnome_setenv ("HOME", "/", TRUE); - gnome_setenv ("PWD", "/", TRUE); - chdir ("/"); + gnome_setenv ("HOME", "/tmp", TRUE); + gnome_setenv ("PWD", "/tmp", TRUE); + chdir ("/tmp"); } else { gnome_setenv ("HOME", pwent->pw_dir, TRUE); gnome_setenv ("PWD", pwent->pw_dir, TRUE); @@ -3874,9 +3879,9 @@ gdm_slave_exec_script (GdmDisplay *d, const gchar *dir, const char *login, } gnome_setenv ("SHELL", pwent->pw_shell, TRUE); } else { - gnome_setenv ("HOME", "/", TRUE); - gnome_setenv ("PWD", "/", TRUE); - chdir ("/"); + gnome_setenv ("HOME", "/tmp", TRUE); + gnome_setenv ("PWD", "/tmp", TRUE); + chdir ("/tmp"); gnome_setenv ("SHELL", "/bin/sh", TRUE); } diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c index a09c599a..4d264dd8 100644 --- a/daemon/xdmcp.c +++ b/daemon/xdmcp.c @@ -153,7 +153,9 @@ static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa struct in_addr *origin); static void gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa); static void gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type); -static void gdm_xdmcp_send_accept (const char *hostname, struct sockaddr_in *clnt_sa, gint displaynum); +static void gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */, + struct sockaddr_in *clnt_sa, + int displaynum); static void gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa, const char *reason); static void gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid); static void gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid); @@ -163,7 +165,9 @@ static void gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa, static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa, struct in_addr *origin); static gboolean gdm_xdmcp_host_allow (struct sockaddr_in *cnlt_sa); -static GdmDisplay *gdm_xdmcp_display_alloc (struct in_addr *addr, const char *hostname, gint); +static GdmDisplay *gdm_xdmcp_display_alloc (struct in_addr *addr, + GdmHostent *he /* eaten and freed */, + int displaynum); static GdmDisplay *gdm_xdmcp_display_lookup (CARD32 sessid); static void gdm_xdmcp_display_dispose_check (const gchar *name); static void gdm_xdmcp_displays_check (void); @@ -933,25 +937,6 @@ gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa, (int)sizeof (struct sockaddr_in)); } -static char * -get_host_from_addr (struct sockaddr_in *clnt_sa) -{ - char *hostname; - struct hostent *he; - - /* Find client hostname */ - he = gethostbyaddr ((gchar *) &(clnt_sa->sin_addr), - sizeof (struct in_addr), - AF_INET); - - if (he != NULL) { - hostname = g_strdup (he->h_name); - } else { - hostname = g_strdup (inet_ntoa (clnt_sa->sin_addr)); - } - return hostname; -} - static void gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len) { @@ -1082,8 +1067,8 @@ gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len) (gdm_is_local_addr (&(clnt_sa->sin_addr)) || gdm_xdmcp_displays_from_host (&(clnt_sa->sin_addr)) < GdmDispPerHost)) { char *disp; - char *hostname = get_host_from_addr (clnt_sa); - disp = g_strdup_printf ("%s:%d", hostname, clnt_dspnum); + GdmHostent *he = gdm_gethostbyaddr (&(clnt_sa->sin_addr)); + disp = g_strdup_printf ("%s:%d", he->hostname, clnt_dspnum); /* Check if we are already talking to this host */ gdm_xdmcp_display_dispose_check (disp); @@ -1094,11 +1079,11 @@ gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len) /* Don't translate, this goes over the wire to servers where we * don't know the charset or language, so it must be ascii */ gdm_xdmcp_send_decline (clnt_sa, "Maximum pending servers"); + gdm_hostent_free (he); } else { - gdm_xdmcp_send_accept (hostname, clnt_sa, clnt_dspnum); + /* the addrs are NOT copied */ + gdm_xdmcp_send_accept (he /* eaten and freed */, clnt_sa, clnt_dspnum); } - - g_free (hostname); } else { /* Don't translate, this goes over the wire to servers where we * don't know the charset or language, so it must be ascii */ @@ -1120,7 +1105,7 @@ gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len) static void -gdm_xdmcp_send_accept (const char *hostname, +gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */, struct sockaddr_in *clnt_sa, gint displaynum) { @@ -1131,7 +1116,9 @@ gdm_xdmcp_send_accept (const char *hostname, ARRAY8 authdata; GdmDisplay *d; - d = gdm_xdmcp_display_alloc (&(clnt_sa->sin_addr), hostname, displaynum); + d = gdm_xdmcp_display_alloc (&(clnt_sa->sin_addr), + he /* eaten and freed */, + displaynum); authentype.data = (CARD8 *) 0; authentype.length = (CARD16) 0; @@ -1520,18 +1507,24 @@ gdm_xdmcp_host_allow (struct sockaddr_in *clnt_sa) */ extern int hosts_ctl (char *daemon, char *client_name, char *client_addr, char *client_user); - struct hostent *client_he; - gchar *client; + GdmHostent *client_he; + char *client; + gboolean ret; /* Find client hostname */ - client_he = gethostbyaddr ((gchar *) &clnt_sa->sin_addr, - sizeof (struct in_addr), - AF_INET); - - client = (client_he != NULL) ? client_he->h_name : NULL; - + client_he = gdm_gethostbyaddr (&(clnt_sa->sin_addr)); + + if (client_he->not_found) + client = "unknown"; + else + client = client_he->hostname; + /* Check with tcp_wrappers if client is allowed to access */ - return (hosts_ctl ("gdm", client ? client : "unknown", inet_ntoa (clnt_sa->sin_addr), "")); + ret = (hosts_ctl ("gdm", client, inet_ntoa (clnt_sa->sin_addr), "")); + + gdm_hostent_free (client_he); + + return ret; #else /* HAVE_TCPWRAPPERS */ return (TRUE); #endif /* HAVE_TCPWRAPPERS */ @@ -1539,7 +1532,9 @@ gdm_xdmcp_host_allow (struct sockaddr_in *clnt_sa) static GdmDisplay * -gdm_xdmcp_display_alloc (struct in_addr *addr, const char *hostname, gint displaynum) +gdm_xdmcp_display_alloc (struct in_addr *addr, + GdmHostent *he /* eaten and freed */, + int displaynum) { GdmDisplay *d = NULL; @@ -1577,11 +1572,20 @@ gdm_xdmcp_display_alloc (struct in_addr *addr, const char *hostname, gint displa d->timed_login_ok = FALSE; } - d->name = g_strdup_printf ("%s:%d", hostname, + d->name = g_strdup_printf ("%s:%d", he->hostname, displaynum); - d->hostname = g_strdup (hostname); + memcpy (&d->addr, addr, sizeof (struct in_addr)); + d->hostname = he->hostname; + he->hostname = NULL; + d->addrs = he->addrs; + he->addrs = NULL; + d->addr_count = he->addr_count; + he->addr_count = 0; + + gdm_hostent_free (he); + d->slave_notify_fd = -1; d->master_notify_fd = -1; |