open-src/xserver/xorg/make_xkm_output_dir.patch
author Arvind Umrao <Arvind.Umrao@Sun.COM>
Thu, 07 Jul 2011 08:33:27 -0700
changeset 1159 b49e24485bb6
parent 1124 7bc7e624f965
child 1185 f9e65ceb1a8a
permissions -rw-r--r--
7053010 Xvfb/Xephyr fails to start as normal user


Based on Xorg upstream git commit b07602014061cb41540f6a7e74e4132e67aa1117 
From: Alan Coopersmith <[email protected]>
Date: Mon, 22 Aug 2005 21:47:59 +0000

If MAKE_XKM_OUTPUT_DIR is defined, call trans_mkdir to create directory if
it doesn't already exist. (ported from Solaris Xsun bug #5039004)

[Xorg has since dropped upstream, but we still use.]

Updated to include changes to ensure xkb directory & files are writable
by gid 0, to fix bug:
6916317 Changing xkb settings after login not working on snv130

diff --git a/xkb/Makefile.am b/xkb/Makefile.am
index fb3ccbf..5a82e09 100644
--- a/xkb/Makefile.am
+++ b/xkb/Makefile.am
@@ -1,6 +1,7 @@
 noinst_LTLIBRARIES = libxkb.la libxkbstubs.la
 
 AM_CFLAGS = $(DIX_CFLAGS)
+AM_CFLAGS += -DMAKE_XKM_OUTPUT_DIR
 
 DDX_SRCS = \
         ddxBeep.c \
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index a935698..7682228 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -146,6 +146,18 @@ Win32System(const char *cmdline)
 #define System(x) Win32System(x)
 #endif
 
+#ifdef MAKE_XKM_OUTPUT_DIR
+/* Borrow trans_mkdir from Xtransutil.c to more safely make directories */
+# undef X11_t
+# define TRANS_SERVER
+# define PRMSG(lvl,x,a,b,c) \
+	if (lvl <= 1) { LogMessage(X_ERROR,x,a,b,c); } else ((void)0)
+# include <X11/Xtrans/Xtransutil.c>
+# ifndef XKM_OUTPUT_DIR_MODE
+#  define XKM_OUTPUT_DIR_MODE 0775
+# endif
+#endif
+
 static void
 OutputDirectory(
     char* outdir,
@@ -153,7 +165,11 @@ OutputDirectory(
 {
 #ifndef WIN32
     /* Can we write an xkm and then open it too? */
-    if (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0 && (strlen(XKM_OUTPUT_DIR) < size))
+    if ( ( (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0)
+#ifdef MAKE_XKM_OUTPUT_DIR    
+	   || (getuid() == 0 && (trans_mkdir(XKM_OUTPUT_DIR, XKM_OUTPUT_DIR_MODE) == 0))
+#endif
+	     ) && (strlen(XKM_OUTPUT_DIR) < size))
     {
 	(void) strcpy (outdir, XKM_OUTPUT_DIR);
     } else
@@ -195,6 +211,15 @@ XkbDDXCompileKeymapByNames(	XkbDescPtr		xkb,
     const char *xkmfile = "-";
 #endif
 
+    /* save gid and reset to gid 0 before making xkm_output_dir or
+       running xkbcomp to create the xkm file in it. */
+    gid_t	usr_gid = getgid();
+
+    if (setregid(0, usr_gid) < 0)
+        Error("Error in setting regid to 0");
+    if (setegid(0) < 0)
+        Error("Error in setting egid to 0");
+    
     snprintf(keymap, sizeof(keymap), "server-%s", display);
 
     OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
@@ -245,6 +270,11 @@ XkbDDXCompileKeymapByNames(	XkbDescPtr		xkb,
 #else
     out= fopen(tmpname, "w");
 #endif
+
+    if (setregid(usr_gid, 0) < 0)
+        Error("Error in resetting regid");
+    if (setegid(usr_gid) < 0)
+        Error("Error in resetting egid");
     
     if (out!=NULL) {
 #ifdef DEBUG