gdm r6334 - in trunk: . daemon



Author: mccann
Date: Mon Jul 28 19:30:09 2008
New Revision: 6334
URL: http://svn.gnome.org/viewvc/gdm?rev=6334&view=rev

Log:
2008-07-28  William Jon McCann  <jmccann redhat com>

	* daemon/gdm-display-access-file.c (create_temp_dir),
	(_create_xauth_file_for_user):
	Use per session directories in /var/run/gdm to
	hold user's X11 authorizations database.  This
	allows us to avoid having a writable /var/run/gdm and
	still allows libXau locking to work.



Modified:
   trunk/ChangeLog
   trunk/daemon/gdm-display-access-file.c

Modified: trunk/daemon/gdm-display-access-file.c
==============================================================================
--- trunk/daemon/gdm-display-access-file.c	(original)
+++ trunk/daemon/gdm-display-access-file.c	Mon Jul 28 19:30:09 2008
@@ -27,6 +27,8 @@
 #include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include <glib.h>
 #include <glib-object.h>
@@ -49,6 +51,10 @@
 #define GDM_DISPLAY_ACCESS_COOKIE_SIZE 16
 #endif
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 static void gdm_display_access_file_finalize (GObject * object);
 
 enum
@@ -214,48 +220,127 @@
         return TRUE;
 }
 
+/*
+ * create_temp_dir based on the mkstemp implementation from the GNU C library.
+ * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+ */
+static int
+create_temp_dir (char *tmpl,
+                 int    permissions)
+{
+        char             *XXXXXX;
+        int               count;
+        int               fd;
+        static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+        static const int  NLETTERS = sizeof (letters) - 1;
+        glong             value;
+        GTimeVal          tv;
+        static int        counter = 0;
+
+        /* find the last occurrence of "XXXXXX" */
+        XXXXXX = g_strrstr (tmpl, "XXXXXX");
+
+        if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) {
+                errno = EINVAL;
+                return -1;
+        }
+
+        /* Get some more or less random data.  */
+        g_get_current_time (&tv);
+        value = (tv.tv_usec ^ tv.tv_sec) + counter++;
+
+        for (count = 0; count < 100; value += 7777, ++count) {
+                glong v = value;
+
+                /* Fill in the random bits.  */
+                XXXXXX[0] = letters[v % NLETTERS];
+                v /= NLETTERS;
+                XXXXXX[1] = letters[v % NLETTERS];
+                v /= NLETTERS;
+                XXXXXX[2] = letters[v % NLETTERS];
+                v /= NLETTERS;
+                XXXXXX[3] = letters[v % NLETTERS];
+                v /= NLETTERS;
+                XXXXXX[4] = letters[v % NLETTERS];
+                v /= NLETTERS;
+                XXXXXX[5] = letters[v % NLETTERS];
+
+                /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */
+                fd = g_mkdir (tmpl, permissions);
+                if (fd >= 0) {
+                        return fd;
+                } else if (errno != EEXIST) {
+                        /* Any other error will apply also to other names we might
+                         *  try, and there are 2^32 or so of them, so give up now.
+                         */
+                        return -1;
+                }
+        }
+
+        /* We got out of the loop because we ran out of combinations to try.  */
+        errno = EEXIST;
+        return -1;
+}
+
 static FILE *
 _create_xauth_file_for_user (const char  *username,
                              char       **filename,
                              GError     **error)
 {
         char   *template;
-        int     fd;
+        char   *auth_filename;
+        int     dir_fd;
+        int     file_fd;
         FILE   *fp;
         uid_t   uid;
         gid_t   gid;
 
+        g_assert (filename != NULL);
+
+        *filename = NULL;
+
+        template = NULL;
+        auth_filename = NULL;
         fp = NULL;
+        dir_fd = -1;
+        file_fd = -1;
 
         /* Create directory if not exist, then set permission 01775 and ownership root:gdm */
         if (g_file_test (GDM_XAUTH_DIR, G_FILE_TEST_IS_DIR) == FALSE) {
                 g_unlink (GDM_XAUTH_DIR);
-                if (g_mkdir (GDM_XAUTH_DIR, S_ISVTX|S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) {
+                if (g_mkdir (GDM_XAUTH_DIR, S_ISVTX | S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
                         g_set_error (error,
                                      G_FILE_ERROR,
                                      g_file_error_from_errno (errno),
                                      "%s", g_strerror (errno));
-                        fd = -1;
                         goto out;
                 }
 
-                g_chmod (GDM_XAUTH_DIR, S_ISVTX|S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
+                g_chmod (GDM_XAUTH_DIR, S_ISVTX | S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
                 _get_uid_and_gid_for_user ("gdm", &uid, &gid);
                 chown (GDM_XAUTH_DIR, 0, gid);
         } else {
-                /* if it does exist make sure it has correct mode */
-                g_chmod (GDM_XAUTH_DIR, S_ISVTX|S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
+                /* if it does exist make sure it has correct mode 01775 */
+                g_chmod (GDM_XAUTH_DIR, S_ISVTX | S_IRWXU |S_IRWXG | S_IROTH | S_IXOTH);
+        }
+
+        if (!_get_uid_and_gid_for_user (username, &uid, &gid)) {
+                g_set_error (error,
+                             GDM_DISPLAY_ERROR,
+                             GDM_DISPLAY_ERROR_GETTING_USER_INFO,
+                             _("could not find user \"%s\" on system"),
+                             username);
+                goto out;
+
         }
 
         template = g_strdup_printf (GDM_XAUTH_DIR
-                                    "/auth-cookie-XXXXXXXX-for-%s",
+                                    "/auth-for-%s-XXXXXX",
                                     username);
 
-        fd = g_mkstemp (template);
-        *filename = template;
-        template = NULL;
-
-        if (fd < 0) {
+        /* Initially create with mode 01700 then later chmod after we create database */
+        dir_fd = create_temp_dir (template, S_ISVTX | S_IRWXU);
+        if (dir_fd < 0) {
                 g_set_error (error,
                              G_FILE_ERROR,
                              g_file_error_from_errno (errno),
@@ -263,40 +348,76 @@
                 goto out;
         }
 
-        if (!_get_uid_and_gid_for_user (username, &uid, &gid)) {
+        g_debug ("GdmDisplayAccessFile: chowning %s to %u:%u", template, (guint)uid, (guint)gid);
+        if (fchown (dir_fd, uid, gid) < 0) {
                 g_set_error (error,
-                             GDM_DISPLAY_ERROR,
-                             GDM_DISPLAY_ERROR_GETTING_USER_INFO,
-                             _("could not find user \"%s\" on system"),
-                             username);
-                close (fd);
-                fd = -1;
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             "%s", g_strerror (errno));
+                close (dir_fd);
+                dir_fd = -1;
                 goto out;
+        }
+        close (dir_fd);
+        dir_fd = -1;
+
+        auth_filename = g_build_filename (template, "database", NULL);
+
+        g_debug ("GdmDisplayAccessFile: creating %s", auth_filename);
+        /* mode 00600 */
+        file_fd = g_open (auth_filename,
+                          O_RDWR | O_CREAT | O_EXCL | O_BINARY,
+                          S_IRUSR | S_IWUSR);
 
+        if (file_fd < 0) {
+                g_set_error (error,
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             "%s", g_strerror (errno));
+                goto out;
         }
 
-        if (fchown (fd, uid, gid) < 0) {
+        g_debug ("GdmDisplayAccessFile: chowning %s to %u:%u", auth_filename, (guint)uid, (guint)gid);
+        if (fchown (file_fd, uid, gid) < 0) {
                 g_set_error (error,
                              G_FILE_ERROR,
                              g_file_error_from_errno (errno),
                              "%s", g_strerror (errno));
-                close (fd);
-                fd = -1;
+                close (file_fd);
+                file_fd = -1;
                 goto out;
         }
 
-        fp = fdopen (fd, "w");
+        /* now open up permissions on per-session directory */
+        g_debug ("GdmDisplayAccessFile: chmoding %s to 1777", template);
+        g_chmod (template, S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
 
+        fp = fdopen (file_fd, "w");
         if (fp == NULL) {
                 g_set_error (error,
                              G_FILE_ERROR,
                              g_file_error_from_errno (errno),
                              "%s", g_strerror (errno));
-                close (fd);
-                fd = -1;
+                close (file_fd);
+                file_fd = -1;
                 goto out;
         }
+
+        *filename = auth_filename;
+        auth_filename = NULL;
+
+        /* don't close it */
+        file_fd = -1;
 out:
+        g_free (template);
+        g_free (auth_filename);
+        if (dir_fd != -1) {
+                close (dir_fd);
+        }
+        if (file_fd != -1) {
+                close (file_fd);
+        }
+
         return fp;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]