mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
allow to customize the error code in case of constraint violation
This commit is contained in:
parent
0d9e140e95
commit
18b2885f69
@ -36,59 +36,69 @@ The following
|
|||||||
configuration options are defined for the memberofoverlay.
|
configuration options are defined for the memberofoverlay.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-group-oc <group-oc>
|
.BI memberof-group-oc \ <group-oc>
|
||||||
The value
|
The value
|
||||||
.B <group-oc>
|
.I <group-oc>
|
||||||
is the name of the objectClass that triggers the reverse group membership
|
is the name of the objectClass that triggers the reverse group membership
|
||||||
update.
|
update.
|
||||||
It defaults to \fIgroupOfNames\fP.
|
It defaults to \fIgroupOfNames\fP.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-member-ad <member-ad>
|
.BI memberof-member-ad \ <member-ad>
|
||||||
The value
|
The value
|
||||||
.B <member-ad>
|
.I <member-ad>
|
||||||
is the name of the attribute that contains the names of the members
|
is the name of the attribute that contains the names of the members
|
||||||
in the group objects; it must be DN-valued.
|
in the group objects; it must be DN-valued.
|
||||||
It defaults to \fImember\fP.
|
It defaults to \fImember\fP.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-memberof-ad <memberof-ad>
|
.BI memberof-memberof-ad \ <memberof-ad>
|
||||||
The value
|
The value
|
||||||
.B <memberof-ad>
|
.I <memberof-ad>
|
||||||
is the name of the attribute that contains the names of the groups
|
is the name of the attribute that contains the names of the groups
|
||||||
an entry is member of; it must be DN-valued. Its contents are
|
an entry is member of; it must be DN-valued. Its contents are
|
||||||
automatically updated by the overlay.
|
automatically updated by the overlay.
|
||||||
It defaults to \fImemberOf\fP.
|
It defaults to \fImemberOf\fP.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-dn <dn>
|
.BI memberof-dn \ <dn>
|
||||||
The value
|
The value
|
||||||
.B <dn>
|
.I <dn>
|
||||||
contains the DN that is used as \fImodifiersName\fP for internal
|
contains the DN that is used as \fImodifiersName\fP for internal
|
||||||
modifications performed to update the reverse group membership.
|
modifications performed to update the reverse group membership.
|
||||||
It defaults to the \fIrootdn\fP of the underlying database.
|
It defaults to the \fIrootdn\fP of the underlying database.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-dangling {ignore, drop, error}
|
.BI "memberof-dangling {" ignore ", " drop ", " error "}"
|
||||||
This option determines the behavior of the overlay when, during
|
This option determines the behavior of the overlay when, during
|
||||||
a modification, it encounters dangling references.
|
a modification, it encounters dangling references.
|
||||||
The default is
|
The default is
|
||||||
.BR ignore ,
|
.IR ignore ,
|
||||||
which may leave dangling references.
|
which may leave dangling references.
|
||||||
Other options are
|
Other options are
|
||||||
.BR drop ,
|
.IR drop ,
|
||||||
which discards those modifications that would result in dangling
|
which discards those modifications that would result in dangling
|
||||||
references, and
|
references, and
|
||||||
.BR error ,
|
.IR error ,
|
||||||
which causes modifications that would result in dangling references
|
which causes modifications that would result in dangling references
|
||||||
to fail.
|
to fail.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B memberof-refint {true|FALSE}
|
.BI memberof-dangling-error \ <error-code>
|
||||||
|
If
|
||||||
|
.BR memberof-dangling
|
||||||
|
is set to
|
||||||
|
.IR error ,
|
||||||
|
this configuration parameter can be used to modify the response code
|
||||||
|
returned in case of violation. It defaults to "constraint violation",
|
||||||
|
but other implementations are known to return "no such object" instead.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "memberof-refint {" true "|" FALSE "}"
|
||||||
This option determines whether the overlay will try to preserve
|
This option determines whether the overlay will try to preserve
|
||||||
referential integrity or not.
|
referential integrity or not.
|
||||||
If set to
|
If set to
|
||||||
.BR TRUE ,
|
.IR TRUE ,
|
||||||
when an entry containing values of the "is member of" attribute is modified,
|
when an entry containing values of the "is member of" attribute is modified,
|
||||||
the corresponding groups are modified as well.
|
the corresponding groups are modified as well.
|
||||||
|
|
||||||
|
@ -1007,6 +1007,92 @@ enum_to_verb(slap_verbmasks *v, slap_mask_t m, struct berval *bv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static slap_verbmasks slap_ldap_response_code_[] = {
|
||||||
|
{ BER_BVC("success"), LDAP_SUCCESS },
|
||||||
|
|
||||||
|
{ BER_BVC("operationsError"), LDAP_OPERATIONS_ERROR },
|
||||||
|
{ BER_BVC("protocolError"), LDAP_PROTOCOL_ERROR },
|
||||||
|
{ BER_BVC("timelimitExceeded"), LDAP_TIMELIMIT_EXCEEDED },
|
||||||
|
{ BER_BVC("sizelimitExceeded"), LDAP_SIZELIMIT_EXCEEDED },
|
||||||
|
{ BER_BVC("compareFalse"), LDAP_COMPARE_FALSE },
|
||||||
|
{ BER_BVC("compareTrue"), LDAP_COMPARE_TRUE },
|
||||||
|
|
||||||
|
{ BER_BVC("authMethodNotSupported"), LDAP_AUTH_METHOD_NOT_SUPPORTED },
|
||||||
|
{ BER_BVC("strongAuthNotSupported"), LDAP_STRONG_AUTH_NOT_SUPPORTED },
|
||||||
|
{ BER_BVC("strongAuthRequired"), LDAP_STRONG_AUTH_REQUIRED },
|
||||||
|
{ BER_BVC("strongerAuthRequired"), LDAP_STRONGER_AUTH_REQUIRED },
|
||||||
|
#if 0 /* not LDAPv3 */
|
||||||
|
{ BER_BVC("partialResults"), LDAP_PARTIAL_RESULTS },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ BER_BVC("referral"), LDAP_REFERRAL },
|
||||||
|
{ BER_BVC("adminlimitExceeded"), LDAP_ADMINLIMIT_EXCEEDED },
|
||||||
|
{ BER_BVC("unavailableCriticalExtension"), LDAP_UNAVAILABLE_CRITICAL_EXTENSION },
|
||||||
|
{ BER_BVC("confidentialityRequired"), LDAP_CONFIDENTIALITY_REQUIRED },
|
||||||
|
{ BER_BVC("saslBindInProgress"), LDAP_SASL_BIND_IN_PROGRESS },
|
||||||
|
|
||||||
|
{ BER_BVC("noSuchAttribute"), LDAP_NO_SUCH_ATTRIBUTE },
|
||||||
|
{ BER_BVC("undefinedType"), LDAP_UNDEFINED_TYPE },
|
||||||
|
{ BER_BVC("inappropriateMatching"), LDAP_INAPPROPRIATE_MATCHING },
|
||||||
|
{ BER_BVC("constraintViolation"), LDAP_CONSTRAINT_VIOLATION },
|
||||||
|
{ BER_BVC("typeOrValueExists"), LDAP_TYPE_OR_VALUE_EXISTS },
|
||||||
|
{ BER_BVC("invalidSyntax"), LDAP_INVALID_SYNTAX },
|
||||||
|
|
||||||
|
{ BER_BVC("noSuchObject"), LDAP_NO_SUCH_OBJECT },
|
||||||
|
{ BER_BVC("aliasProblem"), LDAP_ALIAS_PROBLEM },
|
||||||
|
{ BER_BVC("invalidDnSyntax"), LDAP_INVALID_DN_SYNTAX },
|
||||||
|
#if 0 /* not LDAPv3 */
|
||||||
|
{ BER_BVC("isLeaf"), LDAP_IS_LEAF },
|
||||||
|
#endif
|
||||||
|
{ BER_BVC("aliasDerefProblem"), LDAP_ALIAS_DEREF_PROBLEM },
|
||||||
|
|
||||||
|
{ BER_BVC("proxyAuthzFailure"), LDAP_X_PROXY_AUTHZ_FAILURE },
|
||||||
|
{ BER_BVC("inappropriateAuth"), LDAP_INAPPROPRIATE_AUTH },
|
||||||
|
{ BER_BVC("invalidCredentials"), LDAP_INVALID_CREDENTIALS },
|
||||||
|
{ BER_BVC("insufficientAccess"), LDAP_INSUFFICIENT_ACCESS },
|
||||||
|
|
||||||
|
{ BER_BVC("busy"), LDAP_BUSY },
|
||||||
|
{ BER_BVC("unavailable"), LDAP_UNAVAILABLE },
|
||||||
|
{ BER_BVC("unwillingToPerform"), LDAP_UNWILLING_TO_PERFORM },
|
||||||
|
{ BER_BVC("loopDetect"), LDAP_LOOP_DETECT },
|
||||||
|
|
||||||
|
{ BER_BVC("namingViolation"), LDAP_NAMING_VIOLATION },
|
||||||
|
{ BER_BVC("objectClassViolation"), LDAP_OBJECT_CLASS_VIOLATION },
|
||||||
|
{ BER_BVC("notAllowedOnNonleaf"), LDAP_NOT_ALLOWED_ON_NONLEAF },
|
||||||
|
{ BER_BVC("notAllowedOnRdn"), LDAP_NOT_ALLOWED_ON_RDN },
|
||||||
|
{ BER_BVC("alreadyExists"), LDAP_ALREADY_EXISTS },
|
||||||
|
{ BER_BVC("noObjectClassMods"), LDAP_NO_OBJECT_CLASS_MODS },
|
||||||
|
{ BER_BVC("resultsTooLarge"), LDAP_RESULTS_TOO_LARGE },
|
||||||
|
{ BER_BVC("affectsMultipleDsas"), LDAP_AFFECTS_MULTIPLE_DSAS },
|
||||||
|
|
||||||
|
{ BER_BVC("other"), LDAP_OTHER },
|
||||||
|
|
||||||
|
/* extension-specific */
|
||||||
|
|
||||||
|
{ BER_BVC("cupResourcesExhausted"), LDAP_CUP_RESOURCES_EXHAUSTED },
|
||||||
|
{ BER_BVC("cupSecurityViolation"), LDAP_CUP_SECURITY_VIOLATION },
|
||||||
|
{ BER_BVC("cupInvalidData"), LDAP_CUP_INVALID_DATA },
|
||||||
|
{ BER_BVC("cupUnsupportedScheme"), LDAP_CUP_UNSUPPORTED_SCHEME },
|
||||||
|
{ BER_BVC("cupReloadRequired"), LDAP_CUP_RELOAD_REQUIRED },
|
||||||
|
|
||||||
|
{ BER_BVC("cancelled"), LDAP_CANCELLED },
|
||||||
|
{ BER_BVC("noSuchOperation"), LDAP_NO_SUCH_OPERATION },
|
||||||
|
{ BER_BVC("tooLate"), LDAP_TOO_LATE },
|
||||||
|
{ BER_BVC("cannotCancel"), LDAP_CANNOT_CANCEL },
|
||||||
|
|
||||||
|
{ BER_BVC("assertionFailed"), LDAP_ASSERTION_FAILED },
|
||||||
|
|
||||||
|
{ BER_BVC("proxiedAuthorizationDenied"), LDAP_PROXIED_AUTHORIZATION_DENIED },
|
||||||
|
|
||||||
|
{ BER_BVC("syncRefreshRequired"), LDAP_SYNC_REFRESH_REQUIRED },
|
||||||
|
|
||||||
|
{ BER_BVC("noOperation"), LDAP_X_NO_OPERATION },
|
||||||
|
|
||||||
|
{ BER_BVNULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
slap_verbmasks *slap_ldap_response_code = slap_ldap_response_code_;
|
||||||
|
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
static slap_verbmasks tlskey[] = {
|
static slap_verbmasks tlskey[] = {
|
||||||
{ BER_BVC("no"), SB_TLS_OFF },
|
{ BER_BVC("no"), SB_TLS_OFF },
|
||||||
|
@ -196,4 +196,6 @@ int config_shadow( ConfigArgs *c, int flag );
|
|||||||
|
|
||||||
#define SLAP_X_ORDERED_FMT "{%d}"
|
#define SLAP_X_ORDERED_FMT "{%d}"
|
||||||
|
|
||||||
|
extern slap_verbmasks *slap_ldap_response_code;
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
#endif /* CONFIG_H */
|
||||||
|
@ -155,6 +155,8 @@ typedef struct memberof_t {
|
|||||||
#define MEMBEROF_FREFINT 0x04U
|
#define MEMBEROF_FREFINT 0x04U
|
||||||
#define MEMBEROF_FREVERSE 0x08U
|
#define MEMBEROF_FREVERSE 0x08U
|
||||||
|
|
||||||
|
ber_int_t mo_dangling_err;
|
||||||
|
|
||||||
#define MEMBEROF_CHK(mo,f) \
|
#define MEMBEROF_CHK(mo,f) \
|
||||||
(((mo)->mo_flags & (f)) == (f))
|
(((mo)->mo_flags & (f)) == (f))
|
||||||
#define MEMBEROF_DANGLING_CHECK(mo) \
|
#define MEMBEROF_DANGLING_CHECK(mo) \
|
||||||
@ -571,7 +573,7 @@ memberof_op_add( Operation *op, SlapReply *rs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
||||||
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
|
rc = rs->sr_err = mo->mo_dangling_err;
|
||||||
rs->sr_text = "adding non-existing object "
|
rs->sr_text = "adding non-existing object "
|
||||||
"as group member";
|
"as group member";
|
||||||
send_ldap_result( op, rs );
|
send_ldap_result( op, rs );
|
||||||
@ -649,7 +651,7 @@ memberof_op_add( Operation *op, SlapReply *rs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
||||||
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
|
rc = rs->sr_err = mo->mo_dangling_err;
|
||||||
rs->sr_text = "adding non-existing object "
|
rs->sr_text = "adding non-existing object "
|
||||||
"as memberof";
|
"as memberof";
|
||||||
send_ldap_result( op, rs );
|
send_ldap_result( op, rs );
|
||||||
@ -836,7 +838,7 @@ memberof_op_modify( Operation *op, SlapReply *rs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
||||||
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
|
rc = rs->sr_err = mo->mo_dangling_err;
|
||||||
rs->sr_text = "adding non-existing object "
|
rs->sr_text = "adding non-existing object "
|
||||||
"as group member";
|
"as group member";
|
||||||
send_ldap_result( op, rs );
|
send_ldap_result( op, rs );
|
||||||
@ -933,7 +935,7 @@ memberof_op_modify( Operation *op, SlapReply *rs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
||||||
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
|
rc = rs->sr_err = mo->mo_dangling_err;
|
||||||
rs->sr_text = "deleting non-existing object "
|
rs->sr_text = "deleting non-existing object "
|
||||||
"as memberof";
|
"as memberof";
|
||||||
send_ldap_result( op, rs );
|
send_ldap_result( op, rs );
|
||||||
@ -1044,7 +1046,7 @@ memberof_op_modify( Operation *op, SlapReply *rs )
|
|||||||
op->o_bd->bd_info = (BackendInfo *)on;
|
op->o_bd->bd_info = (BackendInfo *)on;
|
||||||
if ( rc != LDAP_SUCCESS ) {
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
|
||||||
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
|
rc = rs->sr_err = mo->mo_dangling_err;
|
||||||
rs->sr_text = "adding non-existing object "
|
rs->sr_text = "adding non-existing object "
|
||||||
"as memberof";
|
"as memberof";
|
||||||
send_ldap_result( op, rs );
|
send_ldap_result( op, rs );
|
||||||
@ -1490,6 +1492,10 @@ memberof_db_init(
|
|||||||
memberof_t tmp_mo = { 0 }, *mo;
|
memberof_t tmp_mo = { 0 }, *mo;
|
||||||
|
|
||||||
mo = (memberof_t *)ch_calloc( 1, sizeof( memberof_t ) );
|
mo = (memberof_t *)ch_calloc( 1, sizeof( memberof_t ) );
|
||||||
|
|
||||||
|
/* safe default */
|
||||||
|
mo->mo_dangling_err = LDAP_CONSTRAINT_VIOLATION;
|
||||||
|
|
||||||
on->on_bi.bi_private = (void *)mo;
|
on->on_bi.bi_private = (void *)mo;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1499,12 +1505,16 @@ enum {
|
|||||||
MO_DN = 1,
|
MO_DN = 1,
|
||||||
MO_DANGLING,
|
MO_DANGLING,
|
||||||
MO_REFINT,
|
MO_REFINT,
|
||||||
|
MO_GROUP_OC,
|
||||||
|
MO_MEMBER_AD,
|
||||||
|
MO_MEMBER_OF_AD,
|
||||||
#if 0
|
#if 0
|
||||||
MO_REVERSE,
|
MO_REVERSE,
|
||||||
#endif
|
#endif
|
||||||
MO_GROUP_OC,
|
|
||||||
MO_MEMBER_AD,
|
MO_DANGLING_ERROR,
|
||||||
MO_MEMBER_OF_AD
|
|
||||||
|
MO_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static ConfigDriver mo_cf_gen;
|
static ConfigDriver mo_cf_gen;
|
||||||
@ -1570,6 +1580,13 @@ static ConfigTable mo_cfg[] = {
|
|||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ "memberof-dangling-error", "error code",
|
||||||
|
2, 2, 0, ARG_MAGIC|MO_DANGLING_ERROR, mo_cf_gen,
|
||||||
|
"( OLcfgOvAt:18.7 NAME 'olcMemberOfDanglingError' "
|
||||||
|
"DESC 'Error code returned in case of dangling back reference' "
|
||||||
|
"SYNTAX OMsDirectoryString SINGLE-VALUE )",
|
||||||
|
NULL, NULL },
|
||||||
|
|
||||||
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
|
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1581,6 +1598,7 @@ static ConfigOCs mo_ocs[] = {
|
|||||||
"MAY ( "
|
"MAY ( "
|
||||||
"olcMemberOfDN "
|
"olcMemberOfDN "
|
||||||
"$ olcMemberOfDangling "
|
"$ olcMemberOfDangling "
|
||||||
|
"$ olcMemberOfDanglingError"
|
||||||
"$ olcMemberOfRefInt "
|
"$ olcMemberOfRefInt "
|
||||||
"$ olcMemberOfGroupOC "
|
"$ olcMemberOfGroupOC "
|
||||||
"$ olcMemberOfMemberAD "
|
"$ olcMemberOfMemberAD "
|
||||||
@ -1683,6 +1701,25 @@ mo_cf_gen( ConfigArgs *c )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MO_DANGLING_ERROR:
|
||||||
|
if ( mo->mo_flags & MEMBEROF_FDANGLING_ERROR ) {
|
||||||
|
char buf[ SLAP_TEXT_BUFLEN ];
|
||||||
|
enum_to_verb( slap_ldap_response_code, mo->mo_dangling_err, &bv );
|
||||||
|
if ( BER_BVISNULL( &bv ) ) {
|
||||||
|
bv.bv_len = snprintf( buf, sizeof( buf ), "0x%x", mo->mo_dangling_err );
|
||||||
|
if ( bv.bv_len < sizeof( buf ) ) {
|
||||||
|
bv.bv_val = buf;
|
||||||
|
} else {
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value_add_one( &c->rvalue_vals, &bv );
|
||||||
|
} else {
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MO_REFINT:
|
case MO_REFINT:
|
||||||
c->value_int = MEMBEROF_REFINT( mo );
|
c->value_int = MEMBEROF_REFINT( mo );
|
||||||
break;
|
break;
|
||||||
@ -1742,6 +1779,15 @@ mo_cf_gen( ConfigArgs *c )
|
|||||||
mo->mo_flags |= dangling_mode[ i ].mask;
|
mo->mo_flags |= dangling_mode[ i ].mask;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MO_DANGLING_ERROR:
|
||||||
|
i = verb_to_mask( c->argv[ 1 ], slap_ldap_response_code );
|
||||||
|
if ( !BER_BVISNULL( &slap_ldap_response_code[ i ].word ) ) {
|
||||||
|
mo->mo_dangling_err = slap_ldap_response_code[ i ].mask;
|
||||||
|
} else if ( lutil_atoix( &mo->mo_dangling_err, c->argv[ 1 ], 0 ) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MO_REFINT:
|
case MO_REFINT:
|
||||||
if ( c->value_int ) {
|
if ( c->value_int ) {
|
||||||
mo->mo_flags |= MEMBEROF_FREFINT;
|
mo->mo_flags |= MEMBEROF_FREFINT;
|
||||||
|
Loading…
Reference in New Issue
Block a user