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