From 4f26be5cf67f26143a09304c5ee8fbab9aad1663 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Fri, 17 Oct 2008 00:02:13 +0000 Subject: [PATCH] fix parsing of read entry control (ITS#5741) --- servers/slapd/controls.c | 159 +++++++++++++++------------------------ 1 file changed, 59 insertions(+), 100 deletions(-) diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index bb4ca528af..f2efdd1696 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -1226,113 +1226,47 @@ static int parseAssert ( return LDAP_SUCCESS; } -static int parsePreRead ( - Operation *op, - SlapReply *rs, - LDAPControl *ctrl ) -{ - ber_len_t siz, off, i; - AttributeName *an = NULL; - BerElement *ber; - - if ( op->o_preread != SLAP_CONTROL_NONE ) { - rs->sr_text = "preread control specified multiple times"; - return LDAP_PROTOCOL_ERROR; - } - - if ( BER_BVISNULL( &ctrl->ldctl_value )) { - rs->sr_text = "preread control value is absent"; - return LDAP_PROTOCOL_ERROR; - } - - if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { - rs->sr_text = "preread control 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"; - 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; isr_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; - } - } +#define READMSG(post, msg) \ + ( post ? "postread control: " msg : "preread control: " msg ) - 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 ( +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_postread != SLAP_CONTROL_NONE ) { - rs->sr_text = "postread 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 = "postread 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 = "postread 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 post-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 = "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, -- 2.39.5