1. --- ConsoleKit_orig/pam-ck-connector/Makefile.am    2013-01-08 13:28:05.000000000 +0400
  2. +++ ConsoleKit/pam-ck-connector/Makefile.am 2013-01-08 13:29:57.000000000 +0400
  3. @@ -5,6 +5,7 @@
  4.  INCLUDES =                     \
  5.     $(LIBDBUS_CFLAGS)           \
  6.     -I$(top_builddir)/libck-connector   \
  7. +   -DLIBEXECDIR=\""$(libexecdir)"\"    \
  8.     $(NULL)
  9.  
  10.  pamlibdir = $(PAM_MODULE_DIR)
  11. --- ConsoleKit_orig/pam-ck-connector/pam-ck-connector.c 2013-01-08 13:28:05.000000000 +0400
  12. +++ ConsoleKit/pam-ck-connector/pam-ck-connector.c  2013-01-08 13:35:08.000000000 +0400
  13. @@ -36,11 +36,13 @@
  14.  #include <string.h>
  15.  #include <syslog.h>
  16.  #include <sys/stat.h>
  17. +#include <sys/wait.h>
  18.  #include <sys/types.h>
  19.  #include <unistd.h>
  20.  #include <dirent.h>
  21.  #include <limits.h>
  22.  #include <errno.h>
  23. +#include <fcntl.h>
  24.  
  25.  #ifdef HAVE_PATHS_H
  26.  #include <paths.h>
  27. @@ -228,6 +230,129 @@
  28.          return PAM_SUCCESS;
  29.  }
  30.  
  31. +static const char*
  32. +exec_command (char **argvv)
  33. +{
  34. +   pid_t pid;
  35. +   int   fds[2];
  36. +  
  37. +   if (pipe (fds) != 0)
  38. +       return NULL;
  39. +  
  40. +   pid = fork ();
  41. +   if (pid == -1)
  42. +   {
  43. +       close (fds[0]);
  44. +       close (fds[1]);
  45. +       return NULL;
  46. +   }
  47. +  
  48. +   if (pid > 0) /* parent */
  49. +   {
  50. +       close (fds[1]);
  51. +      
  52. +       int status = 0;
  53. +       pid_t retval;
  54. +       char *output = NULL;
  55. +      
  56. +       retval = waitpid (pid, &status, 0);
  57. +       if ((retval == (pid_t)-1) || (status != 0))
  58. +           goto out;
  59. +      
  60. +       int len;
  61. +       char buf[2048];
  62. +       len = read (fds[0], buf, sizeof(buf));
  63. +       if (len <= 0)
  64. +           goto out;
  65. +      
  66. +       buf[len] = '\0';
  67. +       output = strdup (buf);
  68. +      
  69. +       out:
  70. +       close (fds[0]);
  71. +       return output;
  72. +   }
  73. +   else /* child */
  74. +   {
  75. +       close (fds[0]);
  76. +      
  77. +       if (geteuid () == 0) {
  78. +           /* must set the real uid to 0 so the helper will not error
  79. +            *    out if pam is called from setuid binary (su, sudo...) */
  80. +           setuid (0);
  81. +       }
  82. +
  83. +       /* connect stdout to pipe and stdin to /dev/null */
  84. +       int i;
  85. +       i = open (("/dev/null"), O_RDWR);
  86. +       if (i < 0)
  87. +           _exit (errno);
  88. +      
  89. +       if ((dup2 (i, STDIN_FILENO) == -1) || (dup2 (fds[1], STDOUT_FILENO) == -1))
  90. +           _exit (errno);
  91. +      
  92. +       for (i = 3; i < sysconf (_SC_OPEN_MAX); i++)
  93. +           close (i);
  94. +      
  95. +       execv (argvv[0], argvv);
  96. +       _exit (errno);
  97. +   }
  98. +  
  99. +   return NULL; /* will never be reached */
  100. +}
  101. +
  102. +static char *
  103. +bintohex (int         len,
  104. +     const char *bindata)
  105. +{
  106. +   char          *hexdata, *starthex;
  107. +   register char *s = (char *)malloc (3);
  108. +  
  109. +   /* two chars per byte, plus null termination */
  110. +   starthex = hexdata = (char *)malloc (2*len + 1);
  111. +   if (!hexdata)
  112. +       return NULL;
  113. +  
  114. +   for (; len > 0; len--, bindata++) {
  115. +       sprintf (s, "%02x", (unsigned char)*bindata);
  116. +       *hexdata++ = s[0];
  117. +       *hexdata++ = s[1];
  118. +   }
  119. +   free (s);
  120. +   *hexdata = '\0';
  121. +   return starthex;
  122. +}
  123. +
  124. +static const char *
  125. +get_x11_display_device (pam_handle_t *pamh,
  126. +           const char   *x11_display)
  127. +{
  128. +   /* ck-get-x11-display-device uses XOpenDisplay */
  129. +   /* so we need cookie */
  130. +   const struct pam_xauth_data *xdt;
  131. +   char                        *cktool_cmd[5];
  132. +   int                          res;
  133. +   char                        *key;
  134. +   const char                  *x11_display_device;
  135. +  
  136. +   res = pam_get_item (pamh, PAM_XAUTHDATA, (const void **) &xdt);
  137. +   if  (res != PAM_SUCCESS || xdt == NULL)
  138. +       return NULL;
  139. +  
  140. +   key = bintohex (xdt->datalen, xdt->data);
  141. +  
  142. +   cktool_cmd[0] = LIBEXECDIR "/get-x11-display-device.sh";
  143. +   cktool_cmd[1] = x11_display; /* displayname */
  144. +   cktool_cmd[2] = xdt->name; /* protocolname */
  145. +   cktool_cmd[3] = key; /* hexkey */
  146. +   cktool_cmd[4] = NULL;
  147. +  
  148. +   x11_display_device = exec_command (cktool_cmd);
  149. +  
  150. +   free (key);
  151. +   return x11_display_device;
  152. +}
  153. +
  154.  PAM_EXTERN int
  155.  pam_sm_open_session (pam_handle_t *pamh,
  156.                       int           flags,
  157. @@ -304,6 +429,10 @@
  158.                  snprintf (ttybuf, len, _PATH_DEV "%s", display_device);
  159.                  display_device = ttybuf;
  160.          }
  161. +        
  162. +        x11_display_device = NULL;
  163. +        if (x11_display != NULL)
  164. +       x11_display_device = get_x11_display_device (pamh, x11_display);
  165.  
  166.          remote_host_name = NULL;
  167.          s = NULL;
  168. @@ -330,7 +459,6 @@
  169.                  }
  170.          }
  171.  
  172. -        x11_display_device = NULL;
  173.          if ((s = pam_getenv (pamh, "CKCON_X11_DISPLAY_DEVICE")) != NULL) {
  174.                  x11_display_device = s;
  175.                  if (opt_debug) {