]> git.sur5r.net Git - openldap/blobdiff - contrib/slapd-modules/nssov/pam.c
Fix compare checking in pam_authz
[openldap] / contrib / slapd-modules / nssov / pam.c
index 2009f310c1f34eac8a6f995f35395565bfbe820b..a00d418cd74de86c0dca12e002f87192b8f60654 100644 (file)
@@ -1,7 +1,9 @@
 /* pam.c - pam processing routines */
 /* $OpenLDAP$ */
-/*
- * Copyright 2009 by Howard Chu, Symas Corp.
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 
+ *
+ * Copyright 2008-2009 The OpenLDAP Foundation.
+ * Portions Copyright 2008 by Howard Chu, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 static int ppolicy_cid;
 static AttributeDescription *ad_loginStatus;
 
-const char *at_loginStatus =
-       "( 1.3.6.1.4.1.4745.1.20.1 "
-       "NAME ( 'loginStatus' ) "
-       "DESC 'Currently logged in sessions for a user' "
-       "EQUALITY caseIgnoreMatch "
-       "SUBSTR caseIgnoreSubstringsMatch "
-       "ORDERING caseIgnoreOrderingMatch "
-       "SYNTAX OMsDirectoryString "
-       "USAGE directoryOperation )";
-
 struct paminfo {
        struct berval uid;
        struct berval dn;
@@ -108,24 +100,17 @@ static int pam_bindcb(
        return LDAP_SUCCESS;
 }
 
-int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op,
+static int pam_uid2dn(nssov_info *ni, Operation *op,
        struct paminfo *pi)
 {
-       int rc;
-       slap_callback cb = {0};
-       SlapReply rs = {REP_RESULT};
        struct berval sdn;
 
-       pi->msg.bv_val = pi->pwd.bv_val;
-       pi->msg.bv_len = 0;
-       pi->authz = NSLCD_PAM_SUCCESS;
        BER_BVZERO(&pi->dn);
 
        if (!isvalidusername(&pi->uid)) {
-               Debug(LDAP_DEBUG_ANY,"nssov_pam_do_bind(%s): invalid user name\n",
+               Debug(LDAP_DEBUG_ANY,"nssov_pam_uid2dn(%s): invalid user name\n",
                        pi->uid.bv_val,0,0);
-               rc = NSLCD_PAM_USER_UNKNOWN;
-               goto finish;
+               return NSLCD_PAM_USER_UNKNOWN;
        }
 
        if (ni->ni_pam_opts & NI_PAM_SASL2DN) {
@@ -149,11 +134,26 @@ int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op,
                        dnNormalize( 0, NULL, NULL, &sdn, &pi->dn, op->o_tmpmemctx );
                }
        }
-       BER_BVZERO(&sdn);
        if (BER_BVISEMPTY(&pi->dn)) {
-               rc = NSLCD_PAM_USER_UNKNOWN;
-               goto finish;
+               return NSLCD_PAM_USER_UNKNOWN;
        }
+       return 0;
+}
+
+int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op,
+       struct paminfo *pi)
+{
+       int rc;
+       slap_callback cb = {0};
+       SlapReply rs = {REP_RESULT};
+
+       pi->msg.bv_val = pi->pwd.bv_val;
+       pi->msg.bv_len = 0;
+       pi->authz = NSLCD_PAM_SUCCESS;
+       BER_BVZERO(&pi->dn);
+
+       rc = pam_uid2dn(ni, op, pi);
+       if (rc) goto finish;
 
        if (BER_BVISEMPTY(&pi->pwd)) {
                rc = NSLCD_PAM_IGNORE;
@@ -253,6 +253,13 @@ static struct berval svcmsg =
 static struct berval uidmsg =
        BER_BVC("Access denied by UID check");
 
+static int pam_compare_cb(Operation *op, SlapReply *rs)
+{
+       if (rs->sr_err == LDAP_COMPARE_TRUE)
+               op->o_callback->sc_private = (void *)1;
+       return LDAP_SUCCESS;
+}
+
 int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
 {
        struct berval dn, uid, svc, ruser, rhost, tty;
@@ -264,7 +271,7 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        char ruserc[32];
        char rhostc[256];
        char ttyc[256];
-       int rc = NSLCD_PAM_SUCCESS;
+       int rc;
        Entry *e = NULL;
        Attribute *a;
        SlapReply rs = {REP_RESULT};
@@ -279,22 +286,27 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        READ_STRING_BUF2(fp,svcc,sizeof(svcc));
        svc.bv_val = svcc;
        svc.bv_len = tmpint32;
-       READ_STRING_BUF2(fp,svcc,sizeof(ruserc));
+       READ_STRING_BUF2(fp,ruserc,sizeof(ruserc));
        ruser.bv_val = ruserc;
        ruser.bv_len = tmpint32;
-       READ_STRING_BUF2(fp,svcc,sizeof(rhostc));
+       READ_STRING_BUF2(fp,rhostc,sizeof(rhostc));
        rhost.bv_val = rhostc;
        rhost.bv_len = tmpint32;
-       READ_STRING_BUF2(fp,svcc,sizeof(ttyc));
+       READ_STRING_BUF2(fp,ttyc,sizeof(ttyc));
        tty.bv_val = ttyc;
        tty.bv_len = tmpint32;
 
        Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(%s)\n",dn.bv_val,0,0);
 
-       /* We don't do authorization if they weren't authenticated by us */
+       /* If we didn't do authc, we don't have a DN yet */
        if (BER_BVISEMPTY(&dn)) {
-               rc = NSLCD_PAM_USER_UNKNOWN;
-               goto finish;
+               struct paminfo pi;
+               pi.uid = uid;
+               pi.svc = svc;
+
+               rc = pam_uid2dn(ni, op, &pi);
+               if (rc) goto finish;
+               dn = pi.dn;
        }
 
        /* See if they have access to the host and service */
@@ -347,7 +359,7 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
                        }
                }
 
-               cb.sc_response = slap_null_cb;
+               cb.sc_response = pam_compare_cb;
                cb.sc_private = NULL;
                op->o_tag = LDAP_REQ_COMPARE;
                op->o_req_dn = hostdn;
@@ -356,7 +368,7 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
                ava.aa_value = svc;
                op->orc_ava = &ava;
                rc = op->o_bd->be_compare( op, &rs );
-               if ( rs.sr_err != LDAP_COMPARE_TRUE ) {
+               if ( cb.sc_private == NULL ) {
                        authzmsg = svcmsg;
                        rc = NSLCD_PAM_PERM_DENIED;
                        goto finish;
@@ -398,9 +410,10 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        }
        if ((ni->ni_pam_opts & NI_PAM_USERHOST) && nssov_pam_host_ad) {
                a = attr_find(e->e_attrs, nssov_pam_host_ad);
-               if (!a || value_find_ex( nssov_pam_host_ad,
-                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
-                       a->a_vals, &global_host_bv, op->o_tmpmemctx )) {
+               if (!a || attr_valfind( a,
+                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+                       SLAP_MR_VALUE_OF_SYNTAX,
+                       &global_host_bv, NULL, op->o_tmpmemctx )) {
                        rc = NSLCD_PAM_PERM_DENIED;
                        authzmsg = hostmsg;
                        goto finish;
@@ -408,9 +421,10 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        }
        if ((ni->ni_pam_opts & NI_PAM_USERSVC) && nssov_pam_svc_ad) {
                a = attr_find(e->e_attrs, nssov_pam_svc_ad);
-               if (!a || value_find_ex( nssov_pam_svc_ad,
-                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
-                       a->a_vals, &svc, op->o_tmpmemctx )) {
+               if (!a || attr_valfind( a,
+                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+                       SLAP_MR_VALUE_OF_SYNTAX,
+                       &svc, NULL, op->o_tmpmemctx )) {
                        rc = NSLCD_PAM_PERM_DENIED;
                        authzmsg = svcmsg;
                        goto finish;
@@ -423,7 +437,7 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        if (ni->ni_pam_min_uid || ni->ni_pam_max_uid) {
                int id;
                char *tmp;
-               nssov_mapinfo *mi = &ni->ni_maps[NM_host];
+               nssov_mapinfo *mi = &ni->ni_maps[NM_passwd];
                a = attr_find(e->e_attrs, mi->mi_attrs[UIDN_KEY].an_desc);
                if (!a) {
                        rc = NSLCD_PAM_PERM_DENIED;
@@ -451,6 +465,7 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
                else if (!BER_BVISEMPTY(&ni->ni_pam_template))
                        uid = ni->ni_pam_template;
        }
+       rc = NSLCD_PAM_SUCCESS;
 
 finish:
        WRITE_INT32(fp,NSLCD_VERSION);
@@ -548,6 +563,8 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
        cb.sc_response = slap_null_cb;
        op->o_callback = &cb;
        op->o_tag = LDAP_REQ_MODIFY;
+       op->o_dn = op->o_bd->be_rootdn;
+       op->o_ndn = op->o_bd->be_rootndn;
        op->orm_modlist = &mod;
        op->orm_no_opattrs = 1;
        op->o_req_dn = dn;
@@ -660,7 +677,9 @@ int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op)
 int nssov_pam_init()
 {
        int code = 0;
+       const char *text;
        if (!ad_loginStatus)
-               code = register_at( at_loginStatus, &ad_loginStatus, 0 );
+               code = slap_str2ad("loginStatus", &ad_loginStatus, &text);
+
        return code;
 }