summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--daemon/auth.c44
-rw-r--r--daemon/display.c4
-rw-r--r--daemon/errorgui.c91
-rw-r--r--daemon/gdm.h6
-rw-r--r--daemon/misc.c138
-rw-r--r--daemon/misc.h15
-rw-r--r--daemon/server.c2
-rw-r--r--daemon/slave.c35
-rw-r--r--daemon/xdmcp.c84
10 files changed, 332 insertions, 108 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f1af10a..e2cd8ed4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;