Made it so that syscom is checked in pam_csc.so instead of earlier in the PAM stack.
[public/libpam-csc.git] / 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;
 }
+