Commit 266410dc authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

gdmlogin cannot fetch user pictures. SO there is now an interface so that

Tue May 15 02:14:23 2001  George Lebl <jirka@5z.com>

	* daemon/gdm.[ch], daemon/slave.c, gui/gdmlogin.c:  gdmlogin cannot
	  fetch user pictures.  SO there is now an interface so that the
	  slave can check/fetch the pictures for gdmlogin.  Unfortunately
	  imlib is braindead so the way we pass the pictures is to write them
	  to a temp file.  So this is even less friendly on large systems.
	  Paranoia is high however so there should not be a way to exploit
	  it.  Unless you find a pic that kills imlib in which case you can
	  run a dos, so this isn't an option for all systems anyway.
parent e5d5f4b6
Tue May 15 02:14:23 2001 George Lebl <jirka@5z.com>
* daemon/gdm.[ch], daemon/slave.c, gui/gdmlogin.c: gdmlogin cannot
fetch user pictures. SO there is now an interface so that the
slave can check/fetch the pictures for gdmlogin. Unfortunately
imlib is braindead so the way we pass the pictures is to write them
to a temp file. So this is even less friendly on large systems.
Paranoia is high however so there should not be a way to exploit
it. Unless you find a pic that kills imlib in which case you can
run a dos, so this isn't an option for all systems anyway.
Mon May 14 23:54:18 2001 George Lebl <jirka@5z.com>
* gui/gdmlogin.c: Browser fixes. Do smarter sizing of the browser
......
......@@ -64,6 +64,8 @@ gboolean GdmAutomaticLoginEnable = FALSE;
gchar *GdmConfigurator = NULL;
gboolean GdmConfigAvailable = FALSE;
gboolean GdmSystemMenu = FALSE;
gboolean GdmBrowser = FALSE;
gchar *GdmGlobalFaceDir = NULL;
gint GdmXineramaScreen = 0;
gchar *GdmGreeter = NULL;
gchar *GdmChooser = NULL;
......@@ -150,6 +152,8 @@ gdm_config_parse (void)
GdmConfigurator = gnome_config_get_string (GDM_KEY_CONFIGURATOR);
GdmConfigAvailable = gnome_config_get_bool (GDM_KEY_CONFIG_AVAILABLE);
GdmSystemMenu = gnome_config_get_bool (GDM_KEY_SYSMENU);
GdmBrowser = gnome_config_get_bool (GDM_KEY_BROWSER);
GdmGlobalFaceDir = gnome_config_get_string (GDM_KEY_FACEDIR);
GdmXineramaScreen = gnome_config_get_int (GDM_KEY_XINERAMASCREEN);
GdmReboot = gnome_config_get_string (GDM_KEY_REBOOT);
GdmRetryDelay = gnome_config_get_int (GDM_KEY_RETRYDELAY);
......
......@@ -77,6 +77,9 @@
#define GDM_DISABLE '-' /* disable the login screen */
#define GDM_ENABLE '+' /* enable the login screen */
#define GDM_RESETOK 'r' /* reset but don't shake */
#define GDM_NEEDPIC '#' /* need a user picture?, sent after greeter
* is started */
#define GDM_READPIC '%' /* Send a user picture in a temp file */
/* Different login interruptions */
#define GDM_INTERRUPT_TIMED_LOGIN 'T'
......
......@@ -57,9 +57,10 @@ static sigset_t mask;
static gboolean greet = FALSE;
static FILE *greeter;
static pid_t last_killed_pid = 0;
gboolean do_timed_login = FALSE; /* if this is true, login the timed login */
gboolean do_configurator = FALSE; /* if this is true, login as root
* and start the configurator */
static gboolean do_timed_login = FALSE; /* if this is true,
login the timed login */
static gboolean do_configurator = FALSE; /* if this is true, login as root
* and start the configurator */
extern gboolean gdm_first_login;
......@@ -93,6 +94,8 @@ extern gint GdmRetryDelay;
extern gboolean GdmAllowRoot;
extern sigset_t sysmask;
extern gchar *argdelim;
extern gchar *GdmGlobalFaceDir;
extern gboolean GdmBrowser;
/* Local prototypes */
......@@ -689,6 +692,118 @@ gdm_slave_wait_for_login (void)
}
}
/* This is VERY evil! */
static void
run_pictures (void)
{
char *response;
int tempfd;
char tempname[256];
char buf[1024];
size_t bytes;
struct passwd *pwent;
char *picfile;
FILE *fp;
for (;;) {
response = gdm_slave_greeter_ctl (GDM_NEEDPIC, "");
if (gdm_string_empty (response)) {
g_free (response);
return;
}
/* don't quit, we don't want to further confuse a confused
* greeter, just don't send it pics */
if ( ! GdmBrowser) {
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
continue;
}
pwent = getpwnam (response);
if (pwent == NULL) {
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
continue;
}
picfile = g_strconcat (pwent->pw_dir, "/.gnome/photo", NULL);
if (access (picfile, F_OK) != 0) {
g_free (picfile);
picfile = g_strconcat (GdmGlobalFaceDir, "/",
response, NULL);
if (access (picfile, R_OK) == 0) {
gdm_slave_greeter_ctl_no_ret (GDM_READPIC,
picfile);
g_free (picfile);
continue;
}
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
g_free (picfile);
continue;
}
g_free (picfile);
setegid (pwent->pw_gid);
seteuid (pwent->pw_uid);
/* Sanity check on ~user/.gnome/photo */
picfile = g_strconcat (pwent->pw_dir, "/.gnome", NULL);
if ( ! gdm_file_check ("run_pictures", pwent->pw_uid,
picfile, "photo", TRUE, GdmUserMaxFile,
GdmRelaxPerms)) {
g_free (picfile);
seteuid (0);
setegid (GdmGroupId);
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
continue;
}
g_free (picfile);
picfile = g_strconcat (pwent->pw_dir, "/.gnome/photo", NULL);
fp = fopen (picfile, "r");
g_free (picfile);
if (fp == NULL) {
seteuid (0);
setegid (GdmGroupId);
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
continue;
}
strcpy (tempname, "/tmp/gdm-user-picture-XXXXXX");
tempfd = mkstemp (tempname);
if (tempfd < 0) {
fclose (fp);
seteuid (0);
setegid (GdmGroupId);
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
continue;
}
fchmod (tempfd, 0644);
while ((bytes = fread (buf, sizeof (char),
sizeof (buf), fp)) > 0) {
write (tempfd, buf, bytes);
}
fclose (fp);
close (tempfd);
gdm_slave_greeter_ctl_no_ret (GDM_READPIC, tempname);
unlink (tempname);
seteuid (0);
setegid (GdmGroupId);
}
}
static void
gdm_slave_greeter (void)
......@@ -812,6 +927,8 @@ gdm_slave_greeter (void)
greeter = fdopen (STDIN_FILENO, "r");
gdm_debug ("gdm_slave_greeter: Greeter on pid %d", d->greetpid);
run_pictures (); /* Append pictures to greeter if browsing is on */
break;
}
}
......
......@@ -1994,6 +1994,14 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd)
gtk_widget_set_sensitive (login, TRUE);
g_print ("%c\n", STX);
break;
/* These are handled separately so ignore them here and send
* back a NULL response so that the daemon quits sending them */
case GDM_NEEDPIC:
case GDM_READPIC:
g_io_channel_read (source, buf, PIPE_SIZE-1, &len); /* Empty */
g_print ("%c\n", STX);
break;
default:
break;
......@@ -2728,58 +2736,74 @@ gdm_login_sort_func (gpointer d1, gpointer d2)
static GdmLoginUser *
gdm_login_user_alloc (const gchar *logname, uid_t uid, const gchar *homedir)
{
GdmLoginUser *user;
GdkImlibImage *img = NULL;
gchar *filename;
GdmLoginUser *user;
GdkImlibImage *img = NULL;
gchar buf[PIPE_SIZE];
size_t size;
user = g_new0 (GdmLoginUser, 1);
user = g_new0 (GdmLoginUser, 1);
if (!user)
return (NULL);
user->uid = uid;
user->login = g_strdup (logname);
user->homedir = g_strdup (homedir);
user->picture = defface;
user->uid = uid;
user->login = g_strdup (logname);
user->homedir = g_strdup (homedir);
/* read initial request */
do {
while (read (STDIN_FILENO, buf, 1) == 1)
if (buf[0] == STX)
break;
size = read (STDIN_FILENO, buf, sizeof (buf));
if (size <= 0)
return user;
} while (buf[0] != GDM_NEEDPIC);
filename = g_strconcat (homedir, "/.gnome/photo", NULL);
g_print ("%c%s\n", STX, logname);
img = NULL;
if (access (filename, R_OK) == 0) {
img = gdk_imlib_load_image (filename);
} else {
g_free (filename);
filename = g_strconcat (GdmGlobalFaceDir, "/", logname, NULL);
if (access (filename, R_OK) == 0)
img = gdk_imlib_load_image (filename);
do {
while (read (STDIN_FILENO, buf, 1) == 1)
if (buf[0] == STX)
break;
size = read (STDIN_FILENO, buf, sizeof (buf));
if (size <= 0)
return user;
} while (buf[0] != GDM_READPIC);
/* both nul terminate and wipe the trailing \n */
buf[size-1] = '\0';
if (size < 2 ||
access (&buf[1], R_OK) != 0) {
g_print ("%c\n", STX);
return user;
}
}
g_free (filename);
if(img) {
gint w, h;
w = img->rgb_width;
h = img->rgb_height;
if (w > h && w > GdmIconMaxWidth) {
h = h * ((gfloat) GdmIconMaxWidth/w);
w = GdmIconMaxWidth;
} else if (h > GdmIconMaxHeight) {
w = w * ((gfloat) GdmIconMaxHeight/h);
h = GdmIconMaxHeight;
img = gdk_imlib_load_image (&buf[1]);
/* the daemon is now free to go on */
g_print ("%c\n", STX);
if (img != NULL) {
gint w, h;
w = img->rgb_width;
h = img->rgb_height;
if (w > h && w > GdmIconMaxWidth) {
h = h * ((gfloat) GdmIconMaxWidth/w);
w = GdmIconMaxWidth;
} else if (h > GdmIconMaxHeight) {
w = w * ((gfloat) GdmIconMaxHeight/h);
h = GdmIconMaxHeight;
}
maxwidth = MAX (maxwidth, w);
maxheight = MAX (maxheight, h);
user->picture = gdk_imlib_clone_scaled_image (img, w, h);
gdk_imlib_destroy_image (img);
}
maxwidth = MAX (maxwidth, w);
maxheight = MAX (maxheight, h);
user->picture = gdk_imlib_clone_scaled_image (img, w, h);
gdk_imlib_destroy_image (img);
} else {
user->picture = defface;
}
return (user);
return user;
}
......@@ -2877,7 +2901,7 @@ gdm_login_users_init (void)
}
pwent = getpwent();
}
}
endpwent ();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment