summaryrefslogtreecommitdiffstats
path: root/contrib/slapd-modules/autogroup
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:34:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:34:56 +0000
commit3102bdaf142acf3c952310cb620274258492a795 (patch)
tree907e389a831fe1f9dc5d94479d8457584b352434 /contrib/slapd-modules/autogroup
parentAdding debian version 2.6.7+dfsg-1~exp1. (diff)
downloadopenldap-3102bdaf142acf3c952310cb620274258492a795.tar.xz
openldap-3102bdaf142acf3c952310cb620274258492a795.zip
Merging upstream version 2.6.8+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/slapd-modules/autogroup')
-rw-r--r--contrib/slapd-modules/autogroup/Makefile24
-rw-r--r--contrib/slapd-modules/autogroup/README2
-rw-r--r--contrib/slapd-modules/autogroup/autogroup.c260
-rw-r--r--contrib/slapd-modules/autogroup/slapo-autogroup.57
4 files changed, 191 insertions, 102 deletions
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 <hyc@symas.com>
+# 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
+# <http://www.OpenLDAP.org/license.html>.
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 <http://www.openldap.org/>.
*
- * 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 );
@@ -956,6 +965,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)
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
@@ -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 <oc> <URL-ad> <member-ad>\": "
- "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.