diff --git a/doc/man/man5/slapd-sock.5 b/doc/man/man5/slapd-sock.5
index 29a4021101fb0b932b5a526670291c77c0addbc6..dbe955f947fb55ca9afe51a1e038ebce471a72a6 100644
--- a/doc/man/man5/slapd-sock.5
+++ b/doc/man/man5/slapd-sock.5
@@ -59,9 +59,9 @@ sends just the results of an operation. "search" sends all entries that
 the database returned for a search request. The default is empty
 (no responses are sent).
 .TP
-.B socksuffix	<DN suffix>
-Specify subtrees for which the overlay will act. Only operations on
-DNs matching the specified suffix(es) will be processed. The default
+.B sockdnpat	<regexp>
+Specify DN patterns for which the overlay will act. Only operations on
+DNs matching the specified regular expression will be processed. The default
 is empty (all DNs are processed).
 
 .SH PROTOCOL
diff --git a/servers/slapd/back-sock/back-sock.h b/servers/slapd/back-sock/back-sock.h
index 183a4661809f763fd4d2900a54ac768463cf8824..444fbf521bea36f873cfbff06d0117c8db89650a 100644
--- a/servers/slapd/back-sock/back-sock.h
+++ b/servers/slapd/back-sock/back-sock.h
@@ -30,8 +30,8 @@ struct sockinfo {
 	slap_mask_t	si_extensions;
 	slap_mask_t	si_ops;		/* overlay: operations to act on */
 	slap_mask_t	si_resps;	/* overlay: responses to forward */
-	BerVarray	si_suffix;	/* overlay: DN suffixes to match */
-	BerVarray	si_nsuffix;	/* overlay: DN suffixes to match */
+	regex_t	si_dnpat;		/* overlay: DN pattern to match */
+	struct berval 	si_dnpatstr;
 };
 
 #define	SOCK_EXT_BINDDN	1
diff --git a/servers/slapd/back-sock/config.c b/servers/slapd/back-sock/config.c
index 00fb06b072f61c10f6a98f29a0fbc9056eb57e8b..2c0f5d016175b44d57b8b21eca2bf94f0878ea8f 100644
--- a/servers/slapd/back-sock/config.c
+++ b/servers/slapd/back-sock/config.c
@@ -37,7 +37,7 @@ enum {
 	BS_EXT = 1,
 	BS_OPS,
 	BS_RESP,
-	BS_SUFFIX
+	BS_DNPAT
 };
 
 /* The number of overlay-only config attrs */
@@ -54,11 +54,11 @@ static ConfigTable bscfg[] = {
 			"DESC 'Response types to forward' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString )", NULL, NULL },
-	{ "socksuffix", "DN", 2, 0, 0, ARG_DN|ARG_QUOTE|ARG_MAGIC|BS_SUFFIX,
-		bs_cf_gen, "( OLcfgDbAt:7.5 NAME 'olcOvSocketSuffix' "
-			"DESC 'DN suffixes to match' "
-			"EQUALITY distinguishedNameMatch "
-			"SYNTAX OMsDN )", NULL, NULL },
+	{ "sockdnpat", "regexp", 2, 2, 0, ARG_MAGIC|BS_DNPAT,
+		bs_cf_gen, "( OLcfgDbAt:7.5 NAME 'olcOvSocketDNpat' "
+			"DESC 'DN pattern to match' "
+			"EQUALITY caseIgnoreMatch "
+			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
 
 	{ "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
 		(void *)offsetof(struct sockinfo, si_sockpath),
@@ -93,7 +93,7 @@ static ConfigOCs osocs[] = {
 		"MUST olcDbSocketPath "
 		"MAY ( olcDbSocketExtensions $ "
 			" olcOvSocketOps $ olcOvSocketResps $ "
-			" olcOvSocketSuffix ) )",
+			" olcOvSocketDNpat ) )",
 			Cft_Overlay, bscfg },
 	{ NULL, 0, NULL }
 };
@@ -157,9 +157,8 @@ bs_cf_gen( ConfigArgs *c )
 			return mask_to_verbs( ov_ops, si->si_ops, &c->rvalue_vals );
 		case BS_RESP:
 			return mask_to_verbs( ov_resps, si->si_resps, &c->rvalue_vals );
-		case BS_SUFFIX:
-			value_add( &c->rvalue_vals, si->si_suffix );
-			value_add( &c->rvalue_nvals, si->si_nsuffix );
+		case BS_DNPAT:
+			value_add_one( &c->rvalue_vals, &si->si_dnpatstr );
 			return 0;
 		}
 	} else if ( c->op == LDAP_MOD_DELETE ) {
@@ -197,22 +196,10 @@ bs_cf_gen( ConfigArgs *c )
 					si->si_resps ^= dels;
 			}
 			return rc;
-		case BS_SUFFIX:
-			if ( c->valx < 0 ) {
-				ber_bvarray_free( si->si_suffix );
-				ber_bvarray_free( si->si_nsuffix );
-				si->si_suffix = NULL;
-				si->si_nsuffix = NULL;
-			} else {
-				int i = c->valx;
-				ch_free( si->si_suffix[i].bv_val );
-				ch_free( si->si_nsuffix[i].bv_val );
-				do {
-					si->si_suffix[i] = si->si_suffix[i+1];
-					si->si_nsuffix[i] = si->si_nsuffix[i+1];
-					i++;
-				} while ( !BER_BVISNULL( &si->si_suffix[i] ));
-			}
+		case BS_DNPAT:
+			regfree( &si->si_dnpat );
+			ch_free( si->si_dnpatstr.bv_val );
+			BER_BVZERO( &si->si_dnpatstr );
 			return 0;
 		}
 
@@ -224,10 +211,13 @@ bs_cf_gen( ConfigArgs *c )
 			return verbs_to_mask( c->argc, c->argv, ov_ops, &si->si_ops );
 		case BS_RESP:
 			return verbs_to_mask( c->argc, c->argv, ov_resps, &si->si_resps );
-		case BS_SUFFIX:
-			ber_bvarray_add( &si->si_suffix, &c->value_dn );
-			ber_bvarray_add( &si->si_nsuffix, &c->value_ndn );
-			return 0;
+		case BS_DNPAT:
+			if ( !regcomp( &si->si_dnpat, c->argv[1], REG_EXTENDED|REG_ICASE|REG_NOSUB )) {
+				ber_str2bv( c->argv[1], 0, 1, &si->si_dnpatstr );
+				return 0;
+			} else {
+				return 1;
+			}
 		}
 	}
 	return 1;
@@ -300,17 +290,9 @@ static int sock_over_op(
 	if ( !(si->si_ops & sockopflags[which]))
 		return SLAP_CB_CONTINUE;
 
-	if ( si->si_nsuffix ) {
-		int i, ok = 0;
-		for ( i=0; !BER_BVISNULL( &si->si_nsuffix[i] ); i++ ) {
-			if ( dnIsSuffix( &op->o_req_ndn, &si->si_nsuffix[i] )) {
-				ok = 1;
-				break;
-			}
-		}
-		if ( !ok )
-			return SLAP_CB_CONTINUE;
-	}
+	if ( !BER_BVISEMPTY( &si->si_dnpatstr ) &&
+		regexec( &si->si_dnpat, op->o_req_ndn.bv_val, 0, NULL, 0 ))
+		return SLAP_CB_CONTINUE;
 
 	op->o_bd->be_private = si;
 	sc = op->o_callback;