]> git.sur5r.net Git - openldap/commitdiff
fix parsing of read entry control (ITS#5741)
authorPierangelo Masarati <ando@openldap.org>
Fri, 17 Oct 2008 00:02:13 +0000 (00:02 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 17 Oct 2008 00:02:13 +0000 (00:02 +0000)
servers/slapd/controls.c

index bb4ca528afd8f68f371926fb8909efbf20be9d43..f2efdd1696255630eafbd4a0be30816e87d2c683 100644 (file)
@@ -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; 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;
-               }
-       }
+#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,