--- ConsoleKit_orig/pam-ck-connector/Makefile.am 2013-01-08 13:28:05.000000000 +0400 +++ ConsoleKit/pam-ck-connector/Makefile.am 2013-01-08 13:29:57.000000000 +0400 @@ -5,6 +5,7 @@ INCLUDES = \ $(LIBDBUS_CFLAGS) \ -I$(top_builddir)/libck-connector \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ $(NULL) pamlibdir = $(PAM_MODULE_DIR) --- ConsoleKit_orig/pam-ck-connector/pam-ck-connector.c 2013-01-08 13:28:05.000000000 +0400 +++ ConsoleKit/pam-ck-connector/pam-ck-connector.c 2013-01-08 13:35:08.000000000 +0400 @@ -36,11 +36,13 @@ #include #include #include +#include #include #include #include #include #include +#include #ifdef HAVE_PATHS_H #include @@ -228,6 +230,129 @@ return PAM_SUCCESS; } +static const char* +exec_command (char **argvv) +{ + pid_t pid; + int fds[2]; + + if (pipe (fds) != 0) + return NULL; + + pid = fork (); + if (pid == -1) + { + close (fds[0]); + close (fds[1]); + return NULL; + } + + if (pid > 0) /* parent */ + { + close (fds[1]); + + int status = 0; + pid_t retval; + char *output = NULL; + + retval = waitpid (pid, &status, 0); + if ((retval == (pid_t)-1) || (status != 0)) + goto out; + + int len; + char buf[2048]; + len = read (fds[0], buf, sizeof(buf)); + if (len <= 0) + goto out; + + buf[len] = '\0'; + output = strdup (buf); + + out: + close (fds[0]); + return output; + } + else /* child */ + { + close (fds[0]); + + if (geteuid () == 0) { + /* must set the real uid to 0 so the helper will not error + * out if pam is called from setuid binary (su, sudo...) */ + setuid (0); + } + + /* connect stdout to pipe and stdin to /dev/null */ + int i; + i = open (("/dev/null"), O_RDWR); + if (i < 0) + _exit (errno); + + if ((dup2 (i, STDIN_FILENO) == -1) || (dup2 (fds[1], STDOUT_FILENO) == -1)) + _exit (errno); + + for (i = 3; i < sysconf (_SC_OPEN_MAX); i++) + close (i); + + execv (argvv[0], argvv); + _exit (errno); + } + + return NULL; /* will never be reached */ +} + +static char * +bintohex (int len, + const char *bindata) +{ + char *hexdata, *starthex; + register char *s = (char *)malloc (3); + + /* two chars per byte, plus null termination */ + starthex = hexdata = (char *)malloc (2*len + 1); + if (!hexdata) + return NULL; + + for (; len > 0; len--, bindata++) { + sprintf (s, "%02x", (unsigned char)*bindata); + *hexdata++ = s[0]; + *hexdata++ = s[1]; + } + free (s); + *hexdata = '\0'; + return starthex; +} + +static const char * +get_x11_display_device (pam_handle_t *pamh, + const char *x11_display) +{ + /* ck-get-x11-display-device uses XOpenDisplay */ + /* so we need cookie */ + const struct pam_xauth_data *xdt; + char *cktool_cmd[5]; + int res; + char *key; + const char *x11_display_device; + + res = pam_get_item (pamh, PAM_XAUTHDATA, (const void **) &xdt); + if (res != PAM_SUCCESS || xdt == NULL) + return NULL; + + key = bintohex (xdt->datalen, xdt->data); + + cktool_cmd[0] = LIBEXECDIR "/get-x11-display-device.sh"; + cktool_cmd[1] = x11_display; /* displayname */ + cktool_cmd[2] = xdt->name; /* protocolname */ + cktool_cmd[3] = key; /* hexkey */ + cktool_cmd[4] = NULL; + + x11_display_device = exec_command (cktool_cmd); + + free (key); + return x11_display_device; +} + PAM_EXTERN int pam_sm_open_session (pam_handle_t *pamh, int flags, @@ -304,6 +429,10 @@ snprintf (ttybuf, len, _PATH_DEV "%s", display_device); display_device = ttybuf; } + + x11_display_device = NULL; + if (x11_display != NULL) + x11_display_device = get_x11_display_device (pamh, x11_display); remote_host_name = NULL; s = NULL; @@ -330,7 +459,6 @@ } } - x11_display_device = NULL; if ((s = pam_getenv (pamh, "CKCON_X11_DISPLAY_DEVICE")) != NULL) { x11_display_device = s; if (opt_debug) {