2de18f8c3fbcb525042a9e16baccbc399bfc17b3
[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 #include <roken.h>
14
15 #include <security/pam_appl.h>
16 #include <security/pam_modules.h>
17
18 #include "afs_message.h"
19 #include "afs_util.h"
20
21 extern int
22 pam_sm_open_session(pam_handle_t * pamh, int flags, int argc,
23                     const char **argv)
24 {
25     return PAM_SUCCESS;
26 }
27
28
29 #define REMAINLIFETIME 300
30
31 extern int
32 pam_sm_close_session(pam_handle_t * pamh, int flags, int argc,
33                      const char **argv)
34 {
35     int i;
36     int logmask = LOG_UPTO(LOG_INFO);
37     int origmask;
38     int remain = 0;
39     int remainlifetime = REMAINLIFETIME;
40     int no_unlog = 0;
41
42     openlog(pam_afs_ident, LOG_CONS | LOG_PID, LOG_AUTH);
43     origmask = setlogmask(logmask);
44
45     /*
46      * Parse the user options.  Log an error for any unknown options.
47      */
48     for (i = 0; i < argc; i++) {
49         if (strcasecmp(argv[i], "debug") == 0) {
50             logmask |= LOG_MASK(LOG_DEBUG);
51             (void)setlogmask(logmask);
52         } else if (strcasecmp(argv[i], "remain") == 0) {
53             remain = 1;
54         } else if (strcasecmp(argv[i], "remainlifetime") == 0) {
55             i++;
56             remain = 1;
57             remainlifetime = (int)strtol(argv[i], (char **)NULL, 10);
58             if (remainlifetime == 0)
59                 if ((errno == EINVAL) || (errno == ERANGE)) {
60                     remainlifetime = REMAINLIFETIME;
61                     pam_afs_syslog(LOG_ERR, PAMAFS_REMAINLIFETIME, argv[i],
62                                    REMAINLIFETIME);
63                 } else {
64                     no_unlog = 0;
65                     remain = 0;
66                 }
67         } else if (strcmp(argv[i], "no_unlog") == 0) {
68             no_unlog = 1;
69         } else {
70             pam_afs_syslog(LOG_ERR, PAMAFS_UNKNOWNOPT, argv[i]);
71         }
72     }
73
74     if (logmask && LOG_MASK(LOG_DEBUG))
75         syslog(LOG_DEBUG,
76                "pam_afs_session_close: remain: %d, remainlifetime: %d, no_unlog: %d",
77                remain, remainlifetime, no_unlog);
78     if (remain && !no_unlog) {
79         switch (fork()) {
80         case -1:                /* error */
81             return (PAM_SESSION_ERR);
82         case 0:         /* child */
83 #ifdef AFS_LINUX20_ENV
84             setpgrp();
85 #endif
86             setsid();
87             for (i = 0; i < 64; i++)
88                 close(i);
89             sleep(remainlifetime);
90             ktc_ForgetAllTokens();
91             pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED2);
92             exit(0);
93         default:                /* parent */
94             pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED1);
95             return (PAM_SUCCESS);
96         }
97     }
98     if (!no_unlog && ktc_ForgetAllTokens())
99         return PAM_SESSION_ERR;
100     if (logmask && LOG_MASK(LOG_DEBUG))
101         syslog(LOG_DEBUG, "pam_afs_session_close: Session closed");
102     return PAM_SUCCESS;
103 }