pam: Use &, not && for bitwise operations
[openafs.git] / src / pam / afs_session.c
index 741067f..4ff997d 100644 (file)
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-#include <afs/param.h>
 #include <afsconfig.h>
+#include <afs/param.h>
 
-RCSID("$Header$");
+#include <roken.h>
 
 #include <security/pam_appl.h>
 #include <security/pam_modules.h>
 
+#include <afs/auth.h>
+#include "afs_message.h"
+#include "afs_util.h"
+
 extern int
-pam_sm_open_session(
-       pam_handle_t    *pamh,
-       int             flags,
-       int             argc,
-       const char      **argv)
+pam_sm_open_session(pam_handle_t * pamh, int flags, int argc,
+                   const char **argv)
 {
     return PAM_SUCCESS;
 }
 
 
+#define REMAINLIFETIME 300
+
 extern int
-pam_sm_close_session(
-       pam_handle_t    *pamh,
-       int             flags,
-       int             argc,
-       const char      **argv)
+pam_sm_close_session(pam_handle_t * pamh, int flags, int argc,
+                    const char **argv)
 {
+    int i;
+    int logmask = LOG_UPTO(LOG_INFO);
+    int remain = 0;
+    int remainlifetime = REMAINLIFETIME;
+    int no_unlog = 0;
+
+    openlog(pam_afs_ident, LOG_CONS | LOG_PID, LOG_AUTH);
+    setlogmask(logmask);
+
+    /*
+     * Parse the user options.  Log an error for any unknown options.
+     */
+    for (i = 0; i < argc; i++) {
+       if (strcasecmp(argv[i], "debug") == 0) {
+           logmask |= LOG_MASK(LOG_DEBUG);
+           (void)setlogmask(logmask);
+       } else if (strcasecmp(argv[i], "remain") == 0) {
+           remain = 1;
+       } else if (strcasecmp(argv[i], "remainlifetime") == 0) {
+           i++;
+           remain = 1;
+           remainlifetime = (int)strtol(argv[i], (char **)NULL, 10);
+           if (remainlifetime == 0) {
+               if ((errno == EINVAL) || (errno == ERANGE)) {
+                   remainlifetime = REMAINLIFETIME;
+                   pam_afs_syslog(LOG_ERR, PAMAFS_REMAINLIFETIME, argv[i],
+                                  REMAINLIFETIME);
+               } else {
+                   no_unlog = 0;
+                   remain = 0;
+               }
+           }
+       } else if (strcmp(argv[i], "no_unlog") == 0) {
+           no_unlog = 1;
+       } else {
+           pam_afs_syslog(LOG_ERR, PAMAFS_UNKNOWNOPT, argv[i]);
+       }
+    }
+
+    if (logmask & LOG_MASK(LOG_DEBUG))
+       syslog(LOG_DEBUG,
+              "pam_afs_session_close: remain: %d, remainlifetime: %d, no_unlog: %d",
+              remain, remainlifetime, no_unlog);
+    if (remain && !no_unlog) {
+       switch (fork()) {
+       case -1:                /* error */
+           return (PAM_SESSION_ERR);
+       case 0:         /* child */
+#ifdef AFS_LINUX20_ENV
+           setpgrp();
+#endif
+           setsid();
+           for (i = 0; i < 64; i++)
+               close(i);
+           sleep(remainlifetime);
+           ktc_ForgetAllTokens();
+           pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED2);
+           exit(0);
+       default:                /* parent */
+           pam_afs_syslog(LOG_INFO, PAMAFS_SESSIONCLOSED1);
+           return (PAM_SUCCESS);
+       }
+    }
+    if (!no_unlog && ktc_ForgetAllTokens())
+       return PAM_SESSION_ERR;
+    if (logmask & LOG_MASK(LOG_DEBUG))
+       syslog(LOG_DEBUG, "pam_afs_session_close: Session closed");
     return PAM_SUCCESS;
 }