ITS#7080 Postread control support for back-ldif/config

This commit is contained in:
Ondřej Kuzník 2021-05-12 11:04:08 +01:00 committed by Quanah Gibson-Mount
parent 5e4f1e862f
commit a2e9cb1acd
2 changed files with 226 additions and 0 deletions

View File

@ -1399,6 +1399,12 @@ ldif_back_add( Operation *op, SlapReply *rs )
char textbuf[SLAP_TEXT_BUFLEN];
int rc;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
Debug( LDAP_DEBUG_TRACE, "ldif_back_add: \"%s\"\n", e->e_dn );
rc = entry_schema_check( op, e, NULL, 0, 1, NULL,
@ -1413,6 +1419,26 @@ ldif_back_add( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_lock( &li->li_modop_mutex );
rc = ldif_prepare_create( op, e, &path, &parentdir, &rs->sr_text );
if ( rc == LDAP_SUCCESS && op->o_postread ) {
if ( postread_ctrl == NULL ) {
postread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, e,
&slap_post_read_bv, postread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "ldif_back_add: "
"post-read failed \"%s\"\n",
e->e_name.bv_val );
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
rc = rs->sr_err;
}
}
}
if ( rc == LDAP_SUCCESS ) {
ldap_pvt_thread_rdwr_wlock( &li->li_rdwr );
rc = ldif_write_entry( op, e, &path, parentdir, &rs->sr_text );
@ -1427,6 +1453,7 @@ ldif_back_add( Operation *op, SlapReply *rs )
send_res:
rs->sr_err = rc;
if ( num_ctrls ) rs->sr_ctrls = ctrls;
Debug( LDAP_DEBUG_TRACE, "ldif_back_add: err: %d text: %s\n",
rc, rs->sr_text ? rs->sr_text : "" );
send_ldap_result( op, rs );
@ -1445,13 +1472,59 @@ ldif_back_modify( Operation *op, SlapReply *rs )
char textbuf[SLAP_TEXT_BUFLEN];
int rc;
LDAPControl **preread_ctrl = NULL;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
slap_mods_opattrs( op, &op->orm_modlist, 1 );
ldap_pvt_thread_mutex_lock( &li->li_modop_mutex );
rc = get_entry( op, &entry, &path, &rs->sr_text );
if ( rc == LDAP_SUCCESS ) {
if ( op->o_preread ) {
if ( preread_ctrl == NULL ) {
preread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, entry,
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "ldif_back_modify: "
"pre-read failed \"%s\"\n",
entry->e_name.bv_val );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
rc = rs->sr_err;
}
}
}
rc = apply_modify_to_entry( entry, modlst, op, rs, textbuf );
if ( rc == LDAP_SUCCESS && op->o_postread ) {
if ( postread_ctrl == NULL ) {
postread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, entry,
&slap_post_read_bv, postread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "ldif_back_modify: "
"post-read failed \"%s\"\n",
entry->e_name.bv_val );
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
rc = rs->sr_err;
}
}
}
if ( rc == LDAP_SUCCESS ) {
ldap_pvt_thread_rdwr_wlock( &li->li_rdwr );
rc = ldif_write_entry( op, entry, &path, NULL, &rs->sr_text );
@ -1465,6 +1538,7 @@ ldif_back_modify( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_unlock( &li->li_modop_mutex );
rs->sr_err = rc;
if ( num_ctrls ) rs->sr_ctrls = ctrls;
send_ldap_result( op, rs );
slap_graduate_commit_csn( op );
rs->sr_text = NULL; /* remove possible pointer to textbuf */
@ -1479,6 +1553,12 @@ ldif_back_delete( Operation *op, SlapReply *rs )
int rc = LDAP_SUCCESS;
char ebuf[128];
LDAPControl **preread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
if ( BER_BVISEMPTY( &op->o_csn )) {
struct berval csn;
char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE];
@ -1517,6 +1597,30 @@ ldif_back_delete( Operation *op, SlapReply *rs )
}
}
/* pre-read */
if ( op->o_preread ) {
Entry *e = NULL;
if ( preread_ctrl == NULL ) {
preread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
rc = get_entry( op, &e, &path, &rs->sr_text );
if ( rc == LDAP_SUCCESS && slap_read_controls( op, rs, e,
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "ldif_back_delete: "
"pre-read failed \"%s\"\n",
e->e_name.bv_val );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
rc = rs->sr_err;
}
}
entry_free( e );
}
if ( rc == LDAP_SUCCESS ) {
dir2ldif_name( path );
if ( unlink( path.bv_val ) < 0 ) {
@ -1538,6 +1642,7 @@ ldif_back_delete( Operation *op, SlapReply *rs )
ldap_pvt_thread_rdwr_wunlock( &li->li_rdwr );
ldap_pvt_thread_mutex_unlock( &li->li_modop_mutex );
rs->sr_err = rc;
if ( num_ctrls ) rs->sr_ctrls = ctrls;
send_ldap_result( op, rs );
slap_graduate_commit_csn( op );
return rs->sr_err;
@ -1987,6 +2092,8 @@ ldif_back_initialize( BackendInfo *bi )
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_PRE_READ,
LDAP_CONTROL_POST_READ,
NULL
};
int rc;

View File

@ -5945,6 +5945,12 @@ config_back_add( Operation *op, SlapReply *rs )
int renumber, dopause = 1;
ConfigArgs ca;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
NULL, ACL_WADD, NULL )) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
@ -6031,6 +6037,22 @@ config_back_add( Operation *op, SlapReply *rs )
op->o_callback = scp;
op->o_dn = dn;
op->o_ndn = ndn;
} else if ( op->o_postread ) {
if ( postread_ctrl == NULL ) {
postread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, op->ora_e,
&slap_post_read_bv, postread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "ldif_back_modify: "
"post-read failed \"%s\"\n",
op->ora_e->e_name.bv_val );
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
}
}
}
out2:;
@ -6433,6 +6455,13 @@ config_back_modify( Operation *op, SlapReply *rs )
AttributeDescription *rad = NULL;
int do_pause = 1;
LDAPControl **preread_ctrl = NULL;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
cfb = (CfBackInfo *)op->o_bd->be_private;
ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
@ -6474,6 +6503,26 @@ config_back_modify( Operation *op, SlapReply *rs )
slap_mods_opattrs( op, &op->orm_modlist, 1 );
/* If we have a backend, it will handle the control */
if ( !cfb->cb_use_ldif && op->o_preread ) {
if ( preread_ctrl == NULL ) {
preread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, ce->ce_entry,
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "config_back_modify: "
"pre-read failed \"%s\"\n",
ce->ce_entry->e_name.bv_val );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
goto out;
}
}
}
if ( do_pause ) {
if ( op->o_abandon ) {
rs->sr_err = SLAPD_ABANDON;
@ -6511,11 +6560,24 @@ config_back_modify( Operation *op, SlapReply *rs )
op->o_callback = scp;
op->o_dn = dn;
op->o_ndn = ndn;
} else if ( op->o_postread ) {
if ( postread_ctrl == NULL ) {
postread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, ce->ce_entry,
&slap_post_read_bv, postread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "config_back_modify: "
"post-read failed \"%s\"\n",
ce->ce_entry->e_name.bv_val );
}
}
if ( do_pause )
slap_unpause_server();
out:
if ( num_ctrls ) rs->sr_ctrls = ctrls;
send_ldap_result( op, rs );
slap_graduate_commit_csn( op );
return rs->sr_err;
@ -6529,6 +6591,13 @@ config_back_modrdn( Operation *op, SlapReply *rs )
struct berval rdn;
int ixold, ixnew, dopause = 1;
LDAPControl **preread_ctrl = NULL;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
cfb = (CfBackInfo *)op->o_bd->be_private;
ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
@ -6645,6 +6714,26 @@ config_back_modrdn( Operation *op, SlapReply *rs )
goto out;
}
/* If we have a backend, it will handle the control */
if ( !cfb->cb_use_ldif && op->o_preread ) {
if ( preread_ctrl == NULL ) {
preread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, ce->ce_entry,
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "config_back_modrdn: "
"pre-read failed \"%s\"\n",
ce->ce_entry->e_name.bv_val );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
goto out;
}
}
}
if ( op->o_abandon ) {
rs->sr_err = SLAPD_ABANDON;
goto out;
@ -6719,6 +6808,7 @@ config_back_modrdn( Operation *op, SlapReply *rs )
if ( dopause )
slap_unpause_server();
out:
if ( num_ctrls ) rs->sr_ctrls = ctrls;
send_ldap_result( op, rs );
return rs->sr_err;
}
@ -6731,8 +6821,34 @@ config_back_delete( Operation *op, SlapReply *rs )
CfEntryInfo *ce, *last, *ce2;
int dopause = 1;
LDAPControl **preread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
ctrls[num_ctrls] = NULL;
cfb = (CfBackInfo *)op->o_bd->be_private;
/* If we have a backend, it will handle the control */
if ( ce && !cfb->cb_use_ldif && op->o_preread ) {
if ( preread_ctrl == NULL ) {
preread_ctrl = &ctrls[num_ctrls++];
ctrls[num_ctrls] = NULL;
}
if ( slap_read_controls( op, rs, ce->ce_entry,
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_ANY, "config_back_delete: "
"pre-read failed \"%s\"\n",
ce->ce_entry->e_name.bv_val );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
goto out;
}
}
}
ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
if ( !ce ) {
if ( last )
@ -6863,6 +6979,7 @@ config_back_delete( Operation *op, SlapReply *rs )
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
}
out:
if ( num_ctrls ) rs->sr_ctrls = ctrls;
#else
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
#endif /* SLAP_CONFIG_DELETE */
@ -8022,6 +8139,8 @@ config_back_initialize( BackendInfo *bi )
const char *text;
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_PRE_READ,
LDAP_CONTROL_POST_READ,
NULL
};