source: trunk/debathena/debathena/libpam-mktemp/pam_mktemp.c @ 22756

Revision 22756, 5.4 KB checked in by andersk, 16 years ago (diff)
* pam_mktemp.c: Accept dir, not dir*. * debian/control.in: Clarify description.
Line 
1/*
2 * pam_mktemp.c
3 * PAM session management functions for pam_mktemp.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#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 <errno.h>
38#include <security/pam_appl.h>
39#include <security/pam_modules.h>
40#include <security/pam_misc.h>
41
42#define MAXBUF 256
43
44void mktemp_cleanup(pam_handle_t *pamh, void *data, int pam_end_status);
45
46/* Initiate session management by creating temporary file. */
47int
48pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
49{
50    int i;
51    int debug = 0;
52    int pamret;
53    int n;
54    const char *user;
55    struct passwd *pw;
56    char mktemp_buf[MAXBUF];
57    char envput[MAXBUF];
58    const char *prefix = "/tmp/tempfile";
59    const char *var = NULL;
60    int fd;
61    int dir = 0;
62
63    for (i = 0; i < argc; i++) {
64        if (strcmp(argv[i], "debug") == 0)
65            debug = 1;
66        else if (strncmp(argv[i], "prefix=", 7) == 0)
67            prefix = argv[i] + 7;
68        else if (strncmp(argv[i], "var=", 4) == 0)
69            var = argv[i] + 4;
70        else if (strcmp(argv[i], "dir") == 0)
71            dir = 1;
72    }
73
74    if (var == NULL) {
75        syslog(LOG_ERR, "pam_mktemp: No variable to set");
76        return PAM_SESSION_ERR;
77    }
78    if ((pamret = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
79        syslog(LOG_ERR, "pam_mktemp: pam_get_user: %s", pam_strerror(pamh, pamret));
80        return PAM_SESSION_ERR;
81    }
82    errno = 0;
83    pw = getpwnam(user);
84    if (pw == NULL) {
85        if (errno != 0)
86            syslog(LOG_ERR, "pam_mktemp: getpwnam: %m");
87        else
88            syslog(LOG_ERR, "pam_mktemp: no such user: %s", user);
89        return PAM_SESSION_ERR;
90    }
91
92    n = snprintf(mktemp_buf, MAXBUF, "%s-%d-XXXXXX", prefix, pw->pw_uid);
93    if (n < 0 || n >= MAXBUF) {
94        syslog(LOG_ERR, "pam_mktemp: snprintf failed");
95        return PAM_SESSION_ERR;
96    }
97    if (dir) {
98        if (mkdtemp(mktemp_buf) == NULL) {
99            syslog(LOG_ERR, "pam_mktemp: mkdtemp: %m");
100            return PAM_SESSION_ERR;
101        }
102    }
103    else {
104        fd = mkstemp(mktemp_buf);
105        if (fd == -1) {
106            syslog(LOG_ERR, "pam_mktemp: mkstemp: %m");
107            return PAM_SESSION_ERR;
108        }
109        if (close(fd) != 0) {
110            syslog(LOG_ERR, "pam_mktemp: close: %m");
111            return PAM_SESSION_ERR;
112        }
113    }
114    if (chown(mktemp_buf, pw->pw_uid, -1) != 0) {
115        syslog(LOG_ERR, "pam_mktemp: chown: %m");
116        return PAM_SESSION_ERR;
117    }
118    if (debug)
119        syslog(LOG_DEBUG, "pam_mktemp: using temporary file %s", mktemp_buf);
120
121    n = snprintf(envput, MAXBUF, "%s=%s", var, mktemp_buf);
122    if (n < 0 || n >= MAXBUF) {
123        syslog(LOG_ERR, "pam_mktemp: snprintf failed");
124        return PAM_SESSION_ERR;
125    }
126    pamret = pam_putenv(pamh, envput);
127    if (pamret != PAM_SUCCESS) {
128        syslog(LOG_ERR, "pam_mktemp: pam_putenv: %s",
129               pam_strerror(pamh, pamret));
130        return PAM_SESSION_ERR;
131    }
132    pamret = pam_set_data(pamh, var, mktemp_buf, mktemp_cleanup);
133    if (pamret != PAM_SUCCESS) {
134        syslog(LOG_ERR, "pam_mktemp: pam_set_data: %s",
135               pam_strerror(pamh, pamret));
136        return PAM_SESSION_ERR;
137    }
138    return PAM_SUCCESS;
139}
140
141void
142mktemp_cleanup(pam_handle_t *pamh, void *data, int pam_end_status)
143{
144    return;
145}
146
147/* Terminate session management by destroying old temporary file. */
148int
149pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
150{
151    int i;
152    int debug = 0;
153    const char *mktemp_buf;
154    const char *var = NULL;
155
156    for (i = 0; i < argc; i++) {
157        if (strcmp(argv[i], "debug") == 0)
158            debug = 1;
159        else if (strncmp(argv[i], "var=", 4) == 0)
160            var = argv[i] + 4;
161    }
162
163    if (var == NULL) {
164        syslog(LOG_ERR, "pam_mktemp: Nothing to cleanup");
165        return PAM_SESSION_ERR;
166    }
167
168    mktemp_buf = pam_getenv(pamh, var);
169    if (mktemp_buf == NULL) {
170        syslog(LOG_ERR, "pam_mktemp: cannot get %s environment variable",
171               var);
172        return PAM_SESSION_ERR;
173    }
174
175    if (debug)
176        syslog(LOG_DEBUG, "pam_mktemp: removing %s",
177               mktemp_buf);
178    if (remove(mktemp_buf) != 0) {
179        syslog(LOG_ERR, "pam_mktemp: remove(): %m");
180        return PAM_SESSION_ERR;
181    }
182
183    return PAM_SUCCESS;
184}
185
186int
187pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
188{
189    if (flags == PAM_ESTABLISH_CRED)
190        return pam_sm_open_session(pamh, flags, argc, argv);
191    return PAM_SUCCESS;
192}
193
194int
195pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
196{
197    return PAM_SUCCESS;
198}
199
Note: See TracBrowser for help on using the repository browser.