2005-09-08 13:01:08 +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-09-08 13:01:08 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "wine/port.h"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
2011-09-05 17:23:34 +02:00
|
|
|
#ifdef HAVE_LDAP_H
|
|
|
|
#include <ldap.h>
|
|
|
|
#endif
|
2005-09-08 13:01:08 +02:00
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winnls.h"
|
|
|
|
|
|
|
|
#include "winldap_private.h"
|
|
|
|
#include "wldap32.h"
|
2011-09-05 17:23:34 +02:00
|
|
|
#include "wine/debug.h"
|
2005-09-08 13:01:08 +02:00
|
|
|
|
2020-02-05 21:44:14 +01:00
|
|
|
#ifdef HAVE_LDAP
|
2005-09-08 13:01:08 +02:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
|
2020-02-05 21:44:14 +01:00
|
|
|
#endif
|
2005-09-08 13:01:08 +02:00
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_control_freeA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_control_freeW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_control_freeA( LDAPControlA *control )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_SUCCESS;
|
2005-09-08 13:01:08 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
|
|
|
|
TRACE( "(%p)\n", control );
|
|
|
|
controlfreeA( control );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_control_freeW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Free an LDAPControl structure.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* control [I] LDAPControl structure to free.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* LDAP_SUCCESS
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_control_freeW( LDAPControlW *control )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_SUCCESS;
|
2005-09-08 13:01:08 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
|
|
|
|
TRACE( "(%p)\n", control );
|
|
|
|
controlfreeW( control );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_controls_freeA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_controls_freeW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_controls_freeA( LDAPControlA **controls )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_SUCCESS;
|
2005-09-08 13:01:08 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
|
|
|
|
TRACE( "(%p)\n", controls );
|
|
|
|
controlarrayfreeA( controls );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_controls_freeW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Free an array of LDAPControl structures.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* controls [I] Array of LDAPControl structures to free.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* LDAP_SUCCESS
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_controls_freeW( LDAPControlW **controls )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_SUCCESS;
|
2005-09-08 13:01:08 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
|
|
|
|
TRACE( "(%p)\n", controls );
|
|
|
|
controlarrayfreeW( controls );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_create_sort_controlA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_create_sort_controlW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_create_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkey,
|
2005-09-08 20:56:22 +02:00
|
|
|
UCHAR critical, PLDAPControlA *control )
|
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
|
2005-09-08 20:56:22 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
LDAPSortKeyW **sortkeyW = NULL;
|
|
|
|
LDAPControlW *controlW = NULL;
|
|
|
|
|
|
|
|
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
|
|
|
|
|
|
|
|
if (!ld || !sortkey || !control)
|
|
|
|
return WLDAP32_LDAP_PARAM_ERROR;
|
|
|
|
|
|
|
|
sortkeyW = sortkeyarrayAtoW( sortkey );
|
|
|
|
if (!sortkeyW) return WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
|
|
|
|
ret = ldap_create_sort_controlW( ld, sortkeyW, critical, &controlW );
|
|
|
|
|
|
|
|
*control = controlWtoA( controlW );
|
|
|
|
if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
|
|
|
|
ldap_control_freeW( controlW );
|
|
|
|
sortkeyarrayfreeW( sortkeyW );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_create_sort_controlW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Create a control for server sorted search results.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* ld [I] Pointer to an LDAP context.
|
|
|
|
* sortkey [I] Array of LDAPSortKey structures, each specifying an
|
|
|
|
* attribute to use as a sort key, a matching rule and
|
|
|
|
* the sort order (ascending or descending).
|
|
|
|
* critical [I] Tells the server this control is critical to the
|
|
|
|
* search operation.
|
|
|
|
* control [O] LDAPControl created.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: LDAP_SUCCESS
|
|
|
|
* Failure: An LDAP error code.
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Pass the created control as a server control in subsequent calls
|
|
|
|
* to ldap_search_ext(_s) to obtain sorted search results.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkey,
|
2005-09-08 20:56:22 +02:00
|
|
|
UCHAR critical, PLDAPControlW *control )
|
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
|
2005-09-08 20:56:22 +02:00
|
|
|
#ifdef HAVE_LDAP
|
|
|
|
LDAPSortKey **sortkeyU = NULL;
|
|
|
|
LDAPControl *controlU = NULL;
|
|
|
|
|
|
|
|
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
|
|
|
|
|
|
|
|
if (!ld || !sortkey || !control)
|
|
|
|
return WLDAP32_LDAP_PARAM_ERROR;
|
|
|
|
|
|
|
|
sortkeyU = sortkeyarrayWtoU( sortkey );
|
|
|
|
if (!sortkeyU) return WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
|
2008-10-20 12:22:13 +02:00
|
|
|
ret = map_error( ldap_create_sort_control( ld, sortkeyU, critical, &controlU ));
|
2005-09-08 20:56:22 +02:00
|
|
|
|
|
|
|
*control = controlUtoW( controlU );
|
|
|
|
if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
|
|
|
|
ldap_control_free( controlU );
|
|
|
|
sortkeyarrayfreeU( sortkeyU );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_create_vlv_controlA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_create_vlv_controlW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
INT CDECL ldap_create_vlv_controlA( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
|
2005-11-23 20:12:07 +01:00
|
|
|
UCHAR critical, LDAPControlA **control )
|
2005-11-21 14:33:37 +01:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
|
2005-11-21 14:33:37 +01:00
|
|
|
#ifdef HAVE_LDAP
|
2006-04-08 16:11:42 +02:00
|
|
|
LDAPControlW *controlW = NULL;
|
2005-11-21 14:33:37 +01:00
|
|
|
|
|
|
|
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
|
|
|
|
|
2009-01-05 12:40:28 +01:00
|
|
|
if (!ld || !control) return ~0u;
|
2005-11-21 14:33:37 +01:00
|
|
|
|
2006-04-08 16:11:42 +02:00
|
|
|
ret = ldap_create_vlv_controlW( ld, info, critical, &controlW );
|
2005-11-21 14:33:37 +01:00
|
|
|
|
2007-11-08 13:11:34 +01:00
|
|
|
if (ret == WLDAP32_LDAP_SUCCESS)
|
2006-04-08 16:11:42 +02:00
|
|
|
{
|
|
|
|
*control = controlWtoA( controlW );
|
|
|
|
if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
ldap_control_freeW( controlW );
|
|
|
|
}
|
2005-11-21 14:33:37 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_create_vlv_controlW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Create a virtual list view control.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* ld [I] Pointer to an LDAP context.
|
|
|
|
* info [I] LDAPVLVInfo structure specifying a list view window.
|
|
|
|
* critical [I] Tells the server this control is critical to the
|
|
|
|
* search operation.
|
|
|
|
* control [O] LDAPControl created.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: LDAP_SUCCESS
|
|
|
|
* Failure: An LDAP error code.
|
|
|
|
*
|
|
|
|
* NOTES
|
2008-01-03 18:04:28 +01:00
|
|
|
* Pass the created control in conjunction with a sort control as
|
2005-11-30 18:26:42 +01:00
|
|
|
* server controls in subsequent calls to ldap_search_ext(_s). The
|
|
|
|
* server will then return a sorted, contiguous subset of results
|
|
|
|
* that meets the criteria specified in the LDAPVLVInfo structure.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
INT CDECL ldap_create_vlv_controlW( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
|
2005-11-23 20:12:07 +01:00
|
|
|
UCHAR critical, LDAPControlW **control )
|
2005-11-21 14:33:37 +01:00
|
|
|
{
|
2007-11-08 13:11:34 +01:00
|
|
|
INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
|
2005-11-21 14:33:37 +01:00
|
|
|
#ifdef HAVE_LDAP
|
2006-04-08 16:11:42 +02:00
|
|
|
LDAPControl *controlU = NULL;
|
2005-11-21 14:33:37 +01:00
|
|
|
|
|
|
|
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
|
|
|
|
|
2009-01-05 12:40:28 +01:00
|
|
|
if (!ld || !control) return ~0u;
|
2005-11-21 14:33:37 +01:00
|
|
|
|
2008-10-20 12:22:13 +02:00
|
|
|
ret = map_error( ldap_create_vlv_control( ld, (LDAPVLVInfo *)info, &controlU ));
|
2005-11-21 14:33:37 +01:00
|
|
|
|
2008-10-20 12:22:13 +02:00
|
|
|
if (ret == WLDAP32_LDAP_SUCCESS)
|
2006-04-08 16:11:42 +02:00
|
|
|
{
|
|
|
|
*control = controlUtoW( controlU );
|
|
|
|
if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
|
|
|
|
ldap_control_free( controlU );
|
|
|
|
}
|
2005-11-21 14:33:37 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-11-23 10:56:39 +01:00
|
|
|
static inline void bv_val_dup( const struct WLDAP32_berval *src, struct WLDAP32_berval *dst )
|
|
|
|
{
|
2018-02-20 12:06:10 +01:00
|
|
|
if ((dst->bv_val = heap_alloc( src->bv_len )))
|
2015-11-23 10:56:39 +01:00
|
|
|
{
|
|
|
|
memcpy( dst->bv_val, src->bv_val, src->bv_len );
|
|
|
|
dst->bv_len = src->bv_len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dst->bv_len = 0;
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_encode_sort_controlA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_encode_sort_controlW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_encode_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkeys,
|
2015-11-23 10:56:39 +01:00
|
|
|
PLDAPControlA ret, BOOLEAN critical )
|
2005-11-21 14:33:37 +01:00
|
|
|
{
|
2015-11-23 10:56:39 +01:00
|
|
|
LDAPControlA *control;
|
|
|
|
ULONG result;
|
|
|
|
|
|
|
|
if ((result = ldap_create_sort_controlA( ld, sortkeys, critical, &control )) == WLDAP32_LDAP_SUCCESS)
|
|
|
|
{
|
|
|
|
ret->ldctl_oid = strdupU(control->ldctl_oid);
|
|
|
|
bv_val_dup( &control->ldctl_value, &ret->ldctl_value );
|
|
|
|
ret->ldctl_iscritical = control->ldctl_iscritical;
|
|
|
|
ldap_control_freeA( control );
|
|
|
|
}
|
|
|
|
return result;
|
2005-11-21 14:33:37 +01:00
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_encode_sort_controlW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Create a control for server sorted search results.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* ld [I] Pointer to an LDAP context.
|
|
|
|
* sortkey [I] Array of LDAPSortKey structures, each specifying an
|
|
|
|
* attribute to use as a sort key, a matching rule and
|
|
|
|
* the sort order (ascending or descending).
|
|
|
|
* critical [I] Tells the server this control is critical to the
|
|
|
|
* search operation.
|
|
|
|
* control [O] LDAPControl created.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: LDAP_SUCCESS
|
|
|
|
* Failure: An LDAP error code.
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* This function is obsolete. Use its equivalent
|
|
|
|
* ldap_create_sort_control instead.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_encode_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkeys,
|
2015-11-23 10:56:39 +01:00
|
|
|
PLDAPControlW ret, BOOLEAN critical )
|
2005-11-21 14:33:37 +01:00
|
|
|
{
|
2015-11-23 10:56:39 +01:00
|
|
|
LDAPControlW *control;
|
|
|
|
ULONG result;
|
|
|
|
|
|
|
|
if ((result = ldap_create_sort_controlW( ld, sortkeys, critical, &control )) == WLDAP32_LDAP_SUCCESS)
|
|
|
|
{
|
|
|
|
ret->ldctl_oid = strdupW(control->ldctl_oid);
|
|
|
|
bv_val_dup( &control->ldctl_value, &ret->ldctl_value );
|
|
|
|
ret->ldctl_iscritical = control->ldctl_iscritical;
|
|
|
|
ldap_control_freeW( control );
|
|
|
|
}
|
|
|
|
return result;
|
2005-11-21 14:33:37 +01:00
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_free_controlsA (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* See ldap_free_controlsW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_free_controlsA( LDAPControlA **controls )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
|
|
|
return ldap_controls_freeA( controls );
|
|
|
|
}
|
|
|
|
|
2005-11-30 18:26:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* ldap_free_controlsW (WLDAP32.@)
|
|
|
|
*
|
|
|
|
* Free an array of LDAPControl structures.
|
|
|
|
*
|
2005-12-02 11:26:19 +01:00
|
|
|
* PARAMS
|
2005-11-30 18:26:42 +01:00
|
|
|
* controls [I] Array of LDAPControl structures to free.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* LDAP_SUCCESS
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Obsolete, use ldap_controls_freeW.
|
|
|
|
*/
|
2006-06-12 21:34:46 +02:00
|
|
|
ULONG CDECL ldap_free_controlsW( LDAPControlW **controls )
|
2005-09-08 13:01:08 +02:00
|
|
|
{
|
|
|
|
return ldap_controls_freeW( controls );
|
|
|
|
}
|