add matchedDN; fix and clarify behavior when searching in-directory entries

This commit is contained in:
Pierangelo Masarati 2005-11-06 23:26:42 +00:00
parent 4f63434511
commit fd1b1a53f2
3 changed files with 85 additions and 10 deletions

View file

@ -21,8 +21,8 @@ The error responses are generated according to different strategies.
In the first case, all operations targeted at a specific configurable In the first case, all operations targeted at a specific configurable
subtree cause the object related to the request DN to be looked up subtree cause the object related to the request DN to be looked up
and checked for return code data: a response code, plus an optional and checked for return code data: a response code, plus an optional
textual message, an optional configurable delay, and, when the response code textual message, an optional configurable delay, an optional matched DN
is referral, a (list of) referral(s). field, and, when the response code is "referral", a (list of) referral(s).
.LP .LP
Well-known response codes from standard track documents are provided Well-known response codes from standard track documents are provided
in \fBretcode.conf\fP, which can be included after instantiating in \fBretcode.conf\fP, which can be included after instantiating
@ -57,13 +57,15 @@ If not defined, the suffix of the database is used.
.HP .HP
.hy 0 .hy 0
.B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>] .B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>]
.B [ref=<referral>] [sleeptime=<sec>] .B [ref=<referral>] [sleeptime=<sec>] [matched=<DN>]
.RS .RS
A dynamically generated entry, located below \fBretcode\-parent\fP. A dynamically generated entry, located below \fBretcode\-parent\fP.
The \fB<errCode>\fP is the number of the response code; The \fB<errCode>\fP is the number of the response code;
it can be in any format supported by strtol. it can be in any format supported by strtol.
The optional \fB<oplist>\fP is a list of operations that cause The optional \fB<oplist>\fP is a list of operations that cause
response code generation; if absent, all operations are affected. response code generation; if absent, all operations are affected.
The \fBmatched\fP field is the matched DN that is returned
along with the error.
The \fBref\fP field is only allowed for the \fBreferral\fP The \fBref\fP field is only allowed for the \fBreferral\fP
response code. response code.
.RE .RE
@ -130,13 +132,24 @@ The sleep time before the response is actually returned to the client:
SINGLE-VALUE ) SINGLE-VALUE )
.RE .RE
.LP .LP
The matched DN returned to the client:
.RS 4
( 1.3.6.1.4.1.4203.666.11.4.1.5
NAME ( 'errMatchedDN' )
DESC 'Value to be returned as matched DN'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
SINGLE-VALUE )
.RE
.LP
The abstract class that triggers the overlay: The abstract class that triggers the overlay:
.RS 4 .RS 4
( 1.3.6.1.4.1.4203.666.11.4.3.0 ( 1.3.6.1.4.1.4203.666.11.4.3.0
NAME ( 'errAbsObject' ) NAME ( 'errAbsObject' )
SUP top ABSTRACT SUP top ABSTRACT
MUST ( errCode ) MUST ( errCode )
MAY ( cn $ description $ errOp $ errText $ errSleepTime ) ) MAY ( cn $ description $ errOp $ errText $ errSleepTime
$ errMatchedDN ) )
.RE .RE
.LP .LP
The standalone structural objectclass for specifically created data: The standalone structural objectclass for specifically created data:

View file

@ -39,6 +39,7 @@ static AttributeDescription *ad_errCode;
static AttributeDescription *ad_errText; static AttributeDescription *ad_errText;
static AttributeDescription *ad_errOp; static AttributeDescription *ad_errOp;
static AttributeDescription *ad_errSleepTime; static AttributeDescription *ad_errSleepTime;
static AttributeDescription *ad_errMatchedDN;
static ObjectClass *oc_errAbsObject; static ObjectClass *oc_errAbsObject;
static ObjectClass *oc_errObject; static ObjectClass *oc_errObject;
static ObjectClass *oc_errAuxObject; static ObjectClass *oc_errAuxObject;
@ -63,6 +64,7 @@ typedef struct retcode_item_t {
struct berval rdi_dn; struct berval rdi_dn;
struct berval rdi_ndn; struct berval rdi_ndn;
struct berval rdi_text; struct berval rdi_text;
struct berval rdi_matched;
int rdi_err; int rdi_err;
BerVarray rdi_ref; BerVarray rdi_ref;
int rdi_sleeptime; int rdi_sleeptime;
@ -188,7 +190,9 @@ retcode_cb_response( Operation *op, SlapReply *rs )
} }
if ( rs->sr_err == LDAP_SUCCESS ) { if ( rs->sr_err == LDAP_SUCCESS ) {
rdc->rdc_flags = SLAP_CB_CONTINUE; if ( !op->o_abandon ) {
rdc->rdc_flags = SLAP_CB_CONTINUE;
}
return 0; return 0;
} }
@ -264,16 +268,27 @@ retcode_op_func( Operation *op, SlapReply *rs )
return retcode_op_add( op, rs ); return retcode_op_add( op, rs );
case LDAP_REQ_BIND: case LDAP_REQ_BIND:
/* skip if rootdn */
if ( be_isroot_pw( op ) ) { if ( be_isroot_pw( op ) ) {
return SLAP_CB_CONTINUE; return SLAP_CB_CONTINUE;
} }
/* fallthru */ return retcode_op_internal( op, rs );
case LDAP_REQ_SEARCH:
if ( op->ors_scope == LDAP_SCOPE_BASE ) {
rs->sr_err = retcode_op_internal( op, rs );
if ( rs->sr_err == SLAP_CB_CONTINUE ) {
rs->sr_err = LDAP_SUCCESS;
}
send_ldap_result( op, rs );
return rs->sr_err;
}
break;
case LDAP_REQ_MODIFY: case LDAP_REQ_MODIFY:
case LDAP_REQ_DELETE: case LDAP_REQ_DELETE:
case LDAP_REQ_MODRDN: case LDAP_REQ_MODRDN:
case LDAP_REQ_COMPARE: case LDAP_REQ_COMPARE:
case LDAP_REQ_SEARCH:
return retcode_op_internal( op, rs ); return retcode_op_internal( op, rs );
} }
} }
@ -362,6 +377,7 @@ retcode_op_func( Operation *op, SlapReply *rs )
} else { } else {
rs->sr_err = rdi->rdi_err; rs->sr_err = rdi->rdi_err;
rs->sr_text = rdi->rdi_text.bv_val; rs->sr_text = rdi->rdi_text.bv_val;
rs->sr_matched = rdi->rdi_matched.bv_val;
/* FIXME: we only honor the rdi_ref field in case rdi_err /* FIXME: we only honor the rdi_ref field in case rdi_err
* is LDAP_REFERRAL otherwise send_ldap_result() bails out */ * is LDAP_REFERRAL otherwise send_ldap_result() bails out */
@ -520,6 +536,12 @@ retcode_entry_response( Operation *op, SlapReply *rs, Entry *e )
rs->sr_text = a->a_vals[ 0 ].bv_val; rs->sr_text = a->a_vals[ 0 ].bv_val;
} }
/* matched DN */
a = attr_find( e->e_attrs, ad_errMatchedDN );
if ( a != NULL ) {
rs->sr_matched = a->a_vals[ 0 ].bv_val;
}
db.bd_info = on->on_info->oi_orig; db.bd_info = on->on_info->oi_orig;
op->o_bd = &db; op->o_bd = &db;
op->o_callback = NULL; op->o_callback = NULL;
@ -544,6 +566,7 @@ retcode_entry_response( Operation *op, SlapReply *rs, Entry *e )
} }
rs->sr_text = NULL; rs->sr_text = NULL;
rs->sr_matched = NULL;
op->o_callback = o_callback; op->o_callback = o_callback;
} }
@ -711,13 +734,15 @@ retcode_db_config(
} else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) { } else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_COMPARE; rdi.rdi_mask |= SN_DG_OP_COMPARE;
} else if ( strcasecmp( ops[ j ], "add" ) == 0 ) { } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_DELETE; rdi.rdi_mask |= SN_DG_OP_DELETE;
} else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) { } else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_MODIFY; rdi.rdi_mask |= SN_DG_OP_MODIFY;
} else if ( strcasecmp( ops[ j ], "rename" ) == 0 ) { } else if ( strcasecmp( ops[ j ], "rename" ) == 0
|| strcasecmp( ops[ j ], "modrdn" ) == 0 )
{
rdi.rdi_mask |= SN_DG_OP_RENAME; rdi.rdi_mask |= SN_DG_OP_RENAME;
} else if ( strcasecmp( ops[ j ], "search" ) == 0 ) { } else if ( strcasecmp( ops[ j ], "search" ) == 0 ) {
@ -757,6 +782,24 @@ retcode_db_config(
} }
ber_str2bv( &argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text ); ber_str2bv( &argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text );
} else if ( strncasecmp( argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 )
{
struct berval dn;
if ( !BER_BVISNULL( &rdi.rdi_matched ) ) {
fprintf( stderr, "%s: line %d: retcode: "
"\"matched\" already provided.\n",
fname, lineno );
return 1;
}
ber_str2bv( &argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn );
if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) {
fprintf( stderr, "%s: line %d: retcode: "
"unable to prettify matched DN \"%s\".\n",
fname, lineno, &argv[ i ][ STRLENOF( "matched=" ) ] );
return 1;
}
} else if ( strncasecmp( argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 ) } else if ( strncasecmp( argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 )
{ {
char **refs; char **refs;
@ -898,6 +941,13 @@ retcode_db_open( BackendDB *be )
attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL ); attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL );
} }
/* matched */
if ( !BER_BVISNULL( &rdi->rdi_matched ) ) {
val[ 0 ] = rdi->rdi_matched;
attr_merge_normalize_one( &rdi->rdi_e, ad_errMatchedDN, &val[ 0 ], NULL );
}
/* sleep time */ /* sleep time */
if ( rdi->rdi_sleeptime > 0 ) { if ( rdi->rdi_sleeptime > 0 ) {
snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime ); snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime );
@ -968,6 +1018,10 @@ retcode_db_destroy( BackendDB *be )
ber_memfree( rdi->rdi_text.bv_val ); ber_memfree( rdi->rdi_text.bv_val );
} }
if ( !BER_BVISNULL( &rdi->rdi_matched ) ) {
ber_memfree( rdi->rdi_matched.bv_val );
}
BER_BVZERO( &rdi->rdi_e.e_name ); BER_BVZERO( &rdi->rdi_e.e_name );
BER_BVZERO( &rdi->rdi_e.e_nname ); BER_BVZERO( &rdi->rdi_e.e_nname );
@ -1028,6 +1082,13 @@ retcode_init( void )
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
"SINGLE-VALUE )", "SINGLE-VALUE )",
&ad_errSleepTime }, &ad_errSleepTime },
{ "errMatchedDN", "( 1.3.6.1.4.1.4203.666.11.4.1.5 "
"NAME ( 'errMatchedDN' ) "
"DESC 'Value to be returned as matched DN' "
"EQUALITY distinguishedNameMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
"SINGLE-VALUE )",
&ad_errMatchedDN },
{ NULL } { NULL }
}; };
@ -1046,6 +1107,7 @@ retcode_init( void )
"$ errOp " "$ errOp "
"$ errText " "$ errText "
"$ errSleepTime " "$ errSleepTime "
"$ errMatchedDN "
") )", ") )",
&oc_errAbsObject }, &oc_errAbsObject },
{ "errObject", "( 1.3.6.1.4.1.4203.666.11.4.3.1 " { "errObject", "( 1.3.6.1.4.1.4203.666.11.4.3.1 "

View file

@ -29,7 +29,7 @@ retcode-item "cn=authMethodNotSupported" 0x07
retcode-item "cn=strongAuthNotSupported" 0x07 text="same as authMethodNotSupported" retcode-item "cn=strongAuthNotSupported" 0x07 text="same as authMethodNotSupported"
retcode-item "cn=strongAuthRequired" 0x08 retcode-item "cn=strongAuthRequired" 0x08
retcode-item "cn=strongerAuthRequired" 0x08 text="same as strongAuthRequired" retcode-item "cn=strongerAuthRequired" 0x08 text="same as strongAuthRequired"
#retcode-item "cn=partialResults" 0x09 "LDAPv2+ (not LDAPv3)" #retcode-item "cn=partialResults" 0x09 text="LDAPv2+ (not LDAPv3)"
retcode-item "cn=referral" 0x0a text="LDAPv3" ref="ldap://:9019" retcode-item "cn=referral" 0x0a text="LDAPv3" ref="ldap://:9019"
retcode-item "cn=adminLimitExceeded" 0x0b text="LDAPv3" retcode-item "cn=adminLimitExceeded" 0x0b text="LDAPv3"