mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
add "searchFilterAttrDN" rewrite context, and allow filterstring rewrite
This commit is contained in:
parent
1d1cd21814
commit
65b49dd312
@ -513,20 +513,22 @@ client -> server:
|
||||
.LP
|
||||
.RS
|
||||
.nf
|
||||
(default) if defined and no specific context
|
||||
is available
|
||||
bindDN bind
|
||||
searchBase search
|
||||
searchFilter search
|
||||
compareDN compare
|
||||
compareAttrDN compare AVA
|
||||
addDN add
|
||||
addAttrDN add AVA
|
||||
modifyDN modify
|
||||
modifyAttrDN modify AVA
|
||||
modrDN modrdn
|
||||
newSuperiorDN modrdn
|
||||
deleteDN delete
|
||||
(default) if defined and no specific context
|
||||
is available
|
||||
bindDN bind
|
||||
searchBase search
|
||||
searchFilter search
|
||||
searchFilterAttrDN search
|
||||
compareDN compare
|
||||
compareAttrDN compare AVA
|
||||
addDN add
|
||||
addAttrDN add AVA
|
||||
modifyDN modify
|
||||
modifyAttrDN modify AVA
|
||||
modrDN modrdn
|
||||
newSuperiorDN modrdn
|
||||
deleteDN delete
|
||||
exopPasswdDN passwd exop DN if proxy
|
||||
.fi
|
||||
.RE
|
||||
.LP
|
||||
@ -534,11 +536,11 @@ server -> client:
|
||||
.LP
|
||||
.RS
|
||||
.nf
|
||||
searchResult search (only if defined; no default;
|
||||
acts on DN and DN-syntax attributes
|
||||
of search results)
|
||||
searchAttrDN search AVA
|
||||
matchedDN all ops (only if applicable)
|
||||
searchResult search (only if defined; no default;
|
||||
acts on DN and DN-syntax attributes
|
||||
of search results)
|
||||
searchAttrDN search AVA
|
||||
matchedDN all ops (only if applicable)
|
||||
.fi
|
||||
.RE
|
||||
.LP
|
||||
@ -627,10 +629,10 @@ rewriteRule ".*" "%{>addBlanks(%0)}" ":"
|
||||
.\"
|
||||
.\" # Finally, in a bind, if one uses a `uid=username' DN,
|
||||
.\" # it is rewritten in `cn=name surname' if possible.
|
||||
.\" rewriteContext bindDn
|
||||
.\" rewriteContext bindDN
|
||||
.\" rewriteRule ".*" "%{>addBlanks(%{>uid2Gecos(%0)})}" ":"
|
||||
.\"
|
||||
# Rewrite the search base according to `default' rules.
|
||||
# Rewrite the search base according to `default' rules.
|
||||
rewriteContext searchBase alias default
|
||||
|
||||
# Search results with OpenLDAP DN are rewritten back with
|
||||
@ -652,7 +654,7 @@ rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
|
||||
# to real naming contexts, we also need to rewrite
|
||||
# regular DNs, because the definition of a bindDn
|
||||
# rewrite context overrides the default definition.
|
||||
rewriteContext bindDn
|
||||
rewriteContext bindDN
|
||||
rewriteRule "^mail=[^,]+@[^,]+$" "%{attr2dn(%0)}" ":@I"
|
||||
|
||||
# This is a rather sophisticated example. It massages a
|
||||
@ -661,7 +663,7 @@ rewriteRule "^mail=[^,]+@[^,]+$" "%{attr2dn(%0)}" ":@I"
|
||||
# track of the bind DN of the incoming request, which is
|
||||
# stored in a variable called `binddn' with session scope,
|
||||
# and left in place to allow regular binding:
|
||||
rewriteContext bindDn
|
||||
rewriteContext bindDN
|
||||
rewriteRule ".+" "%{&&binddn(%0)}%0" ":"
|
||||
|
||||
# A search filter containing `uid=' is rewritten only
|
||||
|
@ -69,7 +69,7 @@ ldap_back_add(
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "addDn";
|
||||
dc.ctx = "addDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
@ -87,7 +87,7 @@ ldap_back_add(
|
||||
attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.ctx = "addDnAttr";
|
||||
dc.ctx = "addAttrDN";
|
||||
#endif
|
||||
|
||||
isupdate = be_isupdate( op->o_bd, &op->o_ndn );
|
||||
|
@ -62,7 +62,7 @@ ldap_back_bind(
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "bindDn";
|
||||
dc.ctx = "bindDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
@ -303,7 +303,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "bindDn";
|
||||
dc.ctx = "bindDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
@ -532,7 +532,7 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "matchedDn";
|
||||
dc.ctx = "matchedDN";
|
||||
#else
|
||||
dc.tofrom = 0;
|
||||
dc.normalized = 0;
|
||||
|
@ -60,7 +60,7 @@ ldap_back_compare(
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "compareDn";
|
||||
dc.ctx = "compareDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
|
@ -586,96 +586,9 @@ suffix_massage_config(
|
||||
ch_free( rargv[ 1 ] );
|
||||
ch_free( rargv[ 2 ] );
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* FIXME: this is no longer required since now we map filters
|
||||
* based on the parsed filter structure, so we can deal directly
|
||||
* with attribute types and values. The rewriteContext
|
||||
* "searchFilter" now refers to the value of attrbutes
|
||||
* with DN syntax.
|
||||
*/
|
||||
|
||||
/*
|
||||
* the filter should be rewritten as
|
||||
*
|
||||
* rewriteRule
|
||||
* "(.*)member=([^)]+),o=Foo Bar,[ ]?c=US(.*)"
|
||||
* "%1member=%2,dc=example,dc=com%3"
|
||||
*
|
||||
* where "o=Foo Bar, c=US" is the virtual naming context,
|
||||
* and "dc=example, dc=com" is the real naming context
|
||||
*/
|
||||
rargv[ 0 ] = "rewriteContext";
|
||||
rargv[ 1 ] = "searchFilter";
|
||||
rargv[ 2 ] = NULL;
|
||||
rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
|
||||
|
||||
#if 1 /* rewrite filters */
|
||||
{
|
||||
/*
|
||||
* Note: this is far more optimistic than desirable:
|
||||
* for any AVA value ending with the virtual naming
|
||||
* context the terminal part will be replaced by the
|
||||
* real naming context; a better solution would be to
|
||||
* walk the filter looking for DN-valued attributes,
|
||||
* and only rewrite those that require rewriting
|
||||
*/
|
||||
char vbuf_[BUFSIZ], *vbuf = vbuf_,
|
||||
rbuf_[BUFSIZ], *rbuf = rbuf_;
|
||||
int len;
|
||||
|
||||
len = snprintf( vbuf, sizeof( vbuf_ ),
|
||||
"(.*)%s\\)(.*)", nvnc->bv_val );
|
||||
if ( len == -1 ) {
|
||||
/*
|
||||
* traditional behavior: snprintf returns -1
|
||||
* if buffer is insufficient
|
||||
*/
|
||||
return -1;
|
||||
|
||||
} else if ( len >= (int)sizeof( vbuf_ ) ) {
|
||||
/*
|
||||
* C99: snprintf returns the required size
|
||||
*/
|
||||
vbuf = ch_malloc( len + 1 );
|
||||
len = snprintf( vbuf, len,
|
||||
"(.*)%s\\)(.*)", nvnc->bv_val );
|
||||
assert( len > 0 );
|
||||
}
|
||||
|
||||
len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2",
|
||||
nrnc->bv_val );
|
||||
if ( len == -1 ) {
|
||||
return -1;
|
||||
|
||||
} else if ( len >= (int)sizeof( rbuf_ ) ) {
|
||||
rbuf = ch_malloc( len + 1 );
|
||||
len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2",
|
||||
nrnc->bv_val );
|
||||
assert( len > 0 );
|
||||
}
|
||||
|
||||
rargv[ 0 ] = "rewriteRule";
|
||||
rargv[ 1 ] = vbuf;
|
||||
rargv[ 2 ] = rbuf;
|
||||
rargv[ 3 ] = ":";
|
||||
rargv[ 4 ] = NULL;
|
||||
rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
|
||||
|
||||
if ( vbuf != vbuf_ ) {
|
||||
ch_free( vbuf );
|
||||
}
|
||||
|
||||
if ( rbuf != rbuf_ ) {
|
||||
ch_free( rbuf );
|
||||
}
|
||||
}
|
||||
#endif /* rewrite filters */
|
||||
#endif
|
||||
|
||||
#if 0 /* "matched" is not normalized */
|
||||
rargv[ 0 ] = "rewriteContext";
|
||||
rargv[ 1 ] = "matchedDn";
|
||||
rargv[ 1 ] = "matchedDN";
|
||||
rargv[ 2 ] = "alias";
|
||||
rargv[ 3 ] = "searchResult";
|
||||
rargv[ 4 ] = NULL;
|
||||
|
@ -60,7 +60,7 @@ ldap_back_delete(
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "deleteDn";
|
||||
dc.ctx = "deleteDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
|
@ -117,12 +117,12 @@ ldap_back_exop_passwd(
|
||||
op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 );
|
||||
#endif
|
||||
|
||||
if (isproxy) {
|
||||
if ( isproxy ) {
|
||||
dc.rwmap = &li->rwmap;
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "modifyPwd";
|
||||
dc.ctx = "exopPasswdDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
|
@ -118,6 +118,21 @@ ldap_back_db_init(
|
||||
ch_free( li );
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
char *rargv[3];
|
||||
|
||||
/*
|
||||
* the filter rewrite as a string must be disabled
|
||||
* by default; it can be re-enabled by adding rules;
|
||||
* this creates an empty rewriteContext
|
||||
*/
|
||||
rargv[ 0 ] = "rewriteContext";
|
||||
rargv[ 1 ] = "searchFilter";
|
||||
rargv[ 2 ] = NULL;
|
||||
rewrite_parse( li->rwmap.rwm_rw, "<suffix massage>",
|
||||
1, 2, rargv );
|
||||
}
|
||||
#endif /* ENABLE_REWRITE */
|
||||
|
||||
ldap_pvt_thread_mutex_init( &li->conn_mutex );
|
||||
|
@ -180,7 +180,7 @@ map_attr_value(
|
||||
dncookie fdc = *dc;
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
fdc.ctx = "searchFilter";
|
||||
fdc.ctx = "searchFilterAttrDN";
|
||||
#endif
|
||||
|
||||
switch ( ldap_back_dn_massage( &fdc, value, &vtmp ) ) {
|
||||
@ -214,8 +214,8 @@ map_attr_value(
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_filter_map_rewrite(
|
||||
static int
|
||||
ldap_int_back_filter_map_rewrite(
|
||||
dncookie *dc,
|
||||
Filter *f,
|
||||
struct berval *fstr,
|
||||
@ -390,7 +390,7 @@ ldap_back_filter_map_rewrite(
|
||||
for ( p = f->f_list; p != NULL; p = p->f_next ) {
|
||||
len = fstr->bv_len;
|
||||
|
||||
rc = ldap_back_filter_map_rewrite( dc, p, &vtmp, remap );
|
||||
rc = ldap_int_back_filter_map_rewrite( dc, p, &vtmp, remap );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
@ -458,6 +458,73 @@ ldap_back_filter_map_rewrite(
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_filter_map_rewrite(
|
||||
dncookie *dc,
|
||||
Filter *f,
|
||||
struct berval *fstr,
|
||||
int remap )
|
||||
{
|
||||
int rc;
|
||||
dncookie fdc;
|
||||
struct berval ftmp;
|
||||
|
||||
rc = ldap_int_back_filter_map_rewrite( dc, f, fstr, remap );
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
fdc = *dc;
|
||||
ftmp = *fstr;
|
||||
|
||||
fdc.ctx = "searchFilter";
|
||||
|
||||
switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx,
|
||||
( ftmp.bv_len ? ftmp.bv_val : "" ),
|
||||
fdc.conn, &fstr->bv_val )) {
|
||||
case REWRITE_REGEXEC_OK:
|
||||
if ( fstr->bv_val != NULL ) {
|
||||
fstr->bv_len = strlen( fstr->bv_val );
|
||||
free( ftmp.bv_val );
|
||||
} else {
|
||||
*fstr = ftmp;
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_LDAP, DETAIL1,
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n",
|
||||
dc->ctx, ftmp.bv_val, fstr->bv_val );
|
||||
#else /* !NEW_LOGGING */
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n",
|
||||
dc->ctx, ftmp.bv_val, fstr->bv_val );
|
||||
#endif /* !NEW_LOGGING */
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
|
||||
case REWRITE_REGEXEC_UNWILLING:
|
||||
if ( fdc.rs ) {
|
||||
fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
fdc.rs->sr_text = "Operation not allowed";
|
||||
}
|
||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||
break;
|
||||
|
||||
case REWRITE_REGEXEC_ERR:
|
||||
if ( fdc.rs ) {
|
||||
fdc.rs->sr_err = LDAP_OTHER;
|
||||
fdc.rs->sr_text = "Rewrite error";
|
||||
}
|
||||
rc = LDAP_OTHER;
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_REWRITE */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* I don't like this much, but we need two different
|
||||
* functions because different heap managers may be
|
||||
|
@ -63,7 +63,7 @@ ldap_back_modify(
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "modifyDn";
|
||||
dc.ctx = "modifyDN";
|
||||
#else
|
||||
dc.tofrom = 1;
|
||||
dc.normalized = 0;
|
||||
|
@ -68,7 +68,7 @@ ldap_back_modrdn(
|
||||
* Rewrite the new superior, if defined and required
|
||||
*/
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.ctx = "newSuperiorDn";
|
||||
dc.ctx = "newSuperiorDN";
|
||||
#endif
|
||||
if ( ldap_back_dn_massage( &dc, op->orr_newSup,
|
||||
&mnewSuperior ) ) {
|
||||
@ -81,7 +81,7 @@ ldap_back_modrdn(
|
||||
* Rewrite the modrdn dn, if required
|
||||
*/
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.ctx = "modrDn";
|
||||
dc.ctx = "modrDN";
|
||||
#endif
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_ndn, &mdn ) ) {
|
||||
send_ldap_result( op, rs );
|
||||
|
@ -275,7 +275,7 @@ fail:;
|
||||
struct berval mdn;
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
dc.ctx = "matchedDn";
|
||||
dc.ctx = "matchedDN";
|
||||
#else
|
||||
dc.tofrom = 0;
|
||||
dc.normalized = 0;
|
||||
|
@ -42,8 +42,11 @@ ldap_back_dn_massage(
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (rewrite_session( dc->rwmap->rwm_rw, dc->ctx, (dn->bv_len ? dn->bv_val : ""), dc->conn,
|
||||
&res->bv_val )) {
|
||||
rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
|
||||
( dn->bv_len ? dn->bv_val : "" ), dc->conn,
|
||||
&res->bv_val );
|
||||
|
||||
switch ( rc ) {
|
||||
case REWRITE_REGEXEC_OK:
|
||||
if ( res->bv_val != NULL ) {
|
||||
res->bv_len = strlen( res->bv_val );
|
||||
@ -52,10 +55,12 @@ ldap_back_dn_massage(
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_LDAP, DETAIL1,
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n", dc->ctx, dn->bv_val, res->bv_val );
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n",
|
||||
dc->ctx, dn->bv_val, res->bv_val );
|
||||
#else /* !NEW_LOGGING */
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n", dc->ctx, dn->bv_val, res->bv_val );
|
||||
"[rw] %s: \"%s\" -> \"%s\"\n",
|
||||
dc->ctx, dn->bv_val, res->bv_val );
|
||||
#endif /* !NEW_LOGGING */
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
|
@ -73,7 +73,7 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
dc.rwmap = &li->targets[ candidate ]->rwmap;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "addDn";
|
||||
dc.ctx = "addDN";
|
||||
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
send_ldap_result( op, rs );
|
||||
|
@ -203,7 +203,7 @@ meta_back_do_single_bind(
|
||||
dc.rwmap = &li->targets[ candidate ]->rwmap;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "bindDn";
|
||||
dc.ctx = "bindDN";
|
||||
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
send_ldap_result( op, rs );
|
||||
|
@ -67,7 +67,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
*/
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "compareDn";
|
||||
dc.ctx = "compareDN";
|
||||
|
||||
for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
|
||||
struct berval mdn = { 0, NULL };
|
||||
@ -254,7 +254,7 @@ finish:;
|
||||
matched.bv_val = match;
|
||||
matched.bv_len = strlen( match );
|
||||
|
||||
dc.ctx = "matchedDn";
|
||||
dc.ctx = "matchedDN";
|
||||
ldap_back_dn_massage( &dc, &matched, &mmatch );
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ init_one_conn(
|
||||
dc.rwmap = <->rwmap;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "bindDn";
|
||||
dc.ctx = "bindDN";
|
||||
|
||||
/*
|
||||
* Rewrite the bind dn if needed
|
||||
|
@ -46,7 +46,7 @@ $SRCDIR/servers/slapd/slapd -f $CONF -h "ldap://:$PORT/" -d $DEBUG
|
||||
echo "Waiting 2 secs for everything to shut down ..."
|
||||
sleep 2
|
||||
|
||||
#exit
|
||||
exit
|
||||
|
||||
rm -rf $METADBDIR
|
||||
rm -f schema ucdata $CONF $LDAPCONF
|
||||
|
@ -60,7 +60,7 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
||||
dc.rwmap = &li->targets[ candidate ]->rwmap;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "deleteDn";
|
||||
dc.ctx = "deleteDN";
|
||||
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
send_ldap_result( op, rs );
|
||||
|
@ -65,7 +65,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
dc.rwmap = &li->targets[ candidate ]->rwmap;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "modifyDn";
|
||||
dc.ctx = "modifyDN";
|
||||
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
rc = -1;
|
||||
|
@ -495,7 +495,7 @@ new_candidate:;
|
||||
*/
|
||||
if ( candidate_match == initial_candidates
|
||||
&& match.bv_val != NULL && *match.bv_val ) {
|
||||
dc.ctx = "matchedDn";
|
||||
dc.ctx = "matchedDN";
|
||||
dc.rwmap = &li->targets[ last ]->rwmap;
|
||||
|
||||
if ( ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
|
||||
|
Loading…
Reference in New Issue
Block a user