X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fextended.c;h=be35dda443bb96d1330acaad8408dd43fe9b85c6;hb=b898f1271db5021e1873e38e1498a99d9450b646;hp=74e31281ca592d0464906b10ea07ea706d1ebc60;hpb=99f5983fb6e185fd1f135cb99776da6e581f71e1;p=openldap diff --git a/libraries/libldap/extended.c b/libraries/libldap/extended.c index 74e31281ca..be35dda443 100644 --- a/libraries/libldap/extended.c +++ b/libraries/libldap/extended.c @@ -1,9 +1,30 @@ /* $OpenLDAP$ */ -/* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2010 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ +#include "portable.h" + +#include +#include + +#include +#include +#include + +#include "ldap-int.h" +#include "ldap_log.h" + /* * LDAPv3 Extended Operation Request * ExtendedRequest ::= [APPLICATION 23] SEQUENCE { @@ -18,19 +39,9 @@ * response [11] OCTET STRING OPTIONAL * } * + * (Source RFC 4511) */ -#include "portable.h" - -#include -#include - -#include -#include -#include - -#include "ldap-int.h" - int ldap_extended_operation( LDAP *ld, @@ -42,16 +53,13 @@ ldap_extended_operation( { BerElement *ber; int rc; + ber_int_t id; -#ifdef NEW_LOGGING - LDAP_LOG (( "extended", LDAP_LEVEL_ENTRY, "ldap_extended_operation\n" )); -#else Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 ); -#endif assert( ld != NULL ); assert( LDAP_VALID( ld ) ); - assert( reqoid != NULL || *reqoid == '\0' ); + assert( reqoid != NULL && *reqoid != '\0' ); assert( msgidp != NULL ); /* must be version 3 (or greater) */ @@ -66,15 +74,16 @@ ldap_extended_operation( return( ld->ld_errno ); } + LDAP_NEXT_MSGID( ld, id ); if ( reqdata != NULL ) { rc = ber_printf( ber, "{it{tstON}", /* '}' */ - ++ld->ld_msgid, LDAP_REQ_EXTENDED, + id, LDAP_REQ_EXTENDED, LDAP_TAG_EXOP_REQ_OID, reqoid, LDAP_TAG_EXOP_REQ_VALUE, reqdata ); } else { rc = ber_printf( ber, "{it{tsN}", /* '}' */ - ++ld->ld_msgid, LDAP_REQ_EXTENDED, + id, LDAP_REQ_EXTENDED, LDAP_TAG_EXOP_REQ_OID, reqoid ); } @@ -97,7 +106,7 @@ ldap_extended_operation( } /* send the message */ - *msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber ); + *msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber, id ); return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS ); } @@ -116,16 +125,11 @@ ldap_extended_operation_s( int msgid; LDAPMessage *res; -#ifdef NEW_LOGGING - LDAP_LOG (( "extended", LDAP_LEVEL_ENTRY, "ldap_extended_operation_s\n" )); -#else Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation_s\n", 0, 0, 0 ); -#endif assert( ld != NULL ); assert( LDAP_VALID( ld ) ); - assert( reqoid != NULL || *reqoid == '\0' ); - assert( retoidp != NULL || retdatap != NULL ); + assert( reqoid != NULL && *reqoid != '\0' ); rc = ldap_extended_operation( ld, reqoid, reqdata, sctrls, cctrls, &msgid ); @@ -134,12 +138,12 @@ ldap_extended_operation_s( return( rc ); } - if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) { + if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) { return( ld->ld_errno ); } - *retoidp = NULL; - *retdatap = NULL; + if ( retoidp != NULL ) *retoidp = NULL; + if ( retdatap != NULL ) *retdatap = NULL; rc = ldap_parse_extended_result( ld, res, retoidp, retdatap, 0 ); @@ -172,11 +176,7 @@ ldap_parse_extended_result ( assert( LDAP_VALID( ld ) ); assert( res != NULL ); -#ifdef NEW_LOGGING - LDAP_LOG (( "extended", LDAP_LEVEL_ENTRY, "ldap_parse_extended_result\n" )); -#else Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 ); -#endif if( ld->ld_version < LDAP_VERSION3 ) { ld->ld_errno = LDAP_NOT_SUPPORTED; @@ -208,7 +208,7 @@ ldap_parse_extended_result ( return ld->ld_errno; } - rc = ber_scanf( ber, "{iaa" /*}*/, &errcode, + rc = ber_scanf( ber, "{eAA" /*}*/, &errcode, &ld->ld_matched, &ld->ld_error ); if( rc == LBER_ERROR ) { @@ -241,6 +241,8 @@ ldap_parse_extended_result ( return ld->ld_errno; } + assert( resoid[ 0 ] != '\0' ); + tag = ber_peek_tag( ber, &len ); } @@ -280,7 +282,7 @@ ldap_parse_extended_result ( /* Parse an extended partial */ int -ldap_parse_extended_partial ( +ldap_parse_intermediate ( LDAP *ld, LDAPMessage *res, char **retoidp, @@ -289,7 +291,6 @@ ldap_parse_extended_partial ( int freeit ) { BerElement *ber; - ber_tag_t rc; ber_tag_t tag; ber_len_t len; struct berval *resdata; @@ -299,25 +300,21 @@ ldap_parse_extended_partial ( assert( LDAP_VALID( ld ) ); assert( res != NULL ); -#ifdef NEW_LOGGING - LDAP_LOG (( "extended", LDAP_LEVEL_ENTRY, - "ldap_parse_extended_partial\n" )); -#else - Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_partial\n", 0, 0, 0 ); -#endif + Debug( LDAP_DEBUG_TRACE, "ldap_parse_intermediate\n", 0, 0, 0 ); if( ld->ld_version < LDAP_VERSION3 ) { ld->ld_errno = LDAP_NOT_SUPPORTED; return ld->ld_errno; } - if( res->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL ) { + if( res->lm_msgtype != LDAP_RES_INTERMEDIATE ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } if( retoidp != NULL ) *retoidp = NULL; if( retdatap != NULL ) *retdatap = NULL; + if( serverctrls != NULL ) *serverctrls = NULL; ber = ber_dup( res->lm_ber ); @@ -326,9 +323,9 @@ ldap_parse_extended_partial ( return ld->ld_errno; } - rc = ber_scanf( ber, "{" /*}*/ ); + tag = ber_scanf( ber, "{" /*}*/ ); - if( rc == LBER_ERROR ) { + if( tag == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; @@ -339,7 +336,13 @@ ldap_parse_extended_partial ( tag = ber_peek_tag( ber, &len ); - if( tag == LDAP_TAG_EXOP_RES_OID ) { + /* + * NOTE: accept intermediate and extended response tag values + * as older versions of slapd(8) incorrectly used extended + * response tags. + * Should be removed when 2.2 is moved to Historic. + */ + if( tag == LDAP_TAG_IM_RES_OID || tag == LDAP_TAG_EXOP_RES_OID ) { /* we have a resoid */ if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; @@ -347,10 +350,12 @@ ldap_parse_extended_partial ( return ld->ld_errno; } + assert( resoid[ 0 ] != '\0' ); + tag = ber_peek_tag( ber, &len ); } - if( tag == LDAP_TAG_EXOP_RES_VALUE ) { + if( tag == LDAP_TAG_IM_RES_VALUE || tag == LDAP_TAG_EXOP_RES_VALUE ) { /* we have a resdata */ if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; @@ -361,16 +366,16 @@ ldap_parse_extended_partial ( } if ( serverctrls == NULL ) { - rc = LDAP_SUCCESS; + ld->ld_errno = LDAP_SUCCESS; goto free_and_return; } if ( ber_scanf( ber, /*{*/ "}" ) == LBER_ERROR ) { - rc = LDAP_DECODING_ERROR; + ld->ld_errno = LDAP_DECODING_ERROR; goto free_and_return; } - rc = ldap_int_get_controls( ber, serverctrls ); + ld->ld_errno = ldap_pvt_get_controls( ber, serverctrls ); free_and_return: ber_free( ber, 0 ); @@ -391,5 +396,6 @@ free_and_return: ldap_msgfree( res ); } - return LDAP_SUCCESS; + return ld->ld_errno; } +