Made it so that syscom is checked in pam_csc.so instead of earlier in the PAM stack.
authorPeter Barfuss <pbarfuss@maltodextrin.csclub.uwaterloo.ca>
Thu, 24 Jan 2013 02:36:57 +0000 (21:36 -0500)
committerPeter Barfuss <pbarfuss@maltodextrin.csclub.uwaterloo.ca>
Thu, 24 Jan 2013 02:36:57 +0000 (21:36 -0500)
This way syscom can still login when their accounts expired, but messages are still printed. This should hopefully stop the whole 'wait crap I wasn't registered for the past k terms', k>=1 that has been happening semi-frequently for a bunch of syscom members.

Also added #define LDAP_DEPRECATED to get access to a bunch of function prototypes for functions in the LDAP API that are apparently now deprecated.

Also removed the CSCF cruft. In case we ever do need it again, we can vacuum it out from past commits. Or just rewrite it from scratch, especially considering that I doubt CSCF uses that auth backend anymore and some 2/3ds of all functions involved are deprecated according to the latest release of the OpenLDAP API. Or rather, the latest according to Debian, which means it's ~3 years out of date and the functions might very well not even exist anymore (they do exist, I checked, but point still stands. There's no real point to keeping this stuff around, I don't think it was ever operational at any point in the wild, even).

-bofh

pam_csc.c

index cd41dd8..3cf16c7 100644 (file)
--- a/pam_csc.c
+++ b/pam_csc.c
@@ -1,4 +1,5 @@
 #define PAM_SM_ACCOUNT
+#define LDAP_DEPRECATED 1
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -13,6 +14,7 @@
 #include <sasl/sasl.h>
 #include <syslog.h>
 #include <pwd.h>
+#include <grp.h>
 
 #ifndef LDAP_SASL_QUIET
 #  define LDAP_SASL_QUIET 0
 #endif
 
 #define PAM_CSC_CSC_BASE_DN         "ou=People,dc=csclub,dc=uwaterloo,dc=ca"
-#define PAM_CSC_CSCF_URI \
-    "ldaps://eponina.student.cs.uwaterloo.ca" \
-    "ldaps://canadenis.student.cs.uwaterloo.ca"
-#define PAM_CSC_CSCF_BASE_DN        "dc=student,dc=cs,dc=uwateloo,dc=ca"
-#define PAM_CSC_CSCF_BIND_DN \
-    "uid=TODO,dc=student,dc=cs,dc=uwaterloo,dc=ca"
-#define PAM_CSC_CSCF_SASL_USER \
-    "dn:uid=TODO,cn=STUDENT.CS.UWATERLOO.CA,cn=DIGEST-MD5,cn=auth"
-#define PAM_CSC_CSCF_PASSWORD_FILE  "/etc/security/pam_csc_cscf_password"
-#define PAM_CSC_CSCF_SASL_REALM     "STUDENT.CS.UWATERLOO.CA"
 #define PAM_CSC_LDAP_TIMEOUT        5
 #define PAM_CSC_ALLOWED_USERNAMES   {"nobody"}
 #define PAM_CSC_EXPIRED_MSG \
@@ -45,8 +37,6 @@
     "*    Your account has expired - please contact the Computer Science Club    *\n" \
     "*                                                                           *\n" \
     "*****************************************************************************\n"
-#define PAM_CSC_CSCF_DISALLOWED_MSG \
-    "You are not registered as a CS student - login denied."
 
 #define PAM_CSC_SYSLOG_EXPIRED_NO_TERMS \
     "(pam_csc): %s was not registered for current term or previous term - denying login\n"
@@ -54,8 +44,6 @@
     "(pam_csc): %s was not registered for current term but was registered for previous term - permitting login\n"
 #define PAM_CSC_SYSLOG_NOT_A_MEMBER \
     "(pam_csc): %s is not a member account - permitting login\n"
-#define PAM_CSC_SYSLOG_CSCF_DISALLOWED \
-    "(pam_csc): %s is using a CSCF machine but is not enrolled in CS - denying login\n"
 #define PAM_CSC_SYSLOG_SASL_UNRECOGNIZED_CALLBACK \
     "(pam_csc): %ld is not a recognized SASL callback option\n"
 
@@ -173,24 +161,22 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
     int retval = PAM_SUCCESS;
     const char* username;
     struct passwd* pwd;
+    struct group *grp;
     const char* allowed_usernames[] = PAM_CSC_ALLOWED_USERNAMES;
-    int i;
+    unsigned int i;
     time_t cur_time;
     struct tm* local_time;
     int long_term, term_month;
     static const char term_chars[] = {'w', 's', 'f'};
     char cur_term[6], prev_term[6];
-    LDAP *ld_csc = NULL, *ld_cscf = NULL;
-    bool cscf;
-    FILE* pass_file = NULL;
+    LDAP *ld_csc = NULL;
     char* username_escaped = NULL;
-    char *filter_csc = NULL, *filter_cscf = NULL;
-    char *attrs_csc[] = {"objectClass", "term", "nonMemberTerm", NULL},
-        *attrs_cscf[] = {"objectClass", NULL};
-    bool expired;
+    char *filter_csc = NULL;
+    char *attrs_csc[] = {"objectClass", "term", "nonMemberTerm", NULL};
+    bool expired, syscom = 0; 
     const char* pam_rhost;
-    int msg_csc, msg_cscf;
-    LDAPMessage *res_csc = NULL, *res_cscf = NULL;
+    int msg_csc;
+    LDAPMessage *res_csc = NULL;
     struct timeval timeout = {PAM_CSC_LDAP_TIMEOUT, 0};
     LDAPMessage* entry = NULL;
     char **values = NULL, **nmvalues = NULL, **values_iter = NULL;
@@ -212,6 +198,17 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
         }
     }
 
+    /* check to see if user is in group syscom, if yes, still print message but allow login even if user expired */
+    i = 0;
+    grp = getgrnam("syscom");
+    while(grp->gr_mem[i] != NULL) {
+        if(!strcmp(grp->gr_mem[i], username)) {
+            syscom = 1;
+            break;
+        }
+        i++;
+    }
+
     /* check username */
     for(i = 0; i < sizeof(allowed_usernames) / sizeof(char*); i++)
     {
@@ -238,36 +235,11 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
     WARN_NEG1( ldap_simple_bind(ld_csc, NULL, NULL) )
 
     /* check if we are logging in from a CSCF teaching thin client */
-    cscf = false;
     if(pam_get_item(pamh, PAM_RHOST, (const void**)&pam_rhost) && pam_rhost)
     {
         /* TODO: check if pam_rhost is tcNNN.student.cs */
     }
 
-    if(cscf)
-    {
-        pam_csc_sasl_interact_param_t interact_param = {
-            PAM_CSC_CSCF_SASL_REALM,
-            PAM_CSC_CSCF_SASL_USER
-        };
-        int ret;
-
-        /* read password file */
-        WARN_ZERO( pass_file = fopen(PAM_CSC_CSCF_PASSWORD_FILE, "r") )
-        ret = fread(interact_param.pass, sizeof(char),
-            sizeof(interact_param.pass) - 1, pass_file);
-        interact_param.pass[ret] = '\0';
-        if(ret && interact_param.pass[ret - 1] == '\n')
-            interact_param.pass[ret - 1] = '\0';
-        fclose(pass_file); pass_file = NULL;
-
-        /* connect to CSCF */
-        WARN_LDAP( ldap_initialize(&ld_cscf, PAM_CSC_CSCF_URI) )
-        WARN_NEG1( ldap_sasl_interactive_bind_s(ld_cscf, PAM_CSC_CSCF_BIND_DN,
-            "DIGEST-MD5", NULL, NULL, LDAP_SASL_INTERACTIVE | LDAP_SASL_QUIET,
-            pam_csc_sasl_interact, &interact_param) )
-    }
-
     /* create CSC request string */
     WARN_ZERO( filter_csc = malloc(140 + strlen(username_escaped)) )
     sprintf(filter_csc, "(&(uid=%s)(|(&(objectClass=member)(|(term=%s)(term=%s)(nonMemberTerm=%s)(nonMemberTerm=%s)))(!(objectClass=member))))", username_escaped, cur_term, prev_term, cur_term, prev_term);
@@ -276,17 +248,6 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
     WARN_NEG1( msg_csc = ldap_search(ld_csc, PAM_CSC_CSC_BASE_DN,
         LDAP_SCOPE_SUBTREE, filter_csc, attrs_csc, 0) )
 
-    if(cscf)
-    {
-        /* create CSCF request string */
-        WARN_ZERO( filter_cscf = malloc(100 + strlen(username_escaped)) )
-        sprintf(filter_csc, "TODO %s", username_escaped);
-
-        /* issue CSCF request */
-        WARN_NEG1( msg_cscf = ldap_search(ld_cscf, PAM_CSC_CSCF_BASE_DN,
-            LDAP_SCOPE_SUBTREE, filter_cscf, attrs_cscf, 1) )
-    }
-
     /* wait for CSC response */
     WARN_NEG1( ldap_result(ld_csc, msg_csc, 1, &timeout, &res_csc) )
 
@@ -297,7 +258,7 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
         pam_csc_print_message(pamh, PAM_CSC_EXPIRED_MSG, PAM_ERROR_MSG);
         syslog(LOG_AUTHPRIV | LOG_NOTICE, PAM_CSC_SYSLOG_EXPIRED_NO_TERMS,
             username);
-        retval = PAM_AUTH_ERR;
+        retval = (syscom ? PAM_SUCCESS : PAM_AUTH_ERR);
         goto cleanup;
     }
 
@@ -357,40 +318,17 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const c
             pam_csc_print_message(pamh, PAM_CSC_EXPIRED_MSG, PAM_ERROR_MSG);
             syslog(LOG_AUTHPRIV | LOG_NOTICE, PAM_CSC_SYSLOG_EXPIRED_NO_TERMS,
                 username);
-            retval = PAM_AUTH_ERR;
-            goto cleanup;
-        }
-    }
-
-    if(cscf)
-    {
-        /* wait for CSCF response */
-        WARN_NEG1( ldap_result(ld_cscf, msg_cscf, 1, &timeout, &res_cscf) )
-
-        /* check if we got an entry back from CSCF */
-        if(ldap_count_entries(ld_cscf, res_cscf) == 0)
-        {
-            /* output CSCF disallowed message */
-            pam_csc_print_message(pamh, PAM_CSC_CSCF_DISALLOWED_MSG,
-                PAM_ERROR_MSG);
-            syslog(LOG_AUTHPRIV | LOG_NOTICE, PAM_CSC_SYSLOG_CSCF_DISALLOWED,
-                username);
-            retval = PAM_AUTH_ERR;
-            goto cleanup;
+            retval = (syscom ? PAM_SUCCESS : PAM_AUTH_ERR);
         }
     }
 
 cleanup:
-
     if(values) ldap_value_free(values);
     if(nmvalues) ldap_value_free(nmvalues);
     if(res_csc) ldap_msgfree(res_csc);
-    if(res_cscf) ldap_msgfree(res_cscf);
     if(ld_csc) ldap_unbind(ld_csc);
-    if(ld_cscf) ldap_unbind(ld_cscf);
     if(filter_csc) free(filter_csc);
-    if(filter_cscf) free(filter_cscf);
     if(username_escaped) free(username_escaped);
-
     return retval;
 }
+