mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-03 20:40:05 -05:00
fix parsing of read entry control (ITS#5741)
This commit is contained in:
parent
9ebcd375e4
commit
4f26be5cf6
1 changed files with 60 additions and 101 deletions
|
|
@ -1226,113 +1226,47 @@ static int parseAssert (
|
|||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static int parsePreRead (
|
||||
#define READMSG(post, msg) \
|
||||
( post ? "postread control: " msg : "preread control: " msg )
|
||||
|
||||
static int
|
||||
parseReadAttrs(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl *ctrl )
|
||||
LDAPControl *ctrl,
|
||||
int post )
|
||||
{
|
||||
ber_len_t siz, off, i;
|
||||
AttributeName *an = NULL;
|
||||
ber_len_t siz, off, i;
|
||||
BerElement *ber;
|
||||
AttributeName *an = NULL;
|
||||
|
||||
if ( op->o_preread != SLAP_CONTROL_NONE ) {
|
||||
rs->sr_text = "preread control specified multiple times";
|
||||
if ( ( post && op->o_postread != SLAP_CONTROL_NONE ) ||
|
||||
( !post && op->o_preread != SLAP_CONTROL_NONE ) )
|
||||
{
|
||||
rs->sr_text = READMSG( post, "specified multiple times" );
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if ( BER_BVISNULL( &ctrl->ldctl_value )) {
|
||||
rs->sr_text = "preread control value is absent";
|
||||
if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
|
||||
rs->sr_text = READMSG( post, "value is absent" );
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
|
||||
rs->sr_text = "preread control value is empty";
|
||||
if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
|
||||
rs->sr_text = READMSG( post, "value is empty" );
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
#ifdef LDAP_X_TXN
|
||||
if ( op->o_txnSpec ) { /* temporary limitation */
|
||||
rs->sr_text = "cannot perform pre-read in transaction";
|
||||
rs->sr_text = READMSG( post, "cannot perform in transaction" );
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
#endif
|
||||
|
||||
ber = ber_init( &(ctrl->ldctl_value) );
|
||||
if (ber == NULL) {
|
||||
rs->sr_text = "preread control: internal error";
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
|
||||
siz = sizeof( AttributeName );
|
||||
off = offsetof( AttributeName, an_name );
|
||||
if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
|
||||
rs->sr_text = "preread control: decoding error";
|
||||
rs->sr_err = LDAP_PROTOCOL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for( i=0; i<siz; i++ ) {
|
||||
const char *dummy = NULL;
|
||||
|
||||
an[i].an_desc = NULL;
|
||||
an[i].an_oc = NULL;
|
||||
an[i].an_oc_exclude = 0;
|
||||
rs->sr_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
|
||||
if ( rs->sr_err != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
|
||||
rs->sr_text = dummy
|
||||
? dummy
|
||||
: "postread control: unknown attributeType";
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
op->o_preread = ctrl->ldctl_iscritical
|
||||
? SLAP_CONTROL_CRITICAL
|
||||
: SLAP_CONTROL_NONCRITICAL;
|
||||
|
||||
op->o_preread_attrs = an;
|
||||
|
||||
done:
|
||||
(void) ber_free( ber, 1 );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
static int parsePostRead (
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl *ctrl )
|
||||
{
|
||||
ber_len_t siz, off, i;
|
||||
AttributeName *an = NULL;
|
||||
BerElement *ber;
|
||||
|
||||
if ( op->o_postread != SLAP_CONTROL_NONE ) {
|
||||
rs->sr_text = "postread control specified multiple times";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if ( BER_BVISNULL( &ctrl->ldctl_value )) {
|
||||
rs->sr_text = "postread control value is absent";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
|
||||
rs->sr_text = "postread control value is empty";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
#ifdef LDAP_X_TXN
|
||||
if ( op->o_txnSpec ) { /* temporary limitation */
|
||||
rs->sr_text = "cannot perform post-read in transaction";
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
#endif
|
||||
|
||||
ber = ber_init( &(ctrl->ldctl_value) );
|
||||
if (ber == NULL) {
|
||||
rs->sr_text = "postread control: internal error";
|
||||
ber = ber_init( &ctrl->ldctl_value );
|
||||
if ( ber == NULL ) {
|
||||
rs->sr_text = READMSG( post, "internal error" );
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
|
|
@ -1340,7 +1274,7 @@ static int parsePostRead (
|
|||
siz = sizeof( AttributeName );
|
||||
off = offsetof( AttributeName, an_name );
|
||||
if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
|
||||
rs->sr_text = "postread control: decoding error";
|
||||
rs->sr_text = READMSG( post, "decoding error" );
|
||||
rs->sr_err = LDAP_PROTOCOL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1353,8 +1287,11 @@ static int parsePostRead (
|
|||
an[i].an_oc = NULL;
|
||||
an[i].an_oc_exclude = 0;
|
||||
rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
int i;
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
an[i].an_name = an[i].an_desc->ad_cname;
|
||||
|
||||
} else {
|
||||
int j;
|
||||
static struct berval special_attrs[] = {
|
||||
BER_BVC( LDAP_NO_ATTRS ),
|
||||
BER_BVC( LDAP_ALL_USER_ATTRIBUTES ),
|
||||
|
|
@ -1363,33 +1300,55 @@ static int parsePostRead (
|
|||
};
|
||||
|
||||
/* deal with special attribute types */
|
||||
for ( i = 0; !BER_BVISNULL( &special_attrs[ i ] ); i++ ) {
|
||||
if ( bvmatch( &an[i].an_name, &special_attrs[ i ] ) ) {
|
||||
for ( j = 0; !BER_BVISNULL( &special_attrs[ j ] ); j++ ) {
|
||||
if ( bvmatch( &an[i].an_name, &special_attrs[ j ] ) ) {
|
||||
an[i].an_name = special_attrs[ j ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( BER_BVISNULL( &special_attrs[ i ] ) && ctrl->ldctl_iscritical ) {
|
||||
if ( BER_BVISNULL( &special_attrs[ j ] ) && ctrl->ldctl_iscritical ) {
|
||||
rs->sr_err = rc;
|
||||
rs->sr_text = dummy
|
||||
? dummy
|
||||
: "postread control: unknown attributeType";
|
||||
rs->sr_text = dummy ? dummy
|
||||
: READMSG( post, "unknown attributeType" );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
op->o_postread = ctrl->ldctl_iscritical
|
||||
? SLAP_CONTROL_CRITICAL
|
||||
: SLAP_CONTROL_NONCRITICAL;
|
||||
|
||||
op->o_postread_attrs = an;
|
||||
if ( post ) {
|
||||
op->o_postread_attrs = an;
|
||||
op->o_postread = ctrl->ldctl_iscritical
|
||||
? SLAP_CONTROL_CRITICAL
|
||||
: SLAP_CONTROL_NONCRITICAL;
|
||||
} else {
|
||||
op->o_preread_attrs = an;
|
||||
op->o_preread = ctrl->ldctl_iscritical
|
||||
? SLAP_CONTROL_CRITICAL
|
||||
: SLAP_CONTROL_NONCRITICAL;
|
||||
}
|
||||
|
||||
done:
|
||||
(void) ber_free( ber, 1 );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
static int parsePreRead (
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl *ctrl )
|
||||
{
|
||||
return parseReadAttrs( op, rs, ctrl, 0 );
|
||||
}
|
||||
|
||||
static int parsePostRead (
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl *ctrl )
|
||||
{
|
||||
return parseReadAttrs( op, rs, ctrl, 1 );
|
||||
}
|
||||
|
||||
static int parseValuesReturnFilter (
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
|
|
|
|||
Loading…
Reference in a new issue