static ConfigTable ppolicycfg[] = {
{ "ppolicy_default", "policyDN", 2, 2, 0,
- ARG_DN|ARG_MAGIC|PPOLICY_DEFAULT, ppolicy_cf_default,
+ ARG_DN|ARG_QUOTE|ARG_MAGIC|PPOLICY_DEFAULT, ppolicy_cf_default,
"( OLcfgOvAt:12.1 NAME 'olcPPolicyDefault' "
"DESC 'DN of a pwdPolicy object for uncustomized objects' "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
static const char ppolicy_ctrl_oid[] = LDAP_CONTROL_PASSWORDPOLICYRESPONSE;
static LDAPControl *
-create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
+create_passcontrol( Operation *op, int exptime, int grace, LDAPPasswordPolicyError err )
{
char berbuf[LBER_ELEMENT_SIZEOF], bb2[LBER_ELEMENT_SIZEOF];
BerElement *ber = (BerElement *)berbuf, *b2 = (BerElement *)bb2;
- LDAPControl *c;
+ LDAPControl c = { 0 }, *cp;
struct berval bv;
- c = ch_calloc( sizeof( LDAPControl ), 1 );
- if ( c == NULL ) {
- return NULL;
- }
- c->ldctl_oid = (char *)ppolicy_ctrl_oid;
- c->ldctl_iscritical = 0;
- BER_BVZERO( &c->ldctl_value );
+ BER_BVZERO( &c.ldctl_value );
ber_init2( ber, NULL, LBER_USE_DER );
ber_printf( ber, "{" /*}*/ );
}
ber_printf( ber, /*{*/ "N}" );
- if (ber_flatten2( ber, &(c->ldctl_value), 1 ) == LBER_DEFAULT) {
- ch_free(c);
- c = NULL;
+ if (ber_flatten2( ber, &(c.ldctl_value), 1 ) == LBER_DEFAULT) {
+ return NULL;
}
(void)ber_free_buf(ber);
- return c;
+ cp = op->o_tmpalloc( sizeof( LDAPControl ) + c.ldctl_value.bv_len, op->o_tmpmemctx );
+ cp->ldctl_oid = (char *)ppolicy_ctrl_oid;
+ cp->ldctl_iscritical = 0;
+ cp->ldctl_value.bv_val = (char *)&cp[1];
+ cp->ldctl_value.bv_len = c.ldctl_value.bv_len;
+ AC_MEMCPY( cp->ldctl_value.bv_val, c.ldctl_value.bv_val, c.ldctl_value.bv_len );
+ ber_memfree( c.ldctl_value.bv_val );
+
+ return cp;
}
static LDAPControl **
for ( n = 0; rs->sr_ctrls[n]; n++ ) {
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] );
+ op->o_tmpfree( rs->sr_ctrls[n], op->o_tmpmemctx );
rs->sr_ctrls[n] = (LDAPControl *)(-1);
break;
}
if ( ppb->pErr == PP_accountLocked && !pi->use_lockout ) {
ppb->pErr = PP_noError;
}
- ctrl = create_passcontrol( warn, ngut, ppb->pErr );
+ ctrl = create_passcontrol( op, warn, ngut, ppb->pErr );
ppb->oldctrls = add_passcontrol( op, rs, ctrl );
op->o_callback->sc_cleanup = ppolicy_ctrls_cleanup;
}
"connection restricted to password changing only\n", 0, 0, 0);
if ( send_ctrl ) {
LDAPControl *ctrl = NULL;
- ctrl = create_passcontrol( -1, -1, PP_changeAfterReset );
+ ctrl = create_passcontrol( op, -1, -1, PP_changeAfterReset );
oldctrls = add_passcontrol( op, rs, ctrl );
}
op->o_bd->bd_info = (BackendInfo *)on->on_info;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
if ( send_ctrl ) {
LDAPControl *ctrl = NULL;
- ctrl = create_passcontrol( -1, -1, pErr );
+ ctrl = create_passcontrol( op, -1, -1, pErr );
oldctrls = add_passcontrol( op, rs, ctrl );
}
send_ldap_error( op, rs, rc, "Password fails quality checking policy" );
struct berval newpw = BER_BVNULL, oldpw = BER_BVNULL,
*bv, cr[2];
LDAPPasswordPolicyError pErr = PP_noError;
+ LDAPControl *ctrl = NULL;
LDAPControl **oldctrls = NULL;
+ int is_pwdexop = 0;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
req_pwdexop_s *qpw = sc->sc_private;
newpw = qpw->rs_new;
oldpw = qpw->rs_old;
+ is_pwdexop = 1;
break;
}
}
}
}
- } else if ( !is_at_operational( ml->sml_desc->ad_type ) ) {
+ } else if ( !(ml->sml_flags & SLAP_MOD_INTERNAL) && !is_at_operational( ml->sml_desc->ad_type ) ) {
mod_pw_only = 0;
/* modifying something other than password */
}
op->o_bd->bd_info = (BackendInfo *)on->on_info;
be_entry_release_r( op, e );
if ( send_ctrl ) {
- LDAPControl *ctrl = NULL;
-
- ctrl = create_passcontrol( -1, -1, pErr );
+ ctrl = create_passcontrol( op, -1, -1, pErr );
oldctrls = add_passcontrol( op, rs, ctrl );
}
send_ldap_result( op, rs );
if ( send_ctrl ) {
- ctrls_cleanup( op, rs, oldctrls );
+ if ( is_pwdexop ) {
+ if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
+ op->o_tmpfree( oldctrls, op->o_tmpmemctx );
+ }
+ oldctrls = NULL;
+ rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
+
+ } else {
+ ctrls_cleanup( op, rs, oldctrls );
+ }
}
return rs->sr_err;
}