diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c index c4c77d68da8..7f39b9cfe17 100644 --- a/dlls/wldap32/ber.c +++ b/dlls/wldap32/ber.c @@ -21,18 +21,21 @@ #include "config.h" #include +#ifdef HAVE_LDAP_H +#include +#endif + #include "windef.h" #include "winbase.h" -#include "winldap.h" +#include "winldap_private.h" +#include "wldap32.h" #include "wine/debug.h" #ifdef HAVE_LDAP WINE_DEFAULT_DEBUG_CHANNEL(wldap32); #endif -#ifndef LBER_ERROR -# define LBER_ERROR (~0U) -#endif +#define WLDAP32_LBER_ERROR (~0U) /*********************************************************************** * ber_alloc_t (WLDAP32.@) @@ -49,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32); * NOTES * Free the berelement structure with ber_free. */ -BerElement * CDECL WLDAP32_ber_alloc_t( INT options ) +WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t( INT options ) { #ifdef HAVE_LDAP return ber_alloc_t( options ); @@ -76,11 +79,7 @@ BerElement * CDECL WLDAP32_ber_alloc_t( INT options ) */ BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval ) { -#ifdef HAVE_LDAP - return ber_bvdup( berval ); -#else - return NULL; -#endif + return bervalWtoW( berval ); } @@ -101,9 +100,7 @@ BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval ) */ void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval ) { -#ifdef HAVE_LDAP - ber_bvecfree( berval ); -#endif + bvarrayfreeW( berval ); } @@ -124,9 +121,7 @@ void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval ) */ void CDECL WLDAP32_ber_bvfree( BERVAL *berval ) { -#ifdef HAVE_LDAP - ber_bvfree( berval ); -#endif + heap_free( berval ); } @@ -147,12 +142,25 @@ void CDECL WLDAP32_ber_bvfree( BERVAL *berval ) * NOTES * len and cookie should be passed to ber_next_element. */ -ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque ) +ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR **opaque ) { #ifdef HAVE_LDAP - return ber_first_element( berelement, len, opaque ); + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_first_element( berelement, &len, opaque )) != LBER_ERROR) + { + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + *ret_len = len; + } + return ret; + #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -173,12 +181,22 @@ ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR * NOTES * Free the berval structure with ber_bvfree. */ -INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval ) +INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval ) { #ifdef HAVE_LDAP - return ber_flatten( berelement, berval ); + struct berval *bervalU; + struct WLDAP32_berval *bervalW; + + if (ber_flatten( berelement, &bervalU )) return WLDAP32_LBER_ERROR; + + bervalW = bervalUtoW( bervalU ); + ber_bvfree( bervalU ); + if (!bervalW) return WLDAP32_LBER_ERROR; + *berval = bervalW; + return 0; + #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -199,7 +217,7 @@ INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval ) * Set buf to 0 if the berelement was allocated with ldap_first_attribute * or ldap_next_attribute, otherwise set it to 1. */ -void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf ) +void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf ) { #ifdef HAVE_LDAP ber_free( berelement, buf ); @@ -222,10 +240,16 @@ void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf ) * NOTES * Call ber_free to free the returned berelement structure. */ -BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) +WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) { #ifdef HAVE_LDAP - return ber_init( berval ); + struct berval *bervalU; + WLDAP32_BerElement *ret; + + if (!(bervalU = bervalWtoU( berval ))) return NULL; + ret = ber_init( bervalU ); + heap_free( bervalU ); + return ret; #else return NULL; #endif @@ -250,12 +274,25 @@ BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) * len and cookie are initialized by ber_first_element and should * be passed on in subsequent calls to ber_next_element. */ -ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *opaque ) +ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR *opaque ) { #ifdef HAVE_LDAP - return ber_next_element( berelement, len, opaque ); + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_next_element( berelement, &len, opaque )) != LBER_ERROR) + { + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + *ret_len = len; + } + return ret; + #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -273,12 +310,25 @@ ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR * * Success: Tag of the next element. * Failure: LBER_DEFAULT (no more data). */ -ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len ) +ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len ) { #ifdef HAVE_LDAP - return ber_peek_tag( berelement, len ); + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_peek_tag( berelement, &len )) != LBER_ERROR) + { + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + *ret_len = len; + } + return ret; + #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -296,12 +346,25 @@ ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len ) * Success: Tag of the next element. * Failure: LBER_DEFAULT (no more data). */ -ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len ) +ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len ) { #ifdef HAVE_LDAP - return ber_skip_tag( berelement, len ); + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_skip_tag( berelement, &len )) != LBER_ERROR) + { + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + *ret_len = len; + } + return ret; + #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -324,7 +387,7 @@ ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len ) * berelement must have been allocated with ber_alloc_t. This function * can be called multiple times to append data. */ -INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... ) +INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) { #ifdef HAVE_LDAP __ms_va_list list; @@ -367,8 +430,15 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... ) } case 'V': { - struct berval **array = va_arg( list, struct berval ** ); - ret = ber_printf( berelement, new_fmt, array ); + struct WLDAP32_berval **array = va_arg( list, struct WLDAP32_berval ** ); + struct berval **arrayU; + if (!(arrayU = bvarrayWtoU( array ))) + { + ret = -1; + break; + } + ret = ber_printf( berelement, new_fmt, arrayU ); + bvarrayfreeU( arrayU ); break; } case 'X': @@ -396,7 +466,7 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... ) __ms_va_end( list ); return ret; #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } @@ -419,7 +489,7 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... ) * berelement must have been allocated with ber_init. This function * can be called multiple times to decode data. */ -INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... ) +INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) { #ifdef HAVE_LDAP __ms_va_list list; @@ -474,8 +544,12 @@ INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... ) } case 'V': { - struct berval ***array = va_arg( list, struct berval *** ); - ret = ber_scanf( berelement, new_fmt, array ); + struct WLDAP32_berval **arrayW, ***array = va_arg( list, struct WLDAP32_berval *** ); + struct berval **arrayU; + if ((ret = ber_scanf( berelement, new_fmt, &arrayU )) == -1) break; + if ((arrayW = bvarrayUtoW( arrayU ))) *array = arrayW; + else ret = -1; + bvarrayfreeU( arrayU ); break; } case 'n': @@ -496,6 +570,6 @@ INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... ) __ms_va_end( list ); return ret; #else - return LBER_ERROR; + return WLDAP32_LBER_ERROR; #endif } diff --git a/dlls/wldap32/page.c b/dlls/wldap32/page.c index 959567c2bfd..a16ea52409e 100644 --- a/dlls/wldap32/page.c +++ b/dlls/wldap32/page.c @@ -40,7 +40,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32); #ifdef HAVE_LDAP -static struct berval null_cookie = { 0, NULL }; +static struct berval null_cookieU = { 0, NULL }; +static struct WLDAP32_berval null_cookieW = { 0, NULL }; #endif /*********************************************************************** @@ -75,7 +76,7 @@ ULONG CDECL ldap_create_page_controlA( WLDAP32_LDAP *ld, ULONG pagesize, #ifdef HAVE_LDAP /* create a page control by hand */ -static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie, +static ULONG create_page_control( ULONG pagesize, struct berval *cookie, UCHAR critical, PLDAPControlW *control ) { LDAPControlW *ctrl; @@ -91,7 +92,7 @@ static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie, if (cookie) tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, cookie ); else - tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookie ); + tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookieU ); ret = ber_flatten( ber, &berval ); ber_free( ber, 1 ); @@ -149,13 +150,19 @@ ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize, struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlW *control ) { #ifdef HAVE_LDAP + struct berval *cookieU = NULL; + ULONG ret; + TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie, critical, control ); if (!ld || !control || pagesize > LDAP_MAXINT) return WLDAP32_LDAP_PARAM_ERROR; - return create_page_control( pagesize, cookie, critical, control ); + if (cookie && !(cookieU = bervalWtoU( cookie ))) return WLDAP32_LDAP_NO_MEMORY; + ret = create_page_control( pagesize, cookieU, critical, control ); + heap_free( cookieU ); + return ret; #else return WLDAP32_LDAP_NOT_SUPPORTED; @@ -197,7 +204,7 @@ ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search, } TRACE("search->cookie: %s\n", search->cookie ? debugstr_an(search->cookie->bv_val, search->cookie->bv_len) : "NULL"); - ret = ldap_create_page_controlW( ld, pagesize, (struct WLDAP32_berval *)search->cookie, 1, &search->serverctrls[0] ); + ret = ldap_create_page_controlW( ld, pagesize, search->cookie, 1, &search->serverctrls[0] ); if (ret != WLDAP32_LDAP_SUCCESS) return ret; ret = ldap_search_ext_sW( ld, search->dn, search->scope, @@ -230,17 +237,17 @@ ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search, if (!server_ctrls) /* assume end of paged results */ { - search->cookie = &null_cookie; + search->cookie = &null_cookieW; return WLDAP32_LDAP_SUCCESS; } if (search->cookie) { - ber_bvfree( search->cookie ); + heap_free( search->cookie ); search->cookie = NULL; } - ret = ldap_parse_page_controlW( ld, server_ctrls, count, (struct WLDAP32_berval **)&search->cookie ); + ret = ldap_parse_page_controlW( ld, server_ctrls, count, &search->cookie ); if (ret == WLDAP32_LDAP_SUCCESS) TRACE("new search->cookie: %s, count %u\n", debugstr_an(search->cookie->bv_val, search->cookie->bv_len), *count); @@ -286,6 +293,7 @@ ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls, ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP LDAPControlW *control = NULL; + struct berval *cookieU = NULL, *valueU; BerElement *ber; ber_tag_t tag; ULONG i; @@ -302,20 +310,34 @@ ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls, } if (!control) - return WLDAP32_LDAP_CONTROL_NOT_FOUND; - - ber = ber_init( &((LDAPControl *)control)->ldctl_value ); - if (!ber) + return WLDAP32_LDAP_CONTROL_NOT_FOUND; + + if (cookie && !(cookieU = bervalWtoU( *cookie ))) return WLDAP32_LDAP_NO_MEMORY; - tag = ber_scanf( ber, "{iO}", count, cookie ); - if ( tag == LBER_ERROR ) + if (!(valueU = bervalWtoU( &control->ldctl_value ))) + { + heap_free( cookieU ); + return WLDAP32_LDAP_NO_MEMORY; + } + + ber = ber_init( valueU ); + heap_free( valueU ); + if (!ber) + { + heap_free( cookieU ); + return WLDAP32_LDAP_NO_MEMORY; + } + + tag = ber_scanf( ber, "{iO}", count, &cookieU ); + if (tag == LBER_ERROR) ret = WLDAP32_LDAP_DECODING_ERROR; else ret = WLDAP32_LDAP_SUCCESS; + heap_free( cookieU ); ber_free( ber, 1 ); - + #endif return ret; } @@ -338,8 +360,8 @@ ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, PLDAPSearch search ) while (*ctrls) controlfreeW( *ctrls++ ); heap_free( search->serverctrls ); controlarrayfreeW( search->clientctrls ); - if (search->cookie && search->cookie != &null_cookie) - ber_bvfree( search->cookie ); + if (search->cookie && search->cookie != &null_cookieW) + heap_free( search->cookie ); heap_free( search ); return WLDAP32_LDAP_SUCCESS; diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h index 69035050961..8cd546b88b5 100644 --- a/dlls/wldap32/winldap_private.h +++ b/dlls/wldap32/winldap_private.h @@ -103,6 +103,12 @@ typedef struct berelement #define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486 +typedef struct WLDAP32_berval +{ + ULONG bv_len; + PCHAR bv_val; +} LDAP_BERVAL, *PLDAP_BERVAL, BERVAL, *PBERVAL, WLDAP32_BerValue; + typedef struct wldap32 { #ifdef HAVE_LDAP @@ -139,7 +145,7 @@ typedef struct ldapmodA { PCHAR mod_type; union { PCHAR *modv_strvals; - struct berval **modv_bvals; + struct WLDAP32_berval **modv_bvals; } mod_vals; } LDAPModA, *PLDAPModA; @@ -148,7 +154,7 @@ typedef struct ldapmodW { PWCHAR mod_type; union { PWCHAR *modv_strvals; - struct berval **modv_bvals; + struct WLDAP32_berval **modv_bvals; } mod_vals; } LDAPModW, *PLDAPModW; @@ -188,12 +194,6 @@ typedef struct ldap_version_info ULONG lv_minor; } LDAP_VERSION_INFO, *PLDAP_VERSION_INFO; -typedef struct WLDAP32_berval -{ - ULONG bv_len; - PCHAR bv_val; -} LDAP_BERVAL, *PLDAP_BERVAL, BERVAL, *PBERVAL, WLDAP32_BerValue; - #define LDAP_PAGED_RESULT_OID_STRING "1.2.840.113556.1.4.319" #define LDAP_SERVER_RESP_SORT_OID "1.2.840.113556.1.4.474" #define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10" @@ -242,7 +242,7 @@ typedef struct ldapsearch LDAPControlW **clientctrls; struct l_timeval timeout; ULONG sizelimit; - struct berval *cookie; + struct WLDAP32_berval *cookie; } LDAPSearch, *PLDAPSearch; typedef struct ldapsortkeyA diff --git a/dlls/wldap32/wldap32.h b/dlls/wldap32/wldap32.h index 3059df8603e..5b099c9fabc 100644 --- a/dlls/wldap32/wldap32.h +++ b/dlls/wldap32/wldap32.h @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include "wine/heap.h" #include "wine/unicode.h" @@ -293,16 +294,14 @@ static inline void strarrayfreeU( char **strarray ) } } -#ifdef HAVE_LDAP - -static inline struct berval *bvdup( struct berval *bv ) +static inline struct WLDAP32_berval *bervalWtoW( struct WLDAP32_berval *bv ) { - struct berval *berval; - DWORD size = sizeof(struct berval) + bv->bv_len; + struct WLDAP32_berval *berval; + DWORD size = sizeof(*berval) + bv->bv_len; if ((berval = heap_alloc( size ))) { - char *val = (char *)berval + sizeof(struct berval); + char *val = (char *)(berval + 1); berval->bv_len = bv->bv_len; berval->bv_val = val; @@ -311,34 +310,124 @@ static inline struct berval *bvdup( struct berval *bv ) return berval; } -static inline DWORD bvarraylen( struct berval **bv ) +static inline void bvarrayfreeW( struct WLDAP32_berval **bv ) +{ + struct WLDAP32_berval **p = bv; + while (*p) heap_free( *p++ ); + heap_free( bv ); +} + +#ifdef HAVE_LDAP + +static inline struct berval *bervalWtoU( struct WLDAP32_berval *bv ) +{ + struct berval *berval; + DWORD size = sizeof(*berval) + bv->bv_len; + + if ((berval = heap_alloc( size ))) + { + char *val = (char *)(berval + 1); + + berval->bv_len = bv->bv_len; + berval->bv_val = val; + memcpy( val, bv->bv_val, bv->bv_len ); + } + return berval; +} + +static inline struct WLDAP32_berval *bervalUtoW( struct berval *bv ) +{ + struct WLDAP32_berval *berval; + DWORD size = sizeof(*berval) + bv->bv_len; + + assert( bv->bv_len <= ~0u ); + + if ((berval = heap_alloc( size ))) + { + char *val = (char *)(berval + 1); + + berval->bv_len = bv->bv_len; + berval->bv_val = val; + memcpy( val, bv->bv_val, bv->bv_len ); + } + return berval; +} + +static inline DWORD bvarraylenU( struct berval **bv ) { struct berval **p = bv; while (*p) p++; return p - bv; } -static inline struct berval **bvarraydup( struct berval **bv ) +static inline DWORD bvarraylenW( struct WLDAP32_berval **bv ) { - struct berval **berval = NULL; + struct WLDAP32_berval **p = bv; + while (*p) p++; + return p - bv; +} + +static inline struct WLDAP32_berval **bvarrayWtoW( struct WLDAP32_berval **bv ) +{ + struct WLDAP32_berval **berval = NULL; DWORD size; if (bv) { - size = sizeof(struct berval *) * (bvarraylen( bv ) + 1); + size = sizeof(*berval) * (bvarraylenW( bv ) + 1); if ((berval = heap_alloc( size ))) { - struct berval **p = bv; - struct berval **q = berval; + struct WLDAP32_berval **p = bv; + struct WLDAP32_berval **q = berval; - while (*p) *q++ = bvdup( *p++ ); + while (*p) *q++ = bervalWtoW( *p++ ); *q = NULL; } } return berval; } -static inline void bvarrayfree( struct berval **bv ) +static inline struct berval **bvarrayWtoU( struct WLDAP32_berval **bv ) +{ + struct berval **berval = NULL; + DWORD size; + + if (bv) + { + size = sizeof(*berval) * (bvarraylenW( bv ) + 1); + if ((berval = heap_alloc( size ))) + { + struct WLDAP32_berval **p = bv; + struct berval **q = berval; + + while (*p) *q++ = bervalWtoU( *p++ ); + *q = NULL; + } + } + return berval; +} + +static inline struct WLDAP32_berval **bvarrayUtoW( struct berval **bv ) +{ + struct WLDAP32_berval **berval = NULL; + DWORD size; + + if (bv) + { + size = sizeof(*berval) * (bvarraylenU( bv ) + 1); + if ((berval = heap_alloc( size ))) + { + struct berval **p = bv; + struct WLDAP32_berval **q = berval; + + while (*p) *q++ = bervalUtoW( *p++ ); + *q = NULL; + } + } + return berval; +} + +static inline void bvarrayfreeU( struct berval **bv ) { struct berval **p = bv; while (*p) heap_free( *p++ ); @@ -355,7 +444,7 @@ static inline LDAPModW *modAtoW( LDAPModA *mod ) modW->mod_type = strAtoW( mod->mod_type ); if (mod->mod_op & LDAP_MOD_BVALUES) - modW->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals ); + modW->mod_vals.modv_bvals = bvarrayWtoW( mod->mod_vals.modv_bvals ); else modW->mod_vals.modv_strvals = strarrayAtoW( mod->mod_vals.modv_strvals ); } @@ -372,7 +461,7 @@ static inline LDAPMod *modWtoU( LDAPModW *mod ) modU->mod_type = strWtoU( mod->mod_type ); if (mod->mod_op & LDAP_MOD_BVALUES) - modU->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals ); + modU->mod_vals.modv_bvals = bvarrayWtoU( mod->mod_vals.modv_bvals ); else modU->mod_vals.modv_strvals = strarrayWtoU( mod->mod_vals.modv_strvals ); } @@ -382,7 +471,7 @@ static inline LDAPMod *modWtoU( LDAPModW *mod ) static inline void modfreeW( LDAPModW *mod ) { if (mod->mod_op & LDAP_MOD_BVALUES) - bvarrayfree( mod->mod_vals.modv_bvals ); + bvarrayfreeW( mod->mod_vals.modv_bvals ); else strarrayfreeW( mod->mod_vals.modv_strvals ); heap_free( mod ); @@ -391,7 +480,7 @@ static inline void modfreeW( LDAPModW *mod ) static inline void modfreeU( LDAPMod *mod ) { if (mod->mod_op & LDAP_MOD_BVALUES) - bvarrayfree( mod->mod_vals.modv_bvals ); + bvarrayfreeU( mod->mod_vals.modv_bvals ); else strarrayfreeU( mod->mod_vals.modv_strvals ); heap_free( mod );