source: trunk/debathena/debathena/libpam-debathena-home-type/pam_debathena_home_type.c @ 22686

Revision 22686, 4.7 KB checked in by ghudson, 17 years ago (diff)
* debathena/debathena: Snapshot debathena package sources from /mit/debathena/packages/debathena.
RevLine 
[22686]1/*
2 * pam_debathena_home_type.c
3 * PAM session management functions for pam_debathena_home_type.so
4 *
5 * Copyright © 2007 Tim Abbott <tabbott@mit.edu>
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy,
11 * modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28#define _GNU_SOURCE
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <unistd.h>
32#include <syslog.h>
33#include <pwd.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <signal.h>
38#include <errno.h>
39#include <security/pam_appl.h>
40#include <security/pam_modules.h>
41#include <security/pam_misc.h>
42
43#define FS "/usr/bin/fs"
44
45#define MAXBUF 256
46
47/* Initiate session management by updating user's GCONF_CHANGER. */
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    pid_t pid, newpid;
57    int status;
58    struct sigaction act, oldact;
59
60    for (i = 0; i < argc; i++) {
61        if (strcmp(argv[i], "debug") == 0)
62            debug = 1;
63    }
64
65    if ((pamret = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
66        syslog(LOG_ERR, "pam_debathena_home_type: pam_get_user: %s:%d",
67               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_debathena_home_type: getpwnam: %s",
76                   strerror(errno));
77        else
78            syslog(LOG_ERR, "pam_debathena_home_type: no such user: %s", user);
79        return PAM_SESSION_ERR;
80    }
81    if (debug)
82        syslog(LOG_DEBUG, "pam_debathena_home_type: user=%s home=%s",
83               user, pw->pw_dir);
84
85    /* Override gdm's SIGCHLD handler that makes waitpid() return -1.
86       Maybe this leads to some race condition if gdm used that at the time? */
87    memset(&act, 0, sizeof(act));
88    act.sa_handler = SIG_DFL;
89    sigaction(SIGCHLD, &act, &oldact);
90
91    pid = fork();
92    if (pid < 0) {
93        syslog(LOG_ERR, "pam_debathena_home_type: fork(): %s",
94               strerror(errno));
95        return PAM_SESSION_ERR;
96    }
97    if (pid == 0) {
98        if (debug)
99            syslog(LOG_DEBUG, "pam_debathena_home_type: uid=%d euid=%d",
100                   getuid(), geteuid());
101        if (close(1) < 0) {
102            syslog(LOG_ERR, "pam_debathena_home_type: close(): %s",
103                   strerror(errno));
104            _exit(-1);
105        }
106        if (close(2) < 0) {
107            syslog(LOG_ERR, "pam_debathena_home_type: close(): %s",
108                   strerror(errno));
109            _exit(-1);
110        }
111        if (execl(FS, "fs", "whichcell", pw->pw_dir, NULL) < 0) {
112            syslog(LOG_ERR, "pam_debathena_home_type: execl(): %s",
113                   strerror(errno));
114            _exit(-1);
115        }
116        syslog(LOG_ERR, "pam_debathena_home_type: execl(): %s",
117               strerror(errno));
118        _exit(-1);
119    }
120    if (TEMP_FAILURE_RETRY(newpid = waitpid(pid, &status, 0)) == -1 ||
121        !WIFEXITED(status)) {
122        syslog(LOG_ERR, "pam_debathena_home_type: setup failed: %s:%d %d %s",
123               user, status, newpid, strerror(errno));
124        return PAM_SESSION_ERR;
125    }
126    if (WEXITSTATUS(status) == 0) {
127        /* If in AFS, setup the GCONF2 hack. */
128        if (debug)
129            syslog(LOG_DEBUG, "pam_debathena_home_type: AFS homedir %s", user);
130        pam_putenv(pamh, "DEBATHENA_HOME_TYPE=afs");
131    }
132    else {
133        if (debug)
134            syslog(LOG_DEBUG, "pam_debathena_home_type: Local homedir %s", user);
135        pam_putenv(pamh, "DEBATHENA_HOME_TYPE=local");
136    }
137    if (debug)
138        syslog(LOG_DEBUG, "pam_debathena_home_type: succeeded for %s", user);
139    sigaction(SIGCHLD, &oldact, NULL);
140    return PAM_SUCCESS;
141}
142
143int
144pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
145{
146    return PAM_SUCCESS;
147}
148
149int
150pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
151{
152    return pam_sm_open_session(pamh, flags, argc, argv);
153}
154
155int
156pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
157{
158    return PAM_IGNORE;
159}
160
Note: See TracBrowser for help on using the repository browser.