]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/ppolicy.c
check for ee == NULL
[openldap] / servers / slapd / overlays / ppolicy.c
index 68216d445ae635ab4a570c5d5a3f139d18ede91f..e126598055cc1fd3e186c8091899474709639bce 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2004-2006 The OpenLDAP Foundation.
+ * Copyright 2004-2007 The OpenLDAP Foundation.
  * Portions Copyright 2004-2005 Howard Chu, Symas Corporation.
  * Portions Copyright 2004 Hewlett-Packard Company.
  * All rights reserved.
@@ -31,7 +31,7 @@
 #include <ldap.h>
 #include "lutil.h"
 #include "slap.h"
-#if SLAPD_MODULES
+#ifdef SLAPD_MODULES
 #define LIBLTDL_DLL_IMPORT     /* Win32: don't re-export libltdl's symbols */
 #include <ltdl.h>
 #endif
@@ -61,6 +61,7 @@ typedef struct pw_conn {
 
 static pw_conn *pwcons;
 static int ppolicy_cid;
+static int ov_count;
 
 typedef struct pass_policy {
        AttributeDescription *ad; /* attribute to which the policy applies */
@@ -358,6 +359,8 @@ account_locked( Operation *op, Entry *e,
 #define PPOLICY_EXPIRE 0x80L   /* primitive + 0 */
 #define PPOLICY_GRACE  0x81L   /* primitive + 1 */
 
+static const char ppolicy_ctrl_oid[] = LDAP_CONTROL_PASSWORDPOLICYRESPONSE;
+
 static LDAPControl *
 create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
 {
@@ -370,7 +373,7 @@ create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
        if ( c == NULL ) {
                return NULL;
        }
-       c->ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYRESPONSE;
+       c->ldctl_oid = (char *)ppolicy_ctrl_oid;
        c->ldctl_iscritical = 0;
        BER_BVZERO( &c->ldctl_value );
 
@@ -618,7 +621,7 @@ check_password_quality( struct berval *cred, PassPolicy *pp, LDAPPasswordPolicyE
        rc = LDAP_SUCCESS;
 
        if (pp->pwdCheckModule[0]) {
-#if SLAPD_MODULES
+#ifdef SLAPD_MODULES
                lt_dlhandle mod;
                const char *err;
                
@@ -645,13 +648,12 @@ check_password_quality( struct berval *cred, PassPolicy *pp, LDAPPasswordPolicyE
                                ldap_pvt_thread_mutex_lock( &chk_syntax_mutex );
                                ok = prog( cred->bv_val, &txt, e );
                                ldap_pvt_thread_mutex_unlock( &chk_syntax_mutex );
-                               if (txt) {
+                               if (ok != LDAP_SUCCESS) {
                                        Debug(LDAP_DEBUG_ANY,
                                                "check_password_quality: module error: (%s) %s.[%d]\n",
-                                               pp->pwdCheckModule, txt, ok );
+                                               pp->pwdCheckModule, txt ? txt : "", ok );
                                        free(txt);
-                               } else
-                                       ok = LDAP_SUCCESS;
+                               }
                        }
                            
                        lt_dlclose( mod );
@@ -851,7 +853,7 @@ ctrls_cleanup( Operation *op, SlapReply *rs, LDAPControl **oldctrls )
        assert( rs->sr_ctrls[0] != NULL );
 
        for ( n = 0; rs->sr_ctrls[n]; n++ ) {
-               if ( rs->sr_ctrls[n]->ldctl_oid == LDAP_CONTROL_PASSWORDPOLICYRESPONSE ) {
+               if ( rs->sr_ctrls[n]->ldctl_oid == ppolicy_ctrl_oid ) {
                        ch_free( rs->sr_ctrls[n]->ldctl_value.bv_val );
                        ch_free( rs->sr_ctrls[n] );
                        rs->sr_ctrls[n] = (LDAPControl *)(-1);
@@ -919,6 +921,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
                m->sml_flags = 0;
                m->sml_type = ad_pwdFailureTime->ad_cname;
                m->sml_desc = ad_pwdFailureTime;
+               m->sml_numvals = 1;
                m->sml_values = ch_calloc( sizeof(struct berval), 2 );
                m->sml_nvalues = ch_calloc( sizeof(struct berval), 2 );
 
@@ -968,6 +971,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
                        m->sml_flags = 0;
                        m->sml_type = ad_pwdAccountLockedTime->ad_cname;
                        m->sml_desc = ad_pwdAccountLockedTime;
+                       m->sml_numvals = 1;
                        m->sml_values = ch_calloc( sizeof(struct berval), 2 );
                        m->sml_nvalues = ch_calloc( sizeof(struct berval), 2 );
                        ber_dupbv( &m->sml_values[0], &timestamp );
@@ -1060,6 +1064,7 @@ grace:
                m->sml_flags = 0;
                m->sml_type = ad_pwdGraceUseTime->ad_cname;
                m->sml_desc = ad_pwdGraceUseTime;
+               m->sml_numvals = 1;
                m->sml_values = ch_calloc( sizeof(struct berval), 2 );
                m->sml_nvalues = ch_calloc( sizeof(struct berval), 2 );
                ber_dupbv( &m->sml_values[0], &timestamp );
@@ -1283,7 +1288,7 @@ ppolicy_add(
        if ((pa = attr_find( op->oq_add.rs_e->e_attrs,
                slap_schema.si_ad_userPassword )))
        {
-               assert( pa->a_vals );
+               assert( pa->a_vals != NULL );
                assert( !BER_BVISNULL( &pa->a_vals[ 0 ] ) );
 
                if ( !BER_BVISNULL( &pa->a_vals[ 1 ] ) ) {
@@ -1467,6 +1472,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                                ml->sml_flags = SLAP_MOD_INTERNAL;
                                ml->sml_type.bv_val = NULL;
                                ml->sml_desc = ad_pwdGraceUseTime;
+                               ml->sml_numvals = 0;
                                ml->sml_values = NULL;
                                ml->sml_nvalues = NULL;
                                ml->sml_next = NULL;
@@ -1479,6 +1485,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                                ml->sml_flags = SLAP_MOD_INTERNAL;
                                ml->sml_type.bv_val = NULL;
                                ml->sml_desc = ad_pwdAccountLockedTime;
+                               ml->sml_numvals = 0;
                                ml->sml_values = NULL;
                                ml->sml_nvalues = NULL;
                                ml->sml_next = NULL;
@@ -1490,6 +1497,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                                ml->sml_flags = SLAP_MOD_INTERNAL;
                                ml->sml_type.bv_val = NULL;
                                ml->sml_desc = ad_pwdFailureTime;
+                               ml->sml_numvals = 0;
                                ml->sml_values = NULL;
                                ml->sml_nvalues = NULL;
                                ml->sml_next = NULL;
@@ -1513,7 +1521,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                slap_callback *sc;
 
                for ( sc = op->o_callback; sc; sc=sc->sc_next ) {
-                       if ( sc->sc_response == slap_replog_cb &&
+                       if ( sc->sc_response == slap_null_cb &&
                                sc->sc_private ) {
                                req_pwdexop_s *qpw = sc->sc_private;
                                newpw = qpw->rs_new;
@@ -1669,6 +1677,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                ml->sml_flags = SLAP_MOD_INTERNAL;
                ml->sml_desc = pp.ad;
                ml->sml_type = pp.ad->ad_cname;
+               ml->sml_numvals = 1;
                ml->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
                ber_dupbv( &ml->sml_values[0], &oldpw );
                BER_BVZERO( &ml->sml_values[1] );
@@ -1695,7 +1704,10 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-       if (pp.pwdMinAge > 0) {
+       /* Check age, but only if pwdReset is not TRUE */
+       pa = attr_find( e->e_attrs, ad_pwdReset );
+       if ((!pa || !bvmatch( &pa->a_nvals[0], &slap_true_bv )) &&
+               pp.pwdMinAge > 0) {
                time_t pwtime = (time_t)-1, now;
                int age;
 
@@ -1833,6 +1845,7 @@ do_modify:
                mods->sml_desc = ad_pwdChangedTime;
                if (pwmop != LDAP_MOD_DELETE) {
                        mods->sml_op = LDAP_MOD_REPLACE;
+                       mods->sml_numvals = 1;
                        mods->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
                        ber_dupbv( &mods->sml_values[0], &timestamp );
                        BER_BVZERO( &mods->sml_values[1] );
@@ -1909,6 +1922,7 @@ do_modify:
                                mods->sml_op = LDAP_MOD_DELETE;
                                mods->sml_flags = SLAP_MOD_INTERNAL;
                                mods->sml_desc = ad_pwdHistory;
+                               mods->sml_numvals = hsize - pp.pwdInHistory + 1;
                                mods->sml_values = ch_calloc( sizeof( struct berval ),
                                        hsize - pp.pwdInHistory + 2 );
                                BER_BVZERO( &mods->sml_values[ hsize - pp.pwdInHistory + 1 ] );
@@ -1940,6 +1954,7 @@ do_modify:
                                mods->sml_type.bv_val = NULL;
                                mods->sml_desc = ad_pwdHistory;
                                mods->sml_nvalues = NULL;
+                               mods->sml_numvals = 1;
                                mods->sml_values = ch_calloc( sizeof( struct berval ), 2 );
                                mods->sml_values[ 1 ].bv_val = NULL;
                                mods->sml_values[ 1 ].bv_len = 0;
@@ -2019,8 +2034,8 @@ ppolicy_parseCtrl(
        SlapReply *rs,
        LDAPControl *ctrl )
 {
-       if ( ctrl->ldctl_value.bv_len ) {
-               rs->sr_text = "passwordPolicyRequest control value not empty";
+       if ( !BER_BVISNULL( &ctrl->ldctl_value ) ) {
+               rs->sr_text = "passwordPolicyRequest control value not absent";
                return LDAP_PROTOCOL_ERROR;
        }
        op->o_ctrlflag[ppolicy_cid] = ctrl->ldctl_iscritical
@@ -2070,7 +2085,8 @@ attrNormalize(
 
 static int
 ppolicy_db_init(
-       BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
        slap_overinst *on = (slap_overinst *) be->bd_info;
@@ -2113,21 +2129,29 @@ ppolicy_db_init(
 
 static int
 ppolicy_db_open(
-    BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
+       ov_count++;
        return overlay_register_control( be, LDAP_CONTROL_PASSWORDPOLICYREQUEST );
 }
 
 static int
 ppolicy_close(
-       BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
        slap_overinst *on = (slap_overinst *) be->bd_info;
        pp_info *pi = on->on_bi.bi_private;
-       
-       free( pwcons );
+
+       /* Perhaps backover should provide bi_destroy hooks... */
+       ov_count--;
+       if ( ov_count <=0 && pwcons ) {
+               free( pwcons );
+               pwcons = NULL;
+       }
        free( pi->def_policy.bv_val );
        free( pi );