]> git.sur5r.net Git - openldap/commitdiff
ITS#4516 clear restricted status if other Binds have succeeded
authorHoward Chu <hyc@openldap.org>
Thu, 11 May 2006 13:39:44 +0000 (13:39 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 11 May 2006 13:39:44 +0000 (13:39 +0000)
servers/slapd/overlays/ppolicy.c

index 958348e939e035196849fc15ead5b2ddcadf92f8..95ff1fd7c84d914cae5a6c6c7a79fde2dc4e81b1 100644 (file)
@@ -55,7 +55,7 @@ typedef struct pp_info {
  * used by all instances
  */
 typedef struct pw_conn {
-       int restricted;         /* TRUE if connection is restricted */
+       struct berval dn;       /* DN of restricted user */
 } pw_conn;
 
 static pw_conn *pwcons;
@@ -814,7 +814,8 @@ ppolicy_bind_resp( Operation *op, SlapReply *rs )
                         * that we are disallowed from doing anything
                         * other than change password.
                         */
-                       pwcons[op->o_conn->c_conn_idx].restricted = 1;
+                       ber_dupbv( &pwcons[op->o_conn->c_conn_idx].dn,
+                               &op->o_conn->c_ndn );
 
                        ppb->pErr = PP_changeAfterReset;
 
@@ -972,7 +973,10 @@ ppolicy_bind( Operation *op, SlapReply *rs )
        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
 
        /* Reset lockout status on all Bind requests */
-       pwcons[op->o_conn->c_conn_idx].restricted = 0;
+       if ( !BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn )) {
+               ch_free( pwcons[op->o_conn->c_conn_idx].dn.bv_val );
+               BER_BVZERO( &pwcons[op->o_conn->c_conn_idx].dn );
+       }
 
        /* Root bypasses policy */
        if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn )) {
@@ -1026,11 +1030,14 @@ ppolicy_bind( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 }
 
-/* Reset the restricted flag for the next session on this connection */
+/* Reset the restricted info for the next session on this connection */
 static int
 ppolicy_connection_destroy( BackendDB *bd, Connection *conn )
 {
-       pwcons[conn->c_conn_idx].restricted = 0;
+       if ( !BER_BVISEMPTY( &pwcons[conn->c_conn_idx].dn )) {
+               ch_free( pwcons[conn->c_conn_idx].dn.bv_val );
+               BER_BVZERO( &pwcons[conn->c_conn_idx].dn );
+       }
        return SLAP_CB_CONTINUE;
 }
 
@@ -1048,7 +1055,18 @@ ppolicy_restrict(
                send_ctrl = 1;
        }
 
-       if ( op->o_conn && pwcons[op->o_conn->c_conn_idx].restricted ) {
+       if ( op->o_conn && !BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn )) {
+               /* if the current authcDN doesn't match the one we recorded,
+                * then an intervening Bind has succeeded and the restriction
+                * no longer applies. (ITS#4516)
+                */
+               if ( !dn_match( &op->o_conn->c_ndn,
+                               &pwcons[op->o_conn->c_conn_idx].dn )) {
+                       ch_free( pwcons[op->o_conn->c_conn_idx].dn.bv_val );
+                       BER_BVZERO( &pwcons[op->o_conn->c_conn_idx].dn );
+                       return SLAP_CB_CONTINUE;
+               }
+
                Debug( LDAP_DEBUG_TRACE,
                        "connection restricted to password changing only\n", 0, 0, 0);
                if ( send_ctrl ) {
@@ -1354,13 +1372,19 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                }
        }
        
-       if (pwcons[op->o_conn->c_conn_idx].restricted && !mod_pw_only) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "connection restricted to password changing only\n", 0, 0, 0 );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS; 
-               rs->sr_text = "Operations are restricted to bind/unbind/abandon/StartTLS/modify password";
-               pErr = PP_changeAfterReset;
-               goto return_results;
+       if (!BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn ) && !mod_pw_only ) {
+               if ( dn_match( &op->o_conn->c_ndn,
+                               &pwcons[op->o_conn->c_conn_idx].dn )) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "connection restricted to password changing only\n", 0, 0, 0 );
+                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS; 
+                       rs->sr_text = "Operations are restricted to bind/unbind/abandon/StartTLS/modify password";
+                       pErr = PP_changeAfterReset;
+                       goto return_results;
+               } else {
+                       ch_free( pwcons[op->o_conn->c_conn_idx].dn.bv_val );
+                       BER_BVZERO( &pwcons[op->o_conn->c_conn_idx].dn );
+               }
        }
 
        /*