From 1905aa0cb4a680308949e366c21803bcf542d9e1 Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Wed, 28 Feb 2007 14:19:44 -0500 Subject: change the connector API a bit + misc anality I modified the API of the new connector a bit. * include errors * make names a bit more consistent with what they do * have symmetry between open and close * use refcounting * do parameter checking on inputs I also made some changes to whitespace and style. And converted descriptions to gtkdoc style comments. --- pam-ck-connector/pam-ck-connector.c | 287 ++++++++++++++++++++---------------- 1 file changed, 159 insertions(+), 128 deletions(-) (limited to 'pam-ck-connector') diff --git a/pam-ck-connector/pam-ck-connector.c b/pam-ck-connector/pam-ck-connector.c index 835be0c..c026806 100644 --- a/pam-ck-connector/pam-ck-connector.c +++ b/pam-ck-connector/pam-ck-connector.c @@ -1,8 +1,9 @@ -/* +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * * pam-ck-connector.c : PAM module for registering with CK * * Copyright (c) 2007 David Zeuthen - * + * * 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 @@ -11,10 +12,10 @@ * 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 @@ -50,40 +51,50 @@ static int opt_debug = FALSE; static void -_parse_pam_args (const pam_handle_t *pamh, int flags, int argc, const char **argv) +_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]); - } - } + 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) +pam_sm_authenticate (pam_handle_t *pamh, + int flags, + int argc, + const char **argv) { - return PAM_IGNORE; + return PAM_IGNORE; } -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh, int flags, int argc, const char **argv) +PAM_EXTERN int +pam_sm_setcred (pam_handle_t *pamh, + int flags, + int argc, + const char **argv) { - return PAM_IGNORE; + return PAM_IGNORE; } static uid_t -_util_name_to_uid (const char *username, gid_t *default_gid) +_util_name_to_uid (const char *username, + gid_t *default_gid) { - int rc; - uid_t res; - char *buf = NULL; - unsigned int bufsize; + int rc; + uid_t res; + char *buf = NULL; + unsigned int bufsize; struct passwd pwd; struct passwd *pwdp; @@ -97,8 +108,9 @@ _util_name_to_uid (const char *username, gid_t *default_gid) } res = pwdp->pw_uid; - if (default_gid != NULL) + if (default_gid != NULL) { *default_gid = pwdp->pw_gid; + } out: free (buf); @@ -108,119 +120,138 @@ out: /* our singleton */ static CKConnector *ckc = NULL; -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, const char **argv) +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; + if (ckc != NULL) { + ck_connector_unref (ckc); + ckc = NULL; + } + return PAM_SUCCESS; } -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) +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; + int ret; + const char *user; + const char *tty; + const char *x11_display; + const char *s; + uid_t uid; + char buf[256]; + DBusError error; + + 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 = ck_connector_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; + } + + dbus_error_init (&error); + if (! ck_connector_open_session_for_user (ckc, uid, tty, x11_display, &error)) { + /* 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 (dbus_error_is_set (&error)) { + if (opt_debug) { + pam_syslog (pamh, LOG_DEBUG, "%s", error.message); + } + dbus_error_free (&error); + } else { + 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", ck_connector_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 */ + ck_connector_unref (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; + 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, + "pam_ck_connector", + pam_sm_authenticate, + pam_sm_setcred, + NULL, + pam_sm_open_session, + pam_sm_close_session, + NULL, }; #endif -- cgit