From 3102bdaf142acf3c952310cb620274258492a795 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 3 Jun 2024 07:34:56 +0200 Subject: Merging upstream version 2.6.8+dfsg. Signed-off-by: Daniel Baumann --- contrib/slapd-modules/autogroup/Makefile | 24 +- contrib/slapd-modules/autogroup/README | 2 +- contrib/slapd-modules/autogroup/autogroup.c | 260 ++++++++++++++-------- contrib/slapd-modules/autogroup/slapo-autogroup.5 | 7 +- 4 files changed, 191 insertions(+), 102 deletions(-) (limited to 'contrib/slapd-modules/autogroup') diff --git a/contrib/slapd-modules/autogroup/Makefile b/contrib/slapd-modules/autogroup/Makefile index 2446657..a888c23 100644 --- a/contrib/slapd-modules/autogroup/Makefile +++ b/contrib/slapd-modules/autogroup/Makefile @@ -1,4 +1,14 @@ # $OpenLDAP$ +# Copyright 2007 Howard Chu +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted only as authorized by the OpenLDAP +# Public License. +# +# A copy of this license is available in the file LICENSE in the +# top-level directory of the distribution or, alternatively, at +# . LDAP_SRC = ../../.. LDAP_BUILD = $(LDAP_SRC) @@ -12,6 +22,7 @@ NT_LDFLAGS = -no-undefined -avoid-version UNIX_LDFLAGS = -version-info $(LTVER) LIBTOOL = $(LDAP_BUILD)/libtool +INSTALL = /usr/bin/install CC = gcc OPT = -g -O2 DEFS = @@ -20,6 +31,7 @@ LIBS = $($(PLAT)_LIB) $(LDAP_LIB) LD_FLAGS = $(LDFLAGS) $($(PLAT)_LDFLAGS) -rpath $(moduledir) -module PROGRAMS = autogroup.la +MANPAGES = slapo-autogroup.5 LTVER = 0:0:0 prefix=/usr/local @@ -29,6 +41,8 @@ ldap_subdir=/openldap libdir=$(exec_prefix)/lib libexecdir=$(exec_prefix)/libexec moduledir = $(libexecdir)$(ldap_subdir) +mandir = $(exec_prefix)/share/man +man5dir = $(mandir)/man5 .SUFFIXES: .c .o .lo @@ -43,9 +57,17 @@ autogroup.la: autogroup.lo clean: rm -rf *.o *.lo *.la .libs -install: $(PROGRAMS) +install: install-lib install-man FORCE + +install-lib: $(PROGRAMS) mkdir -p $(DESTDIR)$(moduledir) for p in $(PROGRAMS) ; do \ $(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \ done +install-man: + mkdir -p $(DESTDIR)$(man5dir) + $(INSTALL) -m 644 $(MANPAGES) $(DESTDIR)$(man5dir) + +FORCE: + diff --git a/contrib/slapd-modules/autogroup/README b/contrib/slapd-modules/autogroup/README index b68dd75..4f11cf5 100644 --- a/contrib/slapd-modules/autogroup/README +++ b/contrib/slapd-modules/autogroup/README @@ -107,7 +107,7 @@ ACKNOWLEDGEMENTS Norbert Pueschel, and Christian Manal. --- -Copyright 1998-2022 The OpenLDAP Foundation. +Copyright 1998-2024 The OpenLDAP Foundation. Portions Copyright (C) 2007 Michał Szulczyński. All rights reserved. diff --git a/contrib/slapd-modules/autogroup/autogroup.c b/contrib/slapd-modules/autogroup/autogroup.c index cba9b2a..beec3c3 100644 --- a/contrib/slapd-modules/autogroup/autogroup.c +++ b/contrib/slapd-modules/autogroup/autogroup.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2007-2022 The OpenLDAP Foundation. + * Copyright 2007-2024 The OpenLDAP Foundation. * Portions Copyright 2007 Michał Szulczyński. * Portions Copyright 2009 Howard Chu. * All rights reserved. @@ -150,6 +150,7 @@ autogroup_add_member_to_group( Operation *op, BerValue *dn, BerValue *ndn, autog o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + o.o_abandon = 0; oex.oe_key = (void *)&autogroup; LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); @@ -206,6 +207,7 @@ autogroup_add_member_values_to_group( Operation *op, struct berval *dn, autogrou o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + o.o_abandon = 0; oex.oe_key = (void *)&autogroup; LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); @@ -279,6 +281,7 @@ autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn, o.o_permissive_modify = 1; o.o_dont_replicate = 1; o.orm_no_opattrs = 1; + o.o_abandon = 0; oex.oe_key = (void *)&autogroup; LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); @@ -335,6 +338,7 @@ autogroup_delete_member_values_from_group( Operation *op, struct berval *dn, aut o.orm_no_opattrs = 1; o.o_managedsait = SLAP_CONTROL_CRITICAL; o.o_relax = SLAP_CONTROL_CRITICAL; + o.o_abandon = 0; oex.oe_key = (void *)&autogroup; LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); @@ -502,6 +506,10 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_members_from_filter <%s>\n", age->age_dn.bv_val ); + /* if modify isn't set, we're pre-op and should honor abandon flag */ + if ( op->o_abandon && !modify ) + return 0; + o.ors_attrsonly = 0; o.o_tag = LDAP_REQ_SEARCH; @@ -520,6 +528,7 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a o.ors_slimit = SLAP_NO_LIMIT; o.ors_attrs = agf->agf_anlist ? agf->agf_anlist : slap_anlist_no_attrs; o.o_do_not_cache = 1; + o.o_abandon = 0; agg.agg_group = age; agg.agg_filter = agf; @@ -562,6 +571,7 @@ autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *a o.o_permissive_modify = 1; o.o_dont_replicate = 1; o.orm_no_opattrs = 1; + o.o_abandon = 0; oex.oe_key = (void *)&autogroup; LDAP_SLIST_INSERT_HEAD( &o.o_extra, &oex, oe_next ); @@ -598,7 +608,7 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, LDAPURLDesc *lud = NULL; Attribute *a; BerValue *bv, dn; - int rc = 0, match = 1, null_entry = 0; + int rc = 0, null_entry = 0; if ( e == NULL ) { if ( overlay_entry_get_ov( op, ndn, NULL, NULL, 0, &e, on ) != @@ -615,8 +625,7 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, if ( agi->agi_entry != NULL ) { for ( ; *agep ; agep = &(*agep)->age_next ) { - dnMatch( &match, 0, NULL, NULL, &e->e_nname, &(*agep)->age_ndn ); - if ( match == 0 ) { + if ( dn_match( &e->e_nname, &(*agep)->age_ndn )) { Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: group already exists: <%s>\n", e->e_name.bv_val ); return 1; } @@ -672,8 +681,12 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, } if ( lud->lud_filter != NULL ) { - ber_str2bv( lud->lud_filter, 0, 1, &agf->agf_filterstr); agf->agf_filter = str2filter( lud->lud_filter ); + if ( !agf->agf_filter ) { + Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: URL filter is invalid <%s>\n", bv->bv_val ); + goto cleanup; + } + ber_str2bv( lud->lud_filter, 0, 1, &agf->agf_filterstr); } else { Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: URL filter is missing <%s>\n", bv->bv_val ); /* FIXME: error? */ @@ -681,13 +694,7 @@ autogroup_add_group( Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, } if ( lud->lud_attrs != NULL ) { - int i; - - for ( i=0 ; lud->lud_attrs[i]!=NULL ; i++) { - /* Just counting */; - } - - if ( i > 1 ) { + if ( lud->lud_attrs[1] != NULL ) { Debug( LDAP_DEBUG_ANY, "autogroup_add_group: too many attributes specified in url <%s>\n", bv->bv_val ); /* FIXME: error? */ @@ -795,10 +802,7 @@ autogroup_add_entry_cb( Operation *op, SlapReply *rs ) goto done; op->o_bd->bd_info = (BackendInfo *)on; - ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); - if ( aa->agd ) { - autogroup_add_group( op, agi, aa->agd, aa->e, NULL, 1 , 0); - } else { + { autogroup_entry_t *age; autogroup_filter_t *agf; struct berval odn, ondn; @@ -810,6 +814,7 @@ autogroup_add_entry_cb( Operation *op, SlapReply *rs ) op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; + ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); for ( age = agi->agi_entry; age ; age = age->age_next ) { ldap_pvt_thread_mutex_lock( &age->age_mutex ); @@ -817,7 +822,7 @@ autogroup_add_entry_cb( Operation *op, SlapReply *rs ) If yes, we can test that filter against the entry. */ for ( agf = age->age_filter; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { rc = test_filter( op, aa->e, agf->agf_filter ); if ( rc == LDAP_COMPARE_TRUE ) { if ( agf->agf_anlist ) { @@ -833,10 +838,10 @@ autogroup_add_entry_cb( Operation *op, SlapReply *rs ) } ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); op->o_dn = odn; op->o_ndn = ondn; } - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); op->o_bd->bd_info = bi; @@ -873,6 +878,7 @@ autogroup_add_entry( Operation *op, SlapReply *rs) op->o_callback = sc; /* Check if it's a group. */ + ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); for ( ; agd ; agd = agd->agd_next ) { if ( is_entry_objectclass_or_sub( op->ora_e, agd->agd_oc ) ) { Modification mod; @@ -889,10 +895,13 @@ autogroup_add_entry( Operation *op, SlapReply *rs) modify_delete_values( op->ora_e, &mod, /* permissive */ 1, &text, textbuf, sizeof( textbuf ) ); aa->agd = agd; + /* But we should populate the dynamic values immediately. */ + autogroup_add_group( op, agi, agd, op->ora_e, NULL, 1 , 0); break; } } + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; } @@ -922,7 +931,7 @@ autogroup_delete_group( autogroup_info_t *agi, autogroup_entry_t *e ) if ( age_prev != NULL ) { age_prev->age_next = age_next; } else { - agi->agi_entry = NULL; + agi->agi_entry = age_next; } ch_free( age->age_dn.bv_val ); @@ -955,6 +964,85 @@ autogroup_delete_group( autogroup_info_t *agi, autogroup_entry_t *e ) } +static int +autogroup_del_entry_cb( Operation *op, SlapReply *rs ) +{ + slap_callback *sc = op->o_callback; + ag_addinfo *aa = sc->sc_private; + slap_overinst *on = aa->on; + autogroup_info_t *agi = (autogroup_info_t *)on->on_bi.bi_private; + BackendInfo *bi = op->o_bd->bd_info; + struct berval odn, ondn; + autogroup_entry_t *age, *age_prev, *age_next; + autogroup_filter_t *agf; + + if ( rs->sr_err != LDAP_SUCCESS ) + goto done; + + ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); + + /* Check if the entry to be deleted is one of our groups. */ + for ( age = agi->agi_entry ; age ; age=age->age_next ) { + ldap_pvt_thread_mutex_lock( &age->age_mutex ); + if ( dn_match( &op->o_req_ndn, &age->age_ndn )) { + autogroup_delete_group( agi, age ); + break; + } + ldap_pvt_thread_mutex_unlock( &age->age_mutex ); + } + + if ( !aa->e ) { + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); + goto done; + } + + /* Check if the entry matches any of the groups. + If yes, we can delete the entry from that group. */ + + odn = op->o_dn; + ondn = op->o_ndn; + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + op->o_bd->bd_info = (BackendInfo *)on; + + for ( age = agi->agi_entry ; age ; age = age->age_next ) { + ldap_pvt_thread_mutex_lock( &age->age_mutex ); + + for ( agf = age->age_filter; agf ; agf = agf->agf_next ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { + int rc = test_filter( op, aa->e, agf->agf_filter ); + if ( rc == LDAP_COMPARE_TRUE ) { + /* If the attribute is retrieved from the entry, we don't know what to delete + ** So the group must be entirely refreshed + ** But the refresh can't be done now because the entry is not deleted + ** So the group is marked as mustrefresh + */ + if ( agf->agf_anlist ) { + age->age_mustrefresh = 1; + } else { + autogroup_delete_member_from_group( op, &aa->e->e_name, &aa->e->e_nname, age ); + } + break; + } + } + } + ldap_pvt_thread_mutex_unlock( &age->age_mutex ); + } + + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); + op->o_dn = odn; + op->o_ndn = ondn; + op->o_bd->bd_info = bi; + +done: + if ( aa->e ) + entry_free( aa->e ); + op->o_callback = sc->sc_next; + op->o_tmpfree( sc, op->o_tmpmemctx ); + + return SLAP_CB_CONTINUE; +} + static int autogroup_delete_entry( Operation *op, SlapReply *rs) { @@ -963,7 +1051,7 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) autogroup_entry_t *age, *age_prev, *age_next; autogroup_filter_t *agf; Entry *e; - int matched_group = 0, rc = 0; + int matched_group = 0, rc = 0, matched_entry = 0; struct berval odn, ondn; OpExtra *oex; @@ -976,38 +1064,21 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); - if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) != - LDAP_SUCCESS || e == NULL ) { - Debug( LDAP_DEBUG_TRACE, "autogroup_delete_entry: cannot get entry for <%s>\n", op->o_req_dn.bv_val ); - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - return SLAP_CB_CONTINUE; - } - /* Check if the entry to be deleted is one of our groups. */ - for ( age_next = agi->agi_entry ; age_next ; age_prev = age ) { - age = age_next; - ldap_pvt_thread_mutex_lock( &age->age_mutex ); - age_next = age->age_next; - - if ( is_entry_objectclass_or_sub( e, age->age_def->agd_oc ) ) { - int match = 1; - + for ( age = agi->agi_entry ; age ; age=age->age_next ) { + if ( dn_match( &op->o_req_ndn, &age->age_ndn )) { matched_group = 1; - - dnMatch( &match, 0, NULL, NULL, &e->e_nname, &age->age_ndn ); - - if ( match == 0 ) { - autogroup_delete_group( agi, age ); - break; - } + break; } - - ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } - if ( matched_group == 1 ) { - overlay_entry_release_ov( op, e, 0, on ); - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); + /* if matched_group, we wouldn't need to go further, but continuing + * this check allows for groups that are members of other groups + */ + if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) != + LDAP_SUCCESS || e == NULL ) { + Debug( LDAP_DEBUG_TRACE, "autogroup_delete_entry: cannot get entry for <%s>\n", op->o_req_dn.bv_val ); + ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; } @@ -1023,28 +1094,36 @@ autogroup_delete_entry( Operation *op, SlapReply *rs) ldap_pvt_thread_mutex_lock( &age->age_mutex ); for ( agf = age->age_filter; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { rc = test_filter( op, e, agf->agf_filter ); if ( rc == LDAP_COMPARE_TRUE ) { - /* If the attribute is retrieved from the entry, we don't know what to delete - ** So the group must be entirely refreshed - ** But the refresh can't be done now because the entry is not deleted - ** So the group is marked as mustrefresh - */ - if ( agf->agf_anlist ) { - age->age_mustrefresh = 1; - } else { - autogroup_delete_member_from_group( op, &e->e_name, &e->e_nname, age ); - } + matched_entry = 1; break; } } } ldap_pvt_thread_mutex_unlock( &age->age_mutex ); + if ( matched_entry ) + break; } + op->o_dn = odn; op->o_ndn = ondn; + if ( matched_group || matched_entry ) { + slap_callback *sc = op->o_tmpcalloc( sizeof(slap_callback) + sizeof(ag_addinfo), 1, op->o_tmpmemctx ); + ag_addinfo *aa; + + sc->sc_private = (sc+1); + sc->sc_response = autogroup_del_entry_cb; + aa = sc->sc_private; + aa->on = on; + if ( matched_entry ) + aa->e = entry_dup( e ); + sc->sc_next = op->o_callback; + op->o_callback = sc; + } + overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); @@ -1064,15 +1143,16 @@ autogroup_response( Operation *op, SlapReply *rs ) int is_olddn, is_newdn, is_value_refresh, dn_equal; OpExtra *oex; + if ( rs->sr_type != REP_RESULT || rs->sr_err != LDAP_SUCCESS ) + return SLAP_CB_CONTINUE; + LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { if ( oex->oe_key == (void *)&autogroup ) - break; + return SLAP_CB_CONTINUE; } /* Handle all cases where a refresh of the group is needed */ if ( op->o_tag == LDAP_REQ_DELETE || op->o_tag == LDAP_REQ_MODIFY ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { - ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); for ( age = agi->agi_entry ; age ; age = age->age_next ) { @@ -1092,16 +1172,14 @@ autogroup_response( Operation *op, SlapReply *rs ) } ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - } } else if ( op->o_tag == LDAP_REQ_MODRDN ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODRDN from <%s>\n", op->o_req_dn.bv_val ); - Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN to <%s>\n", op->orr_newDN ); + Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN to <%s>\n", op->orr_newDN.bv_val ); ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); - dnMatch( &dn_equal, 0, NULL, NULL, &op->o_req_ndn, &op->orr_nnewDN ); + dn_equal = dn_match( &op->o_req_ndn, &op->orr_nnewDN ); if ( overlay_entry_get_ov( op, &op->orr_nnewDN, NULL, NULL, 0, &e, on ) != LDAP_SUCCESS || e == NULL ) { @@ -1131,22 +1209,17 @@ autogroup_response( Operation *op, SlapReply *rs ) op->o_tmpmemctx ) == 0 ) { for ( age = agi->agi_entry ; age ; age = age->age_next ) { - int match = 1; - - dnMatch( &match, 0, NULL, NULL, &age->age_ndn, &op->o_req_ndn ); - if ( match == 0 ) { + if ( dn_match( &age->age_ndn, &op->o_req_ndn )) { Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN updating group's DN to <%s>\n", op->orr_newDN.bv_val ); - ber_dupbv( &age->age_dn, &op->orr_newDN ); - ber_dupbv( &age->age_ndn, &op->orr_nnewDN ); - - overlay_entry_release_ov( op, e, 0, on ); - ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - return SLAP_CB_CONTINUE; + ber_bvreplace( &age->age_dn, &op->orr_newDN ); + ber_bvreplace( &age->age_ndn, &op->orr_nnewDN ); + goto break1; } } } } +break1: /* For each group: 1. check if the original entry's DN is in the group. @@ -1209,7 +1282,7 @@ autogroup_response( Operation *op, SlapReply *rs ) } for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &op->orr_nnewDN, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->orr_nnewDN, &agf->agf_ndn, agf->agf_scope ) ) { /* TODO: should retest filter as it could imply conditions on the dn */ is_newdn = 1; break; @@ -1279,11 +1352,9 @@ autogroup_response( Operation *op, SlapReply *rs ) attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - } } if ( op->o_tag == LDAP_REQ_MODIFY ) { - if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { Entry etmp; struct berval odn, ondn; Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODIFY <%s>\n", op->o_req_dn.bv_val ); @@ -1317,17 +1388,12 @@ autogroup_response( Operation *op, SlapReply *rs ) a->a_nvals, &agd->agd_oc->soc_cname, op->o_tmpmemctx ) == 0 ) { - Modifications *m; - int match = 1; - - m = op->orm_modlist; + Modifications *m = op->orm_modlist; for ( age = agi->agi_entry ; age ; age = age->age_next ) { ldap_pvt_thread_mutex_lock( &age->age_mutex ); - dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn ); - - if ( match == 0 ) { + if ( dn_match( &op->o_req_ndn, &age->age_ndn )) { for ( ; m ; m = m->sml_next ) { if ( m->sml_desc == age->age_def->agd_member_url_ad ) { autogroup_def_t *group_agd = age->age_def; @@ -1420,7 +1486,7 @@ autogroup_response( Operation *op, SlapReply *rs ) overlay_entry_release_ov( op, group, 0, on ); for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { if ( test_filter( op, &etmp, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { is_newdn = 1; break; @@ -1449,7 +1515,6 @@ autogroup_response( Operation *op, SlapReply *rs ) attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); - } } return SLAP_CB_CONTINUE; @@ -1527,10 +1592,11 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) Modifications *m; for ( m = op->orm_modlist ; m ; m = m->sml_next ) { if ( m->sml_desc == agf->agf_anlist[0].an_desc ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { int rc = test_filter( op, e, agf->agf_filter ); if ( rc == LDAP_COMPARE_TRUE ) { age->age_mustrefresh = 1; + goto breakout; } } } @@ -1539,6 +1605,8 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) if ( autogroup_memberOf_filter( agf->agf_filter, &op->o_req_ndn, agi->agi_memberof_ad ) ) { age->age_mustrefresh = 1; +breakout: + break; } } } @@ -1562,15 +1630,10 @@ autogroup_modify_entry( Operation *op, SlapReply *rs) a->a_nvals, &agd->agd_oc->soc_cname, op->o_tmpmemctx ) == 0 ) { - Modifications *m; - int match = 1; - - m = op->orm_modlist; + Modifications *m = op->orm_modlist; for ( age = agi->agi_entry ; age ; age = age->age_next ) { - dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn ); - - if ( match == 0 ) { + if ( dn_match( &op->o_req_ndn, &age->age_ndn )) { for ( ; m ; m = m->sml_next ) { if ( m->sml_desc == age->age_def->agd_member_ad ) { overlay_entry_release_ov( op, e, 0, on ); @@ -1632,10 +1695,11 @@ autogroup_modrdn_entry( Operation *op, SlapReply *rs) autogroup_filter_t *agf; for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) { if ( agf->agf_anlist ) { - if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffixScope( &op->o_req_ndn, &agf->agf_ndn, agf->agf_scope ) ) { int rc = test_filter( op, e, agf->agf_filter ); if ( rc == LDAP_COMPARE_TRUE ) { age->age_modrdn_olddnmodified = 1; + break; } } } @@ -1813,7 +1877,7 @@ ag_cfgen( ConfigArgs *c ) ch_free( agf ); } - ldap_pvt_thread_mutex_init( &age->age_mutex ); + ldap_pvt_thread_mutex_destroy( &age->age_mutex ); ch_free( age ); } @@ -1912,7 +1976,7 @@ ag_cfgen( ConfigArgs *c ) if( !is_at_subtype( member_url_ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"autogroup-attrset \": " - "AttributeDescription \"%s\" ", + "AttributeDescription \"%s\" " "must be of a subtype \"labeledURI\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", diff --git a/contrib/slapd-modules/autogroup/slapo-autogroup.5 b/contrib/slapd-modules/autogroup/slapo-autogroup.5 index 4c6414d..eb16d88 100644 --- a/contrib/slapd-modules/autogroup/slapo-autogroup.5 +++ b/contrib/slapd-modules/autogroup/slapo-autogroup.5 @@ -1,5 +1,5 @@ .TH SLAPO-AUTOGROUP 5 "RELEASEDATE" "OpenLDAP LDVERSION" -.\" Copyright 1998-2022 The OpenLDAP Foundation All Rights Reserved. +.\" Copyright 1998-2024 The OpenLDAP Foundation All Rights Reserved. .\" Portions Copyright \[u00A9] 2007 Michał Szulczyński. .\" Copying restrictions apply. See the COPYRIGHT file. .\" $OpenLDAP$ @@ -29,6 +29,9 @@ tested for compliance with the filters, and its membership is accordingly updated. For searches and compares, it behaves like a static group. If the attribute part of the URI is filled, the group entry is populated by the values of this attribute in the entries resulting from the search. + +Note that filters that use attributes that are themselves dynamically +computed may not work consistently, and should be avoided. .SH CONFIGURATION Either .BR \FCslapd.conf\FT (5) @@ -111,6 +114,6 @@ updates provided by Emily Backes. .BR slapd.conf (5), .BR slapd (8). .SH Copyrights -Copyright 1998-2022 The OpenLDAP Foundation. +Copyright 1998-2024 The OpenLDAP Foundation. Portions Copyright \[u00A9] 2007 Michał Szulczyński. All rights reserved. -- cgit v1.2.3