diff options
author | William Jon McCann <mccann@jhu.edu> | 2005-07-19 23:39:43 +0000 |
---|---|---|
committer | William Jon McCann <mccann@src.gnome.org> | 2005-07-19 23:39:43 +0000 |
commit | f3806b9da53dd41301c27258711dbf6d84bb913a (patch) | |
tree | 73e0297531a5de206a6a8066b5b0a47383ed51ef /daemon | |
parent | 3d38a4c9747ca77a3621fff99ed15db371968e0b (diff) | |
download | gdm-f3806b9da53dd41301c27258711dbf6d84bb913a.tar.gz |
Use common function for loading face images.
2005-07-19 William Jon McCann <mccann@jhu.edu>
* gui/greeter/greeter_item_ulist.c (gdm_greeter_users_init):
Use common function for loading face images.
* gui/greeter/greeter.c (greeter_ctrl_handler):
Update for new common code.
* gui/gdmuser.c (gdm_user_alloc): Use common function for
loading face images.
(setup_user): Define as static.
* gui/gdmlogin.c (gdm_kill_thingies): Make static.
(gdm_login_ctrl_handler): Update for new gdm_common_login_sound.
Add gdm_kill_thingies before all abort calls since they are
not in gdm_common_abort anymore.
(main): Use new common get face function.
* gui/Makefile.am:
* gui/gdmcommon.c (gdm_common_show_info_msg, gdm_common_login_sound):
Make more common by not depending on external variables.
(gdm_common_abort): Make more common by not depending on
external functions.
(gdm_common_get_face): Add a common function for loading
face images.
* daemon/slave.c (path_is_local, check_user_file)
(check_global_file, get_facefile_from_gnome2_dir_config)
(get_facefile_from_home, get_facefile_from_global, run_pictures):
Don't stat or read from remote home directories. Fixes #310545.
* configure.in:
* daemon/Makefile.am:
* daemon/fstype.c: Add ability to detect filesystem types.
* gui/greeter/greeter_item_ulist.c (gdm_greeter_users_init):
* gui/gdmlogin.c (main):
Try GTK+ themed icon stock_person before falling back to
nobody.png. Fixes #310906.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/fstype.c | 420 | ||||
-rw-r--r-- | daemon/slave.c | 421 |
3 files changed, 665 insertions, 177 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index f304aa69..14047950 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -29,6 +29,7 @@ gdm_binary_SOURCES = \ gdm.h \ display.c \ display.h \ + fstype.c \ slave.c \ slave.h \ server.c \ diff --git a/daemon/fstype.c b/daemon/fstype.c new file mode 100644 index 00000000..e6bef2fc --- /dev/null +++ b/daemon/fstype.c @@ -0,0 +1,420 @@ +/* fstype.c -- determine type of filesystems that files are on + Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This code was relicensed by the FSF on May 1 2002 + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + this file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + +#include <config.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#ifdef STDC_HEADERS +#include <stdlib.h> +#else +extern int errno; +#endif +#include <string.h> +#include <glib.h> +#ifdef HAVE_LIBGEN_H +#include <libgen.h> +#endif + +#if __STDC__ +# define P_(s) s +#else +# define P_(s) () +#endif + +static char *filesystem_type_uncached P_((char *path, char *relpath, struct stat *statp)); + +void fstype_internal_error (int level, int num, char const *fmt, ...); + +#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */ +static int xatoi P_((char *cp)); +#endif + +#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +#include <mntent.h> +#if !defined(MOUNTED) +# if defined(MNT_MNTTAB) /* HP-UX. */ +# define MOUNTED MNT_MNTTAB +# endif +# if defined(MNTTABNAME) /* Dynix. */ +# define MOUNTED MNTTABNAME +# endif +#endif +#endif + +#ifdef FSTYPE_GETMNT /* Ultrix. */ +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/fs_types.h> +#endif + +#ifdef FSTYPE_USG_STATFS /* SVR3. */ +#include <sys/statfs.h> +#include <sys/fstyp.h> +#endif + +#ifdef FSTYPE_STATVFS /* SVR4. */ +#include <sys/statvfs.h> +#include <sys/fstyp.h> +#endif + +#ifdef FSTYPE_STATFS /* 4.4BSD. */ +#include <sys/param.h> /* NetBSD needs this. */ +#include <sys/mount.h> + +#ifndef MFSNAMELEN /* NetBSD defines this. */ +static char * +fstype_to_string (t) + short t; +{ +#ifdef INITMOUNTNAMES /* Defined in 4.4BSD, not in NET/2. */ + static char *mn[] = INITMOUNTNAMES; + if (t >= 0 && t <= MOUNT_MAXTYPE) + return mn[t]; + else + return "?"; +#else /* !INITMOUNTNAMES */ + switch (t) + { + case MOUNT_UFS: + return "ufs"; + case MOUNT_NFS: + return "nfs"; +#ifdef MOUNT_PC + case MOUNT_PC: + return "pc"; +#endif +#ifdef MOUNT_MFS + case MOUNT_MFS: + return "mfs"; +#endif +#ifdef MOUNT_LO + case MOUNT_LO: + return "lofs"; +#endif +#ifdef MOUNT_TFS + case MOUNT_TFS: + return "tfs"; +#endif +#ifdef MOUNT_TMP + case MOUNT_TMP: + return "tmp"; +#endif +#ifdef MOUNT_MSDOS + case MOUNT_MSDOS: + return "msdos"; +#endif +#ifdef MOUNT_ISO9660 + case MOUNT_ISO9660: + return "iso9660fs"; +#endif + default: + return "?"; + } +#endif /* !INITMOUNTNAMES */ +} +#endif /* !MFSNAMELEN */ +#endif /* FSTYPE_STATFS */ + +#ifdef FSTYPE_AIX_STATFS /* AIX. */ +#include <sys/vmount.h> +#include <sys/statfs.h> + +#define FSTYPE_STATFS /* Otherwise like 4.4BSD. */ +#define f_type f_vfstype + +static char * +fstype_to_string (t) + short t; +{ + switch (t) + { + case MNT_AIX: +#if 0 /* NFS filesystems are actually MNT_AIX. */ + return "aix"; +#endif + case MNT_NFS: + return "nfs"; + case MNT_JFS: + return "jfs"; + case MNT_CDROM: + return "cdrom"; + default: + return "?"; + } +} +#endif /* FSTYPE_AIX_STATFS */ + +#ifdef AFS +#include <netinet/in.h> +#include <afs/venus.h> +#if __STDC__ +/* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */ +#undef _VICEIOCTL +#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl)) +#endif +#ifndef _IOW +/* AFS on Solaris 2.3 doesn't get this definition. */ +#include <sys/ioccom.h> +#endif + +static int +in_afs (path) + char *path; +{ + static char space[2048]; + struct ViceIoctl vi; + + vi.in_size = 0; + vi.out_size = sizeof (space); + vi.out = space; + + if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1) + && (errno == EINVAL || errno == ENOENT)) + return 0; + return 1; +} +#endif /* AFS */ + +/* Nonzero if the current filesystem's type is known. */ +static int fstype_known = 0; + +char *filesystem_type (char *path, char *relpath, struct stat *statp); +/* Return a static string naming the type of filesystem that the file PATH, + described by STATP, is on. + RELPATH is the file name relative to the current directory. + Return "unknown" if its filesystem type is unknown. */ + +char * +filesystem_type (char *path, char *relpath, struct stat *statp) +{ + static char *current_fstype = NULL; + static dev_t current_dev; + + if (current_fstype != NULL) + { + if (fstype_known && statp->st_dev == current_dev) + return current_fstype; /* Cached value. */ + g_free (current_fstype); + } + current_dev = statp->st_dev; + current_fstype = filesystem_type_uncached (path, relpath, statp); + return current_fstype; +} + +void +fstype_internal_error (int level, int num, char const *fmt, ...) +{ +} + +/* Return a newly allocated string naming the type of filesystem that the + file PATH, described by STATP, is on. + RELPATH is the file name relative to the current directory. + Return "unknown" if its filesystem type is unknown. */ + +static char * +filesystem_type_uncached (char *path, char *relpath, struct stat *statp) +{ + char *type = NULL; + +#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ + char *table = MOUNTED; + FILE *mfp; + struct mntent *mnt; + + mfp = setmntent (table, "r"); + if (mfp == NULL) { + fstype_internal_error (1, errno, "%s", table); + goto no_mtab; + } + + /* Find the entry with the same device number as STATP, and return + that entry's fstype. */ + while (type == NULL && (mnt = getmntent (mfp))) + { + char *devopt; + dev_t dev; + struct stat disk_stats; + +#ifdef MNTTYPE_IGNORE + if (!strcmp (mnt->mnt_type, MNTTYPE_IGNORE)) + continue; +#endif + + /* Newer systems like SunOS 4.1 keep the dev number in the mtab, + in the options string. For older systems, we need to stat the + directory that the filesystem is mounted on to get it. + + Unfortunately, the HPUX 9.x mnttab entries created by automountq + contain a dev= option but the option value does not match the + st_dev value of the file (maybe the lower 16 bits match?). */ + +#if !defined(hpux) && !defined(__hpux__) + devopt = strstr (mnt->mnt_opts, "dev="); + if (devopt) + { + if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X')) + dev = xatoi (devopt + 6); + else + dev = xatoi (devopt + 4); + } + else +#endif /* not hpux */ + { + if (stat (mnt->mnt_dir, &disk_stats) == -1) { + if (errno == EACCES) + continue; + else + fstype_internal_error (1, errno, "error in %s: %s", table, mnt->mnt_dir); + } + dev = disk_stats.st_dev; + } + + if (dev == statp->st_dev) + type = mnt->mnt_type; + } + + if (endmntent (mfp) == 0) + fstype_internal_error (0, errno, "%s", table); + no_mtab: +#endif + +#ifdef FSTYPE_GETMNT /* Ultrix. */ + int offset = 0; + struct fs_data fsd; + + while (type == NULL + && getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0) + { + if (fsd.fd_req.dev == statp->st_dev) + type = gt_names[fsd.fd_req.fstype]; + } +#endif + +#ifdef FSTYPE_USG_STATFS /* SVR3. */ + struct statfs fss; + char typebuf[FSTYPSZ]; + + if (statfs (relpath, &fss, sizeof (struct statfs), 0) == -1) + { + /* Don't die if a file was just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else if (!sysfs (GETFSTYP, fss.f_fstyp, typebuf)) + type = typebuf; +#endif + +#ifdef FSTYPE_STATVFS /* SVR4. */ + struct statvfs fss; + + if (statvfs (relpath, &fss) == -1) + { + /* Don't die if a file was just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else + type = fss.f_basetype; +#endif + +#ifdef FSTYPE_STATFS /* 4.4BSD. */ + struct statfs fss; + char *p; + + if (S_ISLNK (statp->st_mode)) + p = dirname (relpath); + else + p = relpath; + + if (statfs (p, &fss) == -1) + { + /* Don't die if symlink to nonexisting file, or a file that was + just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else + { +#ifdef MFSNAMELEN /* NetBSD. */ + type = fss.f_fstypename; +#else + type = fstype_to_string (fss.f_type); +#endif + } + if (p != relpath) + free (p); +#endif + +#ifdef AFS + if ((!type || !strcmp (type, "xx")) && in_afs (relpath)) + type = "afs"; +#endif + + /* An unknown value can be caused by an ENOENT error condition. + Don't cache those values. */ + fstype_known = (type != NULL); + + return g_strdup (type ? type : "unknown"); +} + +#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */ +/* Return the value of the hexadecimal number represented by CP. + No prefix (like '0x') or suffix (like 'h') is expected to be + part of CP. */ + +static int +xatoi (char *cp) +{ + int val; + + val = 0; + while (*cp) + { + if (*cp >= 'a' && *cp <= 'f') + val = val * 16 + *cp - 'a' + 10; + else if (*cp >= 'A' && *cp <= 'F') + val = val * 16 + *cp - 'A' + 10; + else if (*cp >= '0' && *cp <= '9') + val = val * 16 + *cp - '0'; + else + break; + cp++; + } + return val; +} +#endif diff --git a/daemon/slave.c b/daemon/slave.c index 9cf63b23..f3d450b5 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * GDM - The GNOME Display Manager * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net> * * This program is free software; you can redistribute it and/or modify @@ -2097,6 +2099,240 @@ is_in_trusted_pic_dir (const char *path) return FALSE; } +static GHashTable *fstype_hash = NULL; +extern char *filesystem_type (char *path, char *relpath, struct stat *statp); + +static gboolean +path_is_local (const char *path) +{ + gpointer local = NULL; + + if (path == NULL) + return FALSE; + + if (fstype_hash == NULL) + fstype_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + else + local = g_hash_table_lookup (fstype_hash, path); + + if (local == NULL) { + struct stat statbuf; + + if (stat (path, &statbuf) == 0) { + char *type = filesystem_type ((char *)path, (char *)path, &statbuf); + gboolean is_local = ((strcmp (type, "nfs") != 0) && + (strcmp (type, "afs") != 0) && + (strcmp (type, "autofs") != 0) && + (strcmp (type, "unknown") != 0) && + (strcmp (type, "ncpfs") != 0)); + local = GINT_TO_POINTER (is_local ? 1 : -1); + g_hash_table_insert (fstype_hash, g_strdup (path), local); + } + } + + return GPOINTER_TO_INT (local) > 0; +} + +static gboolean +check_user_file (const char *path, + guint uid) +{ + char *dir; + char *file; + gboolean is_ok; + + if (path == NULL) + return FALSE; + + if (access (path, R_OK) != 0) + return FALSE; + + dir = g_path_get_dirname (path); + file = g_path_get_basename (path); + + is_ok = gdm_file_check ("run_pictures", + uid, + dir, + file, + TRUE, TRUE, + GdmUserMaxFile, + GdmRelaxPerms); + g_free (dir); + g_free (file); + + return is_ok; +} + +static gboolean +check_global_file (const char *path, + guint uid) +{ + if (path == NULL) + return FALSE; + + if (access (path, R_OK) != 0) + return FALSE; + + return TRUE; +} + +static char * +get_facefile_from_gnome2_dir_config (const char *homedir, + guint uid) +{ + char *picfile = NULL; + char *cfgdir; + + /* Sanity check on ~user/.gnome2/gdm */ + cfgdir = g_build_filename (homedir, ".gnome2", "gdm", NULL); + if (G_LIKELY (check_user_file (cfgdir, uid))) { + VeConfig *cfg; + char *cfgfile; + + cfgfile = g_build_filename (homedir, ".gnome2", "gdm", NULL); + cfg = ve_config_new (cfgfile); + g_free (cfgfile); + + picfile = ve_config_get_string (cfg, "face/picture="); + ve_config_destroy (cfg); + + /* must exist and be absolute (note that this check + * catches empty strings)*/ + /* Note that these days we just set ~/.face */ + if G_UNLIKELY (picfile != NULL && + (picfile[0] != '/' || + /* this catches readability by user */ + access (picfile, R_OK) != 0)) { + g_free (picfile); + picfile = NULL; + } + + if (picfile != NULL) { + char buf[PATH_MAX]; + if (realpath (picfile, buf) == NULL) { + g_free (picfile); + picfile = NULL; + } else { + g_free (picfile); + picfile = g_strdup (buf); + } + } + + if G_UNLIKELY (picfile != NULL) { + if (! is_in_trusted_pic_dir (picfile)) { + /* if not in trusted dir, check it out */ + + /* Note that strict permissions checking is done + * on this file. Even if it may not even be owned by the + * user. This setting should ONLY point to pics in trusted + * dirs. */ + if (! check_user_file (picfile, uid)) { + g_free (picfile); + picfile = NULL; + } + } + } + } + g_free (cfgdir); + + return picfile; +} + +static char * +get_facefile_from_home (const char *homedir, + guint uid) +{ + char *picfile = NULL; + char *path; + gboolean is_local; + + /* special case: look at parent of home to detect autofs + this is so we don't try to trigger an automount */ + path = g_path_get_dirname (homedir); + is_local = path_is_local (path); + g_free (path); + + /* now check that home dir itself is local */ + if (is_local) { + is_local = path_is_local (homedir); + } + + /* only look at local home directories so we don't try to + read from remote (e.g. NFS) volumes */ + if (! is_local) + return NULL; + + + picfile = g_build_filename (homedir, ".face", NULL); + + if (check_user_file (picfile, uid)) + return picfile; + else { + g_free (picfile); + picfile = NULL; + } + + picfile = g_build_filename (homedir, ".face.icon", NULL); + + if (check_user_file (picfile, uid)) + return picfile; + else { + g_free (picfile); + picfile = NULL; + } + + picfile = get_facefile_from_gnome2_dir_config (homedir, uid); + if (check_user_file (picfile, uid)) + return picfile; + else { + g_free (picfile); + picfile = NULL; + } + + /* Nothing found yet, try the old locations */ + + picfile = g_build_filename (homedir, ".gnome2", "photo", NULL); + if (check_user_file (picfile, uid)) + return picfile; + else { + g_free (picfile); + picfile = NULL; + } + + picfile = g_build_filename (homedir, ".gnome", "photo", NULL); + if (check_user_file (picfile, uid)) + return picfile; + else { + g_free (picfile); + picfile = NULL; + } + + return NULL; +} + +static gchar * +get_facefile_from_global (const char *username, + guint uid) +{ + char *picfile = NULL; + + /* Try the global face directory */ + + picfile = g_build_filename (GdmGlobalFaceDir, + username, NULL); + + if (check_global_file (picfile, uid)) + return picfile; + + picfile = gdm_make_filename (GdmGlobalFaceDir, + username, ".png"); + + if (check_global_file (picfile, uid)) + return picfile; + + return NULL; +} + /* This is VERY evil! */ static void run_pictures (void) @@ -2107,9 +2343,7 @@ run_pictures (void) size_t bytes; struct passwd *pwent; char *picfile; - char *picdir; FILE *fp; - char *cfgdir; response = NULL; for (;;) { @@ -2140,182 +2374,15 @@ run_pictures (void) continue; } - if G_LIKELY (picfile == NULL) { - picfile = g_build_filename (pwent->pw_dir, ".face", NULL); - if (access (picfile, R_OK) != 0) { - g_free (picfile); - picfile = NULL; - } else if G_UNLIKELY ( ! gdm_file_check ("run_pictures", pwent->pw_uid, - pwent->pw_dir, ".face", TRUE, TRUE, GdmUserMaxFile, - GdmRelaxPerms)) { - g_free (picfile); - - NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); - - gdm_slave_greeter_ctl_no_ret (GDM_READPIC, ""); - continue; - } - } - - if (picfile == NULL) { - picfile = g_build_filename (pwent->pw_dir, ".face.icon", NULL); - if (access (picfile, R_OK) != 0) { - g_free (picfile); - picfile = NULL; - } else if G_UNLIKELY ( ! gdm_file_check ("run_pictures", pwent->pw_uid, - pwent->pw_dir, ".face.icon", TRUE, TRUE, GdmUserMaxFile, - GdmRelaxPerms)) { - g_free (picfile); - - NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); - - gdm_slave_greeter_ctl_no_ret (GDM_READPIC, ""); - continue; - } - } - - if (picfile == NULL) { - /* Sanity check on ~user/.gnome2/gdm */ - cfgdir = g_build_filename (pwent->pw_dir, ".gnome2", "gdm", NULL); - if G_LIKELY (gdm_file_check ("run_pictures", pwent->pw_uid, - cfgdir, "gdm", TRUE, TRUE, GdmUserMaxFile, - GdmRelaxPerms)) { - VeConfig *cfg; - char *cfgfile; - - cfgfile = g_build_filename (pwent->pw_dir, ".gnome2", "gdm", NULL); - cfg = ve_config_new (cfgfile); - g_free (cfgfile); - picfile = ve_config_get_string (cfg, "face/picture="); - ve_config_destroy (cfg); - - /* must exist and be absolute (note that this check - * catches empty strings)*/ - /* Note that these days we just set ~/.face */ - if G_UNLIKELY (picfile != NULL && - (picfile[0] != '/' || - /* this catches readability by user */ - access (picfile, R_OK) != 0)) { - g_free (picfile); - picfile = NULL; - } - - if (picfile != NULL) { - char buf[PATH_MAX]; - if (realpath (picfile, buf) == NULL) { - g_free (picfile); - picfile = NULL; - } else { - g_free (picfile); - picfile = g_strdup (buf); - } - } - - if G_UNLIKELY (picfile != NULL) { - char *dir; - char *base; - - /* if in trusted dir, just use it */ - if (is_in_trusted_pic_dir (picfile)) { - struct stat s; - - if (stat (picfile, &s) != 0 || - ! S_ISREG (s.st_mode)) { - g_free (picfile); - picfile = g_strdup (""); - } - NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); - - g_free (cfgdir); - - gdm_slave_greeter_ctl_no_ret (GDM_READPIC, - picfile); - g_free (picfile); - continue; - } - - /* if not in trusted dir, check it out */ - dir = g_path_get_dirname (picfile); - base = g_path_get_basename (picfile); - - /* Note that strict permissions checking is done - * on this file. Even if it may not even be owned by the - * user. This setting should ONLY point to pics in trusted - * dirs. */ - if (ve_string_empty (dir) || - ve_string_empty (base) || - ! gdm_file_check ("run_pictures", pwent->pw_uid, - dir, base, TRUE, TRUE, GdmUserMaxFile, - GdmRelaxPerms)) { - g_free (picfile); - picfile = NULL; - } - - g_free (base); - g_free (dir); - } - } - g_free (cfgdir); - } - - /* Nothing found yet, try the old location, - * and if we don't find anything there we try the global - * dir. So this is NOT JUST A FALLBACK, don't remove - * this branch in the future! */ - if (picfile == NULL) { - picfile = g_build_filename (pwent->pw_dir, ".gnome2", "photo", NULL); - picdir = g_build_filename (pwent->pw_dir, ".gnome2", NULL); - if (access (picfile, F_OK) != 0) { - g_free (picfile); - picfile = g_build_filename (pwent->pw_dir, ".gnome", "photo", NULL); - g_free (picdir); - picdir = g_build_filename (pwent->pw_dir, ".gnome", NULL); - } - if (access (picfile, F_OK) != 0) { - NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); + picfile = get_facefile_from_home (pwent->pw_dir, pwent->pw_uid); - /* Try the global face directory */ + if (! picfile) + picfile = get_facefile_from_global (pwent->pw_name, pwent->pw_uid); - g_free (picfile); - g_free (picdir); - picfile = g_build_filename (GdmGlobalFaceDir, - response, NULL); - - if (access (picfile, R_OK) == 0) { - gdm_slave_greeter_ctl_no_ret (GDM_READPIC, - picfile); - g_free (picfile); - continue; - } - - g_free (picfile); - picfile = gdm_make_filename (GdmGlobalFaceDir, - response, ".png"); - - 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; - } - - /* Sanity check on ~user/.gnome[2]/photo */ - if ( ! gdm_file_check ("run_pictures", pwent->pw_uid, - picdir, "photo", TRUE, TRUE, GdmUserMaxFile, - GdmRelaxPerms)) { - g_free (picdir); - - NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); - - gdm_slave_greeter_ctl_no_ret (GDM_READPIC, ""); - continue; - } - g_free (picdir); + if (! picfile) { + NEVER_FAILS_root_set_euid_egid (0, GdmGroupId); + gdm_slave_greeter_ctl_no_ret (GDM_READPIC, ""); + continue; } VE_IGNORE_EINTR (r = stat (picfile, &s)); |