2005-07-18 20:06:42 +02:00
|
|
|
/*
|
|
|
|
* WLDAP32 - LDAP support for Wine
|
|
|
|
*
|
|
|
|
* Copyright 2005 Hans Leidekker
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-05-18 14:49:52 +02:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-07-18 20:06:42 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2005-11-24 19:21:49 +01:00
|
|
|
#include <stdarg.h>
|
2021-02-08 12:33:54 +01:00
|
|
|
#ifdef HAVE_LDAP_H
|
|
|
|
#include <ldap.h>
|
|
|
|
#endif
|
|
|
|
|
2005-07-18 20:06:42 +02:00
|
|
|
#include "windef.h"
|
2005-11-24 19:21:49 +01:00
|
|
|
#include "winbase.h"
|
2021-02-08 12:33:54 +01:00
|
|
|
#include "winldap_private.h"
|
|
|
|
#include "wldap32.h"
|
2006-04-18 20:40:40 +02:00
|
|
|
#include "wine/debug.h"
|
|
|
|
|
2020-02-05 21:44:14 +01:00
|
|
|
#ifdef HAVE_LDAP
|
2006-04-18 20:40:40 +02:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
|
2020-02-05 21:44:14 +01:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
|
2021-02-08 12:33:54 +01:00
|
|
|
#define WLDAP32_LBER_ERROR (~0U)
|
2005-07-18 20:06:42 +02:00
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* ber_alloc_t (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Allocate a berelement structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* options [I] Must be LBER_USE_DER.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Pointer to an allocated berelement structure.
|
|
|
|
* Failure: NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Free the berelement structure with ber_free.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
return ber_alloc_t( options );
|
|
|
|
#else
|
2005-07-18 20:06:42 +02:00
|
|
|
return NULL;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_bvdup (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Copy a berval structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berval [I] Pointer to the berval structure to be copied.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Pointer to a copy of the berval structure.
|
|
|
|
* Failure: NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Free the copy with ber_bvfree.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2021-02-08 12:33:54 +01:00
|
|
|
return bervalWtoW( berval );
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_bvecfree (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Free an array of berval structures.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berval [I] Pointer to an array of berval structures.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Use this function only to free an array of berval structures
|
|
|
|
* returned by a call to ber_scanf with a 'V' in the format string.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2021-02-08 12:33:54 +01:00
|
|
|
bvarrayfreeW( berval );
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_bvfree (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Free a berval structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berval [I] Pointer to a berval structure.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Use this function only to free berval structures allocated by
|
|
|
|
* an LDAP API.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2021-02-08 12:33:54 +01:00
|
|
|
heap_free( berval );
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_first_element (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Return the tag of the first element in a set or sequence.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I] Pointer to a berelement structure.
|
|
|
|
* len [O] Receives the length of the first element.
|
|
|
|
* opaque [O] Receives a pointer to a cookie.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Tag of the first element.
|
|
|
|
* Failure: LBER_DEFAULT (no more data).
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* len and cookie should be passed to ber_next_element.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR **opaque )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
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;
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_flatten (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Flatten a berelement structure into a berval structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
2008-01-03 18:04:28 +01:00
|
|
|
* berelement [I] Pointer to a berelement structure.
|
2006-07-10 22:18:40 +02:00
|
|
|
* berval [O] Pointer to a berval structure.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: 0
|
|
|
|
* Failure: LBER_ERROR
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Free the berval structure with ber_bvfree.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
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;
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_free (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Free a berelement structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
2008-01-03 18:04:28 +01:00
|
|
|
* berelement [I] Pointer to the berelement structure to be freed.
|
2006-07-10 22:18:40 +02:00
|
|
|
* buf [I] Flag.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Set buf to 0 if the berelement was allocated with ldap_first_attribute
|
|
|
|
* or ldap_next_attribute, otherwise set it to 1.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
ber_free( berelement, buf );
|
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_init (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Initialise a berelement structure from a berval structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berval [I] Pointer to a berval structure.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Pointer to a berelement structure.
|
|
|
|
* Failure: NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Call ber_free to free the returned berelement structure.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
struct berval *bervalU;
|
|
|
|
WLDAP32_BerElement *ret;
|
|
|
|
|
|
|
|
if (!(bervalU = bervalWtoU( berval ))) return NULL;
|
|
|
|
ret = ber_init( bervalU );
|
|
|
|
heap_free( bervalU );
|
|
|
|
return ret;
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2005-07-18 20:06:42 +02:00
|
|
|
return NULL;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_next_element (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Return the tag of the next element in a set or sequence.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I] Pointer to a berelement structure.
|
|
|
|
* len [I/O] Receives the length of the next element.
|
|
|
|
* opaque [I/O] Pointer to a cookie.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Tag of the next element.
|
|
|
|
* Failure: LBER_DEFAULT (no more data).
|
|
|
|
*
|
|
|
|
* NOTES
|
2008-01-03 18:04:28 +01:00
|
|
|
* len and cookie are initialized by ber_first_element and should
|
2006-07-10 22:18:40 +02:00
|
|
|
* be passed on in subsequent calls to ber_next_element.
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR *opaque )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
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;
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_peek_tag (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Return the tag of the next element.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I] Pointer to a berelement structure.
|
|
|
|
* len [O] Receives the length of the next element.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Tag of the next element.
|
|
|
|
* Failure: LBER_DEFAULT (no more data).
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
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;
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ber_skip_tag (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Skip the current tag and return the tag of the next element.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I] Pointer to a berelement structure.
|
|
|
|
* len [O] Receives the length of the skipped element.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Tag of the next element.
|
|
|
|
* Failure: LBER_DEFAULT (no more data).
|
2006-04-18 20:38:43 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:38:43 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2021-02-08 12:33:54 +01:00
|
|
|
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;
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:38:43 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:38:43 +02:00
|
|
|
|
2006-04-18 20:40:40 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* ber_printf (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Encode a berelement structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I/O] Pointer to a berelement structure.
|
|
|
|
* fmt [I] Format string.
|
|
|
|
* ... [I] Values to encode.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Non-negative number.
|
|
|
|
* Failure: LBER_ERROR
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* berelement must have been allocated with ber_alloc_t. This function
|
|
|
|
* can be called multiple times to append data.
|
2006-04-18 20:40:40 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:40:40 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_list list;
|
2006-04-18 20:40:40 +02:00
|
|
|
int ret = 0;
|
|
|
|
char new_fmt[2];
|
|
|
|
|
|
|
|
new_fmt[1] = 0;
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_start( list, fmt );
|
2006-04-18 20:40:40 +02:00
|
|
|
while (*fmt)
|
|
|
|
{
|
|
|
|
new_fmt[0] = *fmt++;
|
|
|
|
switch(new_fmt[0])
|
|
|
|
{
|
|
|
|
case 'b':
|
|
|
|
case 'e':
|
|
|
|
case 'i':
|
|
|
|
{
|
|
|
|
int i = va_arg( list, int );
|
|
|
|
ret = ber_printf( berelement, new_fmt, i );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'o':
|
|
|
|
case 's':
|
|
|
|
{
|
|
|
|
char *str = va_arg( list, char * );
|
|
|
|
ret = ber_printf( berelement, new_fmt, str );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 't':
|
|
|
|
{
|
|
|
|
unsigned int tag = va_arg( list, unsigned int );
|
|
|
|
ret = ber_printf( berelement, new_fmt, tag );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'v':
|
|
|
|
{
|
|
|
|
char **array = va_arg( list, char ** );
|
|
|
|
ret = ber_printf( berelement, new_fmt, array );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'V':
|
|
|
|
{
|
2021-02-08 12:33:54 +01:00
|
|
|
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 );
|
2006-04-18 20:40:40 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'X':
|
|
|
|
{
|
|
|
|
char *str = va_arg( list, char * );
|
|
|
|
int len = va_arg( list, int );
|
2006-08-11 14:42:06 +02:00
|
|
|
new_fmt[0] = 'B'; /* 'X' is deprecated */
|
|
|
|
ret = ber_printf( berelement, new_fmt, str, len );
|
2006-04-18 20:40:40 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'n':
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case '[':
|
|
|
|
case ']':
|
|
|
|
ret = ber_printf( berelement, new_fmt );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
FIXME( "Unknown format '%c'\n", new_fmt[0] );
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ret == -1) break;
|
|
|
|
}
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_end( list );
|
2006-04-18 20:40:40 +02:00
|
|
|
return ret;
|
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:40:40 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|
|
|
|
|
2006-04-18 20:40:40 +02:00
|
|
|
|
2006-04-18 20:41:03 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* ber_scanf (WLDAP32.@)
|
2006-07-10 22:18:40 +02:00
|
|
|
*
|
|
|
|
* Decode a berelement structure.
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* berelement [I/O] Pointer to a berelement structure.
|
|
|
|
* fmt [I] Format string.
|
|
|
|
* ... [I] Pointers to values to be decoded.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Non-negative number.
|
|
|
|
* Failure: LBER_ERROR
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* berelement must have been allocated with ber_init. This function
|
|
|
|
* can be called multiple times to decode data.
|
2006-04-18 20:41:03 +02:00
|
|
|
*/
|
2021-02-08 12:33:54 +01:00
|
|
|
INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
|
2005-07-18 20:06:42 +02:00
|
|
|
{
|
2006-04-18 20:41:03 +02:00
|
|
|
#ifdef HAVE_LDAP
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_list list;
|
2006-04-18 20:41:03 +02:00
|
|
|
int ret = 0;
|
|
|
|
char new_fmt[2];
|
|
|
|
|
|
|
|
new_fmt[1] = 0;
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_start( list, fmt );
|
2006-04-18 20:41:03 +02:00
|
|
|
while (*fmt)
|
|
|
|
{
|
|
|
|
new_fmt[0] = *fmt++;
|
|
|
|
switch(new_fmt[0])
|
|
|
|
{
|
|
|
|
case 'a':
|
|
|
|
{
|
|
|
|
char **ptr = va_arg( list, char ** );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, ptr );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'b':
|
|
|
|
case 'e':
|
|
|
|
case 'i':
|
|
|
|
{
|
|
|
|
int *i = va_arg( list, int * );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, i );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 't':
|
|
|
|
{
|
|
|
|
unsigned int *tag = va_arg( list, unsigned int * );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, tag );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'v':
|
|
|
|
{
|
|
|
|
char ***array = va_arg( list, char *** );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, array );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'B':
|
|
|
|
{
|
|
|
|
char **str = va_arg( list, char ** );
|
|
|
|
int *len = va_arg( list, int * );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, str, len );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'O':
|
|
|
|
{
|
|
|
|
struct berval **ptr = va_arg( list, struct berval ** );
|
|
|
|
ret = ber_scanf( berelement, new_fmt, ptr );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'V':
|
|
|
|
{
|
2021-02-08 12:33:54 +01:00
|
|
|
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 );
|
2006-04-18 20:41:03 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'n':
|
|
|
|
case 'x':
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case '[':
|
|
|
|
case ']':
|
|
|
|
ret = ber_scanf( berelement, new_fmt );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
FIXME( "Unknown format '%c'\n", new_fmt[0] );
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ret == -1) break;
|
|
|
|
}
|
2008-12-31 20:49:07 +01:00
|
|
|
__ms_va_end( list );
|
2006-04-18 20:41:03 +02:00
|
|
|
return ret;
|
|
|
|
#else
|
2021-02-08 12:33:54 +01:00
|
|
|
return WLDAP32_LBER_ERROR;
|
2006-04-18 20:41:03 +02:00
|
|
|
#endif
|
2005-07-18 20:06:42 +02:00
|
|
|
}
|