source: trunk/debathena/debathena/libpam-athena-locker/pam_athena_locker.c @ 23624

Revision 23624, 4.8 KB checked in by tabbott, 16 years ago (diff)
In libpam-athena-locker: * Make not having a Kerberos ticket log at level DEBUG, since system users like cron often trigger this condition.
Line 
1/*
2 * pam_athena-locker.c
3 * PAM session management functions for pam_athena_locker.so
4 *
5 * Copyright © 2007 Tim Abbott <tabbott@mit.edu> and Anders Kaseorg
6 * <andersk@mit.edu>
7 *
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use, copy,
12 * modify, merge, publish, distribute, sublicense, and/or sell copies
13 * of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#define _GNU_SOURCE
30#include <sys/types.h>
31#include <sys/wait.h>
32#include <unistd.h>
33#include <syslog.h>
34#include <pwd.h>
35#include <grp.h>
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39#include <signal.h>
40#include <stdarg.h>
41#include <errno.h>
42#include <security/pam_appl.h>
43#include <security/pam_modules.h>
44#include <security/pam_misc.h>
45#include <afs/afssyscalls.h>
46
47/* Initiate session management by attaching locker. */
48int
49pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
50{
51    int i;
52    int debug = 0;
53    int pamret;
54    const char *user;
55    struct passwd *pw;
56    const char *filecache;
57    pid_t pid;
58    int status;
59    struct sigaction act, oldact;
60
61    for (i = 0; i < argc; i++) {
62        if (strcmp(argv[i], "debug") == 0)
63            debug = 1;
64    }
65
66    if ((pamret = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
67        syslog(LOG_ERR, "pam_athena_locker: pam_get_user: %s:%d", pam_strerror(pamh, pamret), pamret);
68        return PAM_SESSION_ERR;
69    }
70
71    errno = 0;
72    pw = getpwnam(user);
73    if (pw == NULL) {
74        if (errno != 0)
75            syslog(LOG_ERR, "pam_athena_locker: getpwnam: %s", strerror(errno));
76        else
77            syslog(LOG_ERR, "pam_athena_locker: no such user: %s", user);
78        return PAM_SESSION_ERR;
79    }
80
81    if (lsetpag() != 0) {
82        syslog(LOG_ERR, "pam_athena_locker: Could not create a PAG");
83        return PAM_SESSION_ERR;
84    }
85
86    if ((filecache = pam_getenv(pamh, "KRB5CCNAME")) == NULL) {
87        if (debug)
88            syslog(LOG_DEBUG, "pam_athena_locker: No Kerberos ticket cache; not attaching locker");
89        return PAM_SESSION_ERR;
90    }
91
92    /* Override gdm's SIGCHLD handler that makes waitpid() return -1.
93       Maybe this leads to some race condition if gdm used that at the time? */
94    memset(&act, 0, sizeof(act));
95    act.sa_handler = SIG_DFL;
96    sigaction(SIGCHLD, &act, &oldact);
97
98    pid = fork();
99    if (pid == -1) {
100        syslog(LOG_ERR, "pam_athena_locker: fork(): %s", strerror(errno));
101        return PAM_SESSION_ERR;
102    }
103    if (pid == 0) {
104        if (setenv("KRB5CCNAME", filecache, 1) != 0) {
105            syslog(LOG_ERR, "pam_athena_locker: setenv(): %s", strerror(errno));
106            _exit(1);
107        }
108        if (debug)
109            syslog(LOG_DEBUG, "pam_athena_locker: uid=%d euid=%d", getuid(), geteuid());
110        if (setuid(pw->pw_uid) != 0) {
111            syslog(LOG_ERR, "pam_athena_locker: setuid(): %s", strerror(errno));
112            return PAM_SESSION_ERR;
113        }
114        if (debug)
115            syslog(LOG_DEBUG, "pam_athena_locker: uid=%d euid=%d", getuid(), geteuid());
116        if (close(1) < 0) {
117            syslog(LOG_ERR, "pam_debathena_home_type: close(): %s",
118                   strerror(errno));
119            _exit(-1);
120        }
121        if (close(2) < 0) {
122            syslog(LOG_ERR, "pam_debathena_home_type: close(): %s",
123                   strerror(errno));
124            _exit(-1);
125        }
126        execl("/bin/attach", "attach", "--quiet", "--nozephyr", user, NULL);
127        syslog(LOG_ERR, "pam_athena_locker: execl(): %s", strerror(errno));
128        _exit(1);
129    }
130    if (TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)) == -1 ||
131        !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
132        syslog(LOG_ERR, "pam_athena_locker: locker attachment failed: %s", user);
133        return PAM_SESSION_ERR;
134    }
135    if (debug)
136        syslog(LOG_DEBUG, "pam_athena_locker: attached locker %s", user);
137    sigaction(SIGCHLD, &oldact, NULL);
138    return PAM_SUCCESS;
139}
140
141/* Terminate session management. */
142int
143pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
144{
145    return PAM_SUCCESS;
146}
147
148int
149pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
150{
151    if (flags == PAM_ESTABLISH_CRED)
152        return pam_sm_open_session(pamh, flags, argc, argv);
153    return PAM_SUCCESS;
154}
155
156int
157pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
158{
159    return PAM_SUCCESS;
160}
161
Note: See TracBrowser for help on using the repository browser.