summaryrefslogtreecommitdiffstats
path: root/pam-ck-connector
diff options
context:
space:
mode:
Diffstat (limited to 'pam-ck-connector')
-rw-r--r--pam-ck-connector/Makefile.am17
-rw-r--r--pam-ck-connector/pam-ck-connector.c228
-rw-r--r--pam-ck-connector/pam_ck_connector.880
3 files changed, 325 insertions, 0 deletions
diff --git a/pam-ck-connector/Makefile.am b/pam-ck-connector/Makefile.am
new file mode 100644
index 0000000..e03923b
--- /dev/null
+++ b/pam-ck-connector/Makefile.am
@@ -0,0 +1,17 @@
+
+if ENABLE_PAM_MODULE
+
+INCLUDES = $(LIBDBUS_CFLAGS) -I$(top_builddir)/libck-connector
+
+pamlib_LTLIBRARIES=pam_ck_connector.la
+pamlibdir=/lib/security
+pam_ck_connector_la_SOURCES = pam-ck-connector.c
+pam_ck_connector_la_LDFLAGS = -no-undefined -module -avoid-version
+pam_ck_connector_la_LIBADD = -lpam $(LIBDBUS_LIBS) $(top_builddir)/libck-connector/libck-connector.la
+
+man_MANS = pam_ck_connector.8
+
+endif
+
+clean-local :
+ rm -f *~
diff --git a/pam-ck-connector/pam-ck-connector.c b/pam-ck-connector/pam-ck-connector.c
new file mode 100644
index 0000000..835be0c
--- /dev/null
+++ b/pam-ck-connector/pam-ck-connector.c
@@ -0,0 +1,228 @@
+/*
+ * pam-ck-connector.c : PAM module for registering with CK
+ *
+ * Copyright (c) 2007 David Zeuthen <davidz@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <ctype.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#define PAM_SM_SESSION
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#include "ck-connector.h"
+
+static int opt_debug = FALSE;
+
+static void
+_parse_pam_args (const pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int i;
+
+ opt_debug = FALSE;
+ for (i = 0; i < argc && argv[i] != NULL; i++) {
+ if (strcmp (argv[i] ,"debug") == 0) {
+ opt_debug = TRUE;
+ } else {
+ pam_syslog (pamh, LOG_ERR, "unknown option: %s", argv[i]);
+ }
+ }
+}
+
+
+PAM_EXTERN int
+pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN int
+pam_sm_setcred (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+static uid_t
+_util_name_to_uid (const char *username, gid_t *default_gid)
+{
+ int rc;
+ uid_t res;
+ char *buf = NULL;
+ unsigned int bufsize;
+ struct passwd pwd;
+ struct passwd *pwdp;
+
+ res = (uid_t) -1;
+
+ bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
+ buf = calloc (sizeof (char), bufsize);
+ rc = getpwnam_r (username, &pwd, buf, bufsize, &pwdp);
+ if (rc != 0 || pwdp == NULL) {
+ goto out;
+ }
+
+ res = pwdp->pw_uid;
+ if (default_gid != NULL)
+ *default_gid = pwdp->pw_gid;
+
+out:
+ free (buf);
+ return res;
+}
+
+/* our singleton */
+static CKConnector *ckc = NULL;
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ if (ckc != NULL) {
+ ckc_free (ckc);
+ ckc = NULL;
+ }
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int ret;
+ const char *user;
+ const char *tty;
+ const char *x11_display;
+ const char *s;
+ uid_t uid;
+ char buf[256];
+
+ ret = PAM_IGNORE;
+
+ _parse_pam_args (pamh, flags, argc, argv);
+
+ /* Register with ConsoleKit as part of the session management */
+ if (ckc != NULL) {
+ pam_syslog (pamh, LOG_ERR, "process already registered with ConsoleKit");
+ goto out;
+ }
+
+ ckc = ckc_new ();
+ if (ckc == NULL) {
+ pam_syslog (pamh, LOG_ERR, "oom creating ConsoleKit connector object");
+ goto out;
+ }
+
+ if (pam_get_user (pamh, &user, NULL) != PAM_SUCCESS || user == NULL) {
+ pam_syslog (pamh, LOG_ERR, "cannot determine username");
+ goto out;
+ }
+
+ if (pam_get_item (pamh, PAM_TTY, (const void **) &tty) != PAM_SUCCESS || tty == NULL) {
+ pam_syslog (pamh, LOG_ERR, "cannot determine tty");
+ goto out;
+ }
+
+ if ((s = pam_getenv (pamh, "CKCON_TTY")) != NULL) {
+ tty = s;
+ if (opt_debug)
+ pam_syslog (pamh, LOG_INFO, "using '%s' as tty (from CKCON_TTY)", tty);
+ }
+
+ x11_display = NULL;
+ if ((s = pam_getenv (pamh, "CKCON_X11_DISPLAY")) != NULL) {
+ x11_display = s;
+ if (opt_debug)
+ pam_syslog (pamh, LOG_INFO, "using '%s' as X11 display (from CKCON_X11_DISPLAY)", x11_display);
+ }
+
+ uid = _util_name_to_uid (user, NULL);
+ if (uid == (uid_t) -1) {
+ pam_syslog (pamh, LOG_ERR, "cannot determine uid for user '%s'", user);
+ goto out;
+ }
+
+ if (!ckc_create_local_session (ckc, uid, tty, x11_display)) {
+ /* this might not be a bug for servers that don't have
+ * the message bus or ConsoleKit daemon running - so
+ * only log a message in debugging mode.
+ */
+ if (opt_debug)
+ pam_syslog (pamh, LOG_DEBUG, "insufficient privileges or D-Bus / ConsoleKit not available");
+ goto out;
+ }
+
+ /* now set the cookie */
+ buf[sizeof (buf) - 1] = '\0';
+ snprintf (buf, sizeof (buf) - 1, "XDG_SESSION_COOKIE=%s", ckc_get_cookie (ckc));
+ if (pam_putenv (pamh, buf) != PAM_SUCCESS) {
+ pam_syslog (pamh, LOG_ERR, "unable to set XDG_SESSION_COOKIE vairable");
+ /* tear down session the hard way */
+ ckc_free (ckc);
+ ckc = NULL;
+ goto out;
+ }
+
+ if (opt_debug) {
+ pam_syslog (pamh, LOG_DEBUG, "registered uid=%d on tty='%s' with ConsoleKit", uid, tty);
+ }
+
+ /* note that we're leaking our CKConnector instance ckc - this
+ * is *by design* such that when the login manager (that uses
+ * us) exits / crashes / etc. ConsoleKit will notice, via D-Bus
+ * connection tracking, that the login session ended.
+ */
+
+ ret = PAM_SUCCESS;
+
+out:
+ return ret;
+}
+
+#ifdef PAM_STATIC
+
+struct pam_module _pam_ckconnector_modstruct = {
+ "pam_ck_connector",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/pam-ck-connector/pam_ck_connector.8 b/pam-ck-connector/pam_ck_connector.8
new file mode 100644
index 0000000..43241a0
--- /dev/null
+++ b/pam-ck-connector/pam_ck_connector.8
@@ -0,0 +1,80 @@
+.\" Title: pam_ck_connector
+.\" Author: David Zeuthen <davidz@redhat.com>
+.\" Date: 02/27/2007
+.\"
+.TH "PAM_CK_CONNECTOR" "8" "02/27/2007" "ConsoleKit Manual" "ConsoleKit Manual"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+pam_ck_connector \- Register sessin with ConsoleKit
+.SH "SYNOPSIS"
+.HP 12
+\fBpam_ck_connector.so\fR [debug]
+.SH "DESCRIPTION"
+.PP
+The pam_ck_connector PAM module registers a login session with
+the system-wide
+.I ConsoleKit
+daemon. This PAM module should be used with
+caution; only local login managers such as
+.B login(1)
+should use this. Since the
+.I ConsoleKit
+daemon can accept both an
+.B tty
+and an X11 display the normal parameters set by PAM are not always
+useful.
+
+An application can therefore override these with the PAM environment
+variables
+.B CKCON_TTY
+and
+.B CHCON_X11_DISPLAY
+(the application should remember to unset these before starting the
+login session).
+
+Also note that the
+.I ConsoleKit
+daemon may reject registration attempts if the given set of data are
+inconsistent with each other. More more information, see the
+.I ConsoleKit
+documentation on the
+.B OpenSessionWithParameters()
+method call on the
+.B org.freedesktop.ConsoleKit.Manager
+D-Bus interface.
+
+If registration with the
+.I ConsoleKit
+daemon succeeds, this PAM module will set the environment variable
+.B XDG_SESSION_COOKIE
+which is used to defined membership of a login session.
+
+This PAM module has the side effect that it creates a connection to
+the system message bus that is kept open until the session ends. This
+is used by the
+.I ConsoleKit
+daemon to track the life-cycle of the
+session and, as such, should the login manager crash, the session will
+be properly unregistered.
+
+.SH "OPTIONS"
+.PP
+.TP 3n
+\fBdebug\fR
+Print debug information.
+.fi
+.RE
+.sp
+.SH "SEE ALSO"
+.PP
+
+\fBpam.conf\fR(5),
+\fBpam.d\fR(8),
+\fBpam\fR(8),
+\fBdbus-daemon\fR(1)
+.SH "AUTHOR"
+.PP
+pam_ck_connector was written by David Zeuthen <davidz@redhat.com>.