death to trailing whitespace
[openafs.git] / src / pam / afs_session.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #include <syslog.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <errno.h>
19
20 #include <security/pam_appl.h>
21 #include <security/pam_modules.h>
22
23 #include "afs_message.h"
24 #include "afs_util.h"
25
26 extern int
27 pam_sm_open_session(pam_handle_t * pamh, int flags, int argc,
28                     const char **argv)
29 {
30     return PAM_SUCCESS;
31 }
32
33
34 #define REMAINLIFETIME 300
35
36 extern int
37 pam_sm_close_session(pam_handle_t * pamh, int flags, int argc,
38                      const char **argv)
39 {
40     int i;
41     int logmask = LOG_UPTO(LOG_INFO);
42     int origmask;
43     int remain = 0;
44     int remainlifetime = REMAINLIFETIME;
45     int no_unlog = 0;
46
47     openlog(pam_afs_ident, LOG_CONS | LOG_PID, LOG_AUTH);
48     origmask = setlogmask(logmask);
49
50     /*
51      * Parse the user options.  Log an error for any unknown options.
52      */
53     for (i = 0; i < argc; i++) {
54         if (strcasecmp(argv[i], "debug") == 0) {
55             logmask |= LOG_MASK(LOG_DEBUG);
56             (void)setlogmask(logmask);
57         } else if (strcasecmp(argv[i], "remain") == 0) {
58             remain = 1;
59         } else if (strcasecmp(argv[i], "remainlifetime") == 0) {
60             i++;
61             remain = 1;
62             remainlifetime = (int)strtol(argv[i], (char **)NULL, 10);
63             if (remainlifetime == 0)
64                 if ((errno == EINVAL) || (errno == ERANGE)) {
65                     remainlifetime = REMAINLIFETIME;
66                     pam_afs_syslog(LOG_ERR, PAMAFS_REMAINLIFETIME, argv[i],
67                                    REMAINLIFETIME);
68                 } else {
69                     no_unlog = 0;
70                     remain = 0;
71                 }
72         } else if (strcmp(argv[i], "no_unlog") == 0) {
73             no_unlog = 1;
74         } else {
75             pam_afs_syslog(LOG_ERR, PAMAFS_UNKNOWNOPT, argv[i]);
76         }
77     }
78
79     if (logmask && LOG_MASK(LOG_DEBUG))
80         syslog(LOG_DEBUG,
81                "pam_afs_session_close: remain: %d, remainlifetime: %d, no_unlog: %d",
82                remain, remainlifetime, no_unlog);
83     if (remain && !no_unlog) {
84         switch (fork()) {
85         case -1:                /* error */
86             return (PAM_SESSION_ERR);
87         case 0:         /* child */
88 #ifdef AFS_LINUX20_ENV
89             setpgrp();
90 #endif
91             setsid();
92             for (i = 0; i < 64; i++)
93                 close(i);
94             sleep(remainlifetime);
95             ktc_ForgetAllTokens();
96             pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED2);
97             exit(0);
98         default:                /* parent */
99             pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED1);
100             return (PAM_SUCCESS);
101         }
102     }
103     if (!no_unlog && ktc_ForgetAllTokens())
104         return PAM_SESSION_ERR;
105     if (logmask && LOG_MASK(LOG_DEBUG))
106         syslog(LOG_DEBUG, "pam_afs_session_close: Session closed");
107     return PAM_SUCCESS;
108 }