diff --git a/servers/slapd/overlays/dynlist.c b/servers/slapd/overlays/dynlist.c
index 96c0b0cf20d30dddf57efdf74d4f2b886a9c8f32..8a080ceadcabbe3ebdd74530f89b7bfed5aca173 100644
--- a/servers/slapd/overlays/dynlist.c
+++ b/servers/slapd/overlays/dynlist.c
@@ -58,7 +58,7 @@ static AttributeName anlist_no_attrs[] = {
 static AttributeName *slap_anlist_no_attrs = anlist_no_attrs;
 #endif
 
-static AttributeDescription *ad_dgIdentity;
+static AttributeDescription *ad_dgIdentity, *ad_dgAuthz;
 
 typedef struct dynlist_info_t {
 	ObjectClass		*dli_oc;
@@ -348,6 +348,26 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
 		return SLAP_CB_CONTINUE;
 	}
 
+	if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
+		Attribute *authz = NULL;
+
+		/* if not rootdn and dgAuthz is present,
+		 * check if user can be authorized as dgIdentity */
+		if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
+			&& ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) )
+		{
+			if ( slap_sasl_matches( op, authz->a_nvals,
+				&o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
+			{
+				return SLAP_CB_CONTINUE;
+			}
+		}
+
+		o.o_dn = id->a_vals[0];
+		o.o_ndn = id->a_nvals[0];
+		o.o_groups = NULL;
+	}
+
 	if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
 		e = entry_dup( rs->sr_entry );
 	} else {
@@ -355,12 +375,6 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
 	}
 	e_flags = rs->sr_flags | ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
 
-	if ( ad_dgIdentity && ( id = attrs_find( e->e_attrs, ad_dgIdentity ))) {
-		o.o_dn = id->a_vals[0];
-		o.o_ndn = id->a_nvals[0];
-		o.o_groups = NULL;
-	}
-
 	dlc.dlc_e = e;
 	dlc.dlc_dli = dli;
 	cb.sc_private = &dlc;
@@ -557,16 +571,33 @@ dynlist_compare( Operation *op, SlapReply *rs )
 			 * interested in. We'll use slapd's existing dyngroup
 			 * evaluator to get the answer we want.
 			 */
-			struct berval *id = NULL;
+			BerVarray id = NULL, authz = NULL;
 
 			o.o_do_not_cache = 1;
 
 			if ( ad_dgIdentity && backend_attribute( &o, NULL, &o.o_req_ndn,
-				ad_dgIdentity, &id, ACL_READ ) == LDAP_SUCCESS ) {
+				ad_dgIdentity, &id, ACL_READ ) == LDAP_SUCCESS )
+			{
+				/* if not rootdn and dgAuthz is present,
+				 * check if user can be authorized as dgIdentity */
+				if ( ad_dgAuthz && !BER_BVISEMPTY( id ) && !be_isroot( op )
+					&& backend_attribute( &o, NULL, &o.o_req_ndn,
+						ad_dgAuthz, &authz, ACL_READ ) == LDAP_SUCCESS )
+				{
+					
+					rs->sr_err = slap_sasl_matches( op, authz,
+						&o.o_ndn, &o.o_ndn );
+					ber_bvarray_free_x( authz, op->o_tmpmemctx );
+					if ( rs->sr_err != LDAP_SUCCESS ) {
+						goto done;
+					}
+				}
+
 				o.o_dn = *id;
 				o.o_ndn = *id;
 				o.o_groups = NULL; /* authz changed, invalidate cached groups */
 			}
+
 			rs->sr_err = backend_group( &o, NULL, &o.o_req_ndn,
 				&o.oq_compare.rs_ava->aa_value, dli->dli_oc, dli->dli_ad );
 			switch ( rs->sr_err ) {
@@ -586,6 +617,7 @@ dynlist_compare( Operation *op, SlapReply *rs )
 				break;
 			}
 
+done:;
 			if ( id ) ber_bvarray_free_x( id, o.o_tmpmemctx );
 
 			return SLAP_CB_CONTINUE;
@@ -593,17 +625,34 @@ dynlist_compare( Operation *op, SlapReply *rs )
 	}
 
 	if ( overlay_entry_get_ov( &o, &o.o_req_ndn, NULL, NULL, 0, &e, on ) !=
-		LDAP_SUCCESS || e == NULL ) {
+		LDAP_SUCCESS || e == NULL )
+	{
 		return SLAP_CB_CONTINUE;
 	}
+
 	if ( ad_dgIdentity ) {
 		Attribute *id = attrs_find( e->e_attrs, ad_dgIdentity );
 		if ( id ) {
+			Attribute *authz;
+
+			/* if not rootdn and dgAuthz is present,
+			 * check if user can be authorized as dgIdentity */
+			if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
+				&& ( authz = attrs_find( e->e_attrs, ad_dgAuthz ) ) )
+			{
+				if ( slap_sasl_matches( op, authz->a_nvals,
+					&o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
+				{
+					goto release;
+				}
+			}
+
 			o.o_dn = id->a_vals[0];
 			o.o_ndn = id->a_nvals[0];
 			o.o_groups = NULL;
 		}
 	}
+
 	dli = (dynlist_info_t *)on->on_bi.bi_private;
 	for ( ; dli != NULL && rs->sr_err != LDAP_COMPARE_TRUE; dli = dli->dli_next ) {
 		Attribute	*a;
@@ -1353,6 +1402,15 @@ dynlist_db_open(
 		/* Just a warning */
 	}
 
+	rc = slap_str2ad( "dgAuthz", &ad_dgAuthz, &text );
+	if ( rc != LDAP_SUCCESS ) {
+		snprintf( cr->msg, sizeof( cr->msg),
+			"unable to fetch attributeDescription \"dgAuthz\": %d (%s)",
+			rc, text );
+		Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s\n", cr->msg, 0, 0 );
+		/* Just a warning */
+	}
+
 	return 0;
 }
 
diff --git a/servers/slapd/schema/dyngroup.schema b/servers/slapd/schema/dyngroup.schema
index 2e3366f14d74aaddab9ffd7e5ae8faff7e6c3287..b8244b3f493d4a207894f23df6b975943abf78f5 100644
--- a/servers/slapd/schema/dyngroup.schema
+++ b/servers/slapd/schema/dyngroup.schema
@@ -67,6 +67,13 @@ attributetype ( DynGroupAttr:1
 	DESC 'Identity to use when processing the memberURL'
 	SUP distinguishedName SINGLE-VALUE )
 
+attributeType ( DynGroupAttr:2
+	NAME 'dgAuthz'
+	DESC 'Optional authorization rules that determine who is allowed to assume the dgIdentity'
+	EQUALITY authzMatch
+	SYNTAX 1.3.6.1.4.1.4203.666.2.7
+	X-ORDERED 'VALUES' )
+
 objectClass ( NetscapeLDAPobjectClass:33
 	NAME 'groupOfURLs'
 	SUP top STRUCTURAL
@@ -79,4 +86,6 @@ objectClass ( NetscapeLDAPobjectClass:33
 objectClass ( DynGroupOC:1
 	NAME 'dgIdentityAux'
 	SUP top AUXILIARY
-	MAY dgIdentity )
+	MAY ( dgIdentity $ dgAuthz ) )
+
+
diff --git a/tests/data/dynlist.out b/tests/data/dynlist.out
index c6b5be3079cc8922acafda9c546b6cf9f028b5e7..370a5dafebaaca28850a677a3c4e9f00db1cb065 100644
--- a/tests/data/dynlist.out
+++ b/tests/data/dynlist.out
@@ -139,7 +139,7 @@ objectClass: groupOfURLs
 objectClass: dgIdentityAux
 cn: Dynamic List of Members
 memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
-dgIdentity: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=ex
+dgIdentity: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,dc=ex
  ample,dc=com
 member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
  ple,dc=com
@@ -156,3 +156,39 @@ member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
 member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
 member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
 
+# Testing list search with dgIdentity and dgAuthz anonymously...
+dn: cn=Dynamic List of Members,ou=Dynamic Lists,dc=example,dc=com
+objectClass: groupOfURLs
+objectClass: dgIdentityAux
+cn: Dynamic List of Members
+memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
+dgIdentity: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,dc=ex
+ ample,dc=com
+dgAuthz: {0}dn:cn=Barbara Jensen,ou=Information Technology DivisioN,ou=People,
+ dc=example,dc=com
+
+# Testing list search with dgIdentity and dgAuthz as the authorized identity...
+dn: cn=Dynamic List of Members,ou=Dynamic Lists,dc=example,dc=com
+objectClass: groupOfURLs
+objectClass: dgIdentityAux
+cn: Dynamic List of Members
+memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
+dgIdentity: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,dc=ex
+ ample,dc=com
+dgAuthz: {0}dn:cn=Barbara Jensen,ou=Information Technology DivisioN,ou=People,
+ dc=example,dc=com
+member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
+ ple,dc=com
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
+ e,dc=com
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
+ mple,dc=com
+member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+
diff --git a/tests/scripts/test044-dynlist b/tests/scripts/test044-dynlist
index 5ec785021b20e57fb6a324b88e495a53729a5606..e0bb527409e2f8923625cae15621a32725f9fd3b 100755
--- a/tests/scripts/test044-dynlist
+++ b/tests/scripts/test044-dynlist
@@ -316,7 +316,7 @@ if test $RC != 0 ; then
 	exit $RC
 fi
 
-CMPDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,$BASEDN"
+CMPDN="$BJORNSDN"
 echo "Testing list compare..."
 echo "# Testing list compare..." >> $SEARCHOUT
 $LDAPCOMPARE -h $LOCALHOST -p $PORT1 \
@@ -451,6 +451,42 @@ if test $RC != 0 ; then
 	exit $RC
 fi
 
+echo "Testing dgAuthz..."
+
+CMPDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,$BASEDN"
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+	> $TESTOUT 2>&1 << EOMODS
+dn: cn=Dynamic List of Members,$LISTDN
+changetype: modify
+add: dgAuthz
+dgAuthz: dn:$BABSDN
+EOMODS
+
+echo "Testing list search with dgIdentity and dgAuthz anonymously..."
+echo "# Testing list search with dgIdentity and dgAuthz anonymously..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$LISTDN" -h $LOCALHOST -p $PORT1 \
+	'(cn=Dynamic List of Members)' '*' \
+	>> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+	echo "ldapsearch failed ($RC)!"
+	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+	exit $RC
+fi
+
+echo "Testing list search with dgIdentity and dgAuthz as the authorized identity..."
+echo "# Testing list search with dgIdentity and dgAuthz as the authorized identity..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$LISTDN" -h $LOCALHOST -p $PORT1 \
+	-D "$BABSDN" -w bjensen \
+	'(cn=Dynamic List of Members)' '*' \
+	>> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+	echo "ldapsearch failed ($RC)!"
+	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+	exit $RC
+fi
+
 test $KILLSERVERS != no && kill -HUP $KILLPIDS
 
 LDIF=$DYNLISTOUT