2969 lines
87 KiB
C
2969 lines
87 KiB
C
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
winldap.h LDAP client 32 API header file
|
|
|
|
Abstract:
|
|
|
|
This module is the header file for the 32 bit LDAP client API for
|
|
Windows NT and Windows 95. This API is based on RFC 1823 with some
|
|
enhancements for LDAP v3.
|
|
|
|
Notes about Unicode support :
|
|
|
|
If you have UNICODE defined at compile time, you'll pull in the unicode
|
|
versions of the calls. Note that your executable may then not work with
|
|
other implementations of the LDAP API that don't support Unicode. If
|
|
UNICODE is not defined, then we define the LDAP calls without the trailing
|
|
'A' (as in ldap_bind rather than ldap_bindA) so that your app may work
|
|
with other implementations that don't support Unicode.
|
|
|
|
The import library has all three forms of the call present... ldap_bindW,
|
|
ldap_bindA, and ldap_bind. ldap_bindA simply calls ldap_bind. ldap_bind
|
|
simply converts the arguments to unicode and calls ldap_bindW. The
|
|
reason this is done is because we have to put UTF-8 on the wire, so if
|
|
we converted from Unicode to single byte, we'd loose information. Since
|
|
all core processing is done in Unicode, nothing is lost.
|
|
|
|
Updates :
|
|
|
|
11/01/96 Modified for new API RFC draft.
|
|
|
|
Environments :
|
|
|
|
Win32 user mode
|
|
|
|
--*/
|
|
|
|
//
|
|
// Only pull in this header file once... controlled by LDAP_CLIENT_DEFINED
|
|
// variable.
|
|
//
|
|
|
|
#ifndef LDAP_CLIENT_DEFINED
|
|
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
|
|
#define LDAP_CLIENT_DEFINED
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifndef BASETYPES
|
|
#include <windef.h>
|
|
#endif
|
|
|
|
#ifndef _SCHNLSP_H_
|
|
#include <schnlsp.h>
|
|
#endif
|
|
|
|
#if !defined(_WINLDAP_)
|
|
#define WINLDAPAPI DECLSPEC_IMPORT
|
|
#else
|
|
//#define WINLDAPAPI __declspec(dllexport)
|
|
#define WINLDAPAPI
|
|
#endif
|
|
|
|
#ifndef LDAPAPI
|
|
#define LDAPAPI __cdecl
|
|
#endif
|
|
|
|
//
|
|
// The #define LDAP_UNICODE controls if we map the undecorated calls to
|
|
// their unicode counterparts or just leave them defined as the normal
|
|
// single byte entry points.
|
|
//
|
|
// If you want to write a UNICODE enabled application, you'd normally
|
|
// just have UNICODE defined and then we'll default to using all LDAP
|
|
// Unicode calls.
|
|
//
|
|
|
|
#ifndef LDAP_UNICODE
|
|
#ifdef UNICODE
|
|
#define LDAP_UNICODE 1
|
|
#else
|
|
#define LDAP_UNICODE 0
|
|
#endif
|
|
#endif
|
|
|
|
//
|
|
// Global constants
|
|
//
|
|
|
|
#define LDAP_PORT 389
|
|
#define LDAP_SSL_PORT 636
|
|
#define LDAP_GC_PORT 3268
|
|
#define LDAP_SSL_GC_PORT 3269
|
|
|
|
//
|
|
// We currently support going to either v2 or v3 servers, though the API
|
|
// is only a V2 API. We'll add support for result sets, server side
|
|
// sorting, extended operations, etc as soon as they stabilize.
|
|
//
|
|
|
|
#define LDAP_VERSION1 1
|
|
#define LDAP_VERSION2 2
|
|
#define LDAP_VERSION3 3
|
|
#define LDAP_VERSION LDAP_VERSION2
|
|
|
|
//
|
|
// All tags are CCFTTTTT.
|
|
// CC Tag Class 00 = universal
|
|
// 01 = application wide
|
|
// 10 = context specific
|
|
// 11 = private use
|
|
//
|
|
// F Form 0 primitive
|
|
// 1 constructed
|
|
//
|
|
// TTTTT Tag Number
|
|
//
|
|
|
|
//
|
|
// LDAP v2 & v3 commands.
|
|
//
|
|
|
|
#define LDAP_BIND_CMD 0x60L // application + constructed
|
|
#define LDAP_UNBIND_CMD 0x42L // application + primitive
|
|
#define LDAP_SEARCH_CMD 0x63L // application + constructed
|
|
#define LDAP_MODIFY_CMD 0x66L // application + constructed
|
|
#define LDAP_ADD_CMD 0x68L // application + constructed
|
|
#define LDAP_DELETE_CMD 0x4aL // application + primitive
|
|
#define LDAP_MODRDN_CMD 0x6cL // application + constructed
|
|
#define LDAP_COMPARE_CMD 0x6eL // application + constructed
|
|
#define LDAP_ABANDON_CMD 0x50L // application + primitive
|
|
#define LDAP_SESSION_CMD 0x71L // not in base LDAP protocol
|
|
#define LDAP_EXTENDED_CMD 0x77L // application + constructed
|
|
|
|
//
|
|
// Responses/Results for LDAP v2 & v3
|
|
//
|
|
|
|
#define LDAP_RES_BIND 0x61L // application + constructed
|
|
#define LDAP_RES_SEARCH_ENTRY 0x64L // application + constructed
|
|
#define LDAP_RES_SEARCH_RESULT 0x65L // application + constructed
|
|
#define LDAP_RES_MODIFY 0x67L // application + constructed
|
|
#define LDAP_RES_ADD 0x69L // application + constructed
|
|
#define LDAP_RES_DELETE 0x6bL // application + constructed
|
|
#define LDAP_RES_MODRDN 0x6dL // application + constructed
|
|
#define LDAP_RES_COMPARE 0x6fL // application + constructed
|
|
#define LDAP_RES_SESSION 0x72L // not in base LDAP protocol
|
|
#define LDAP_RES_REFERRAL 0x73L // application + constructed
|
|
#define LDAP_RES_EXTENDED 0x78L // application + constructed
|
|
#define LDAP_RES_ANY (-1L)
|
|
|
|
#define LDAP_INVALID_CMD 0xff
|
|
#define LDAP_INVALID_RES 0xff
|
|
|
|
|
|
//
|
|
// We'll make the error codes compatible with reference implementation
|
|
//
|
|
|
|
typedef enum {
|
|
LDAP_SUCCESS = 0x00,
|
|
LDAP_OPERATIONS_ERROR = 0x01,
|
|
LDAP_PROTOCOL_ERROR = 0x02,
|
|
LDAP_TIMELIMIT_EXCEEDED = 0x03,
|
|
LDAP_SIZELIMIT_EXCEEDED = 0x04,
|
|
LDAP_COMPARE_FALSE = 0x05,
|
|
LDAP_COMPARE_TRUE = 0x06,
|
|
LDAP_AUTH_METHOD_NOT_SUPPORTED = 0x07,
|
|
LDAP_STRONG_AUTH_REQUIRED = 0x08,
|
|
LDAP_REFERRAL_V2 = 0x09,
|
|
LDAP_PARTIAL_RESULTS = 0x09,
|
|
LDAP_REFERRAL = 0x0a,
|
|
LDAP_ADMIN_LIMIT_EXCEEDED = 0x0b,
|
|
LDAP_UNAVAILABLE_CRIT_EXTENSION = 0x0c,
|
|
LDAP_CONFIDENTIALITY_REQUIRED = 0x0d,
|
|
LDAP_SASL_BIND_IN_PROGRESS = 0x0e,
|
|
|
|
LDAP_NO_SUCH_ATTRIBUTE = 0x10,
|
|
LDAP_UNDEFINED_TYPE = 0x11,
|
|
LDAP_INAPPROPRIATE_MATCHING = 0x12,
|
|
LDAP_CONSTRAINT_VIOLATION = 0x13,
|
|
LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 0x14,
|
|
LDAP_INVALID_SYNTAX = 0x15,
|
|
|
|
LDAP_NO_SUCH_OBJECT = 0x20,
|
|
LDAP_ALIAS_PROBLEM = 0x21,
|
|
LDAP_INVALID_DN_SYNTAX = 0x22,
|
|
LDAP_IS_LEAF = 0x23,
|
|
LDAP_ALIAS_DEREF_PROBLEM = 0x24,
|
|
|
|
LDAP_INAPPROPRIATE_AUTH = 0x30,
|
|
LDAP_INVALID_CREDENTIALS = 0x31,
|
|
LDAP_INSUFFICIENT_RIGHTS = 0x32,
|
|
LDAP_BUSY = 0x33,
|
|
LDAP_UNAVAILABLE = 0x34,
|
|
LDAP_UNWILLING_TO_PERFORM = 0x35,
|
|
LDAP_LOOP_DETECT = 0x36,
|
|
|
|
LDAP_NAMING_VIOLATION = 0x40,
|
|
LDAP_OBJECT_CLASS_VIOLATION = 0x41,
|
|
LDAP_NOT_ALLOWED_ON_NONLEAF = 0x42,
|
|
LDAP_NOT_ALLOWED_ON_RDN = 0x43,
|
|
LDAP_ALREADY_EXISTS = 0x44,
|
|
LDAP_NO_OBJECT_CLASS_MODS = 0x45,
|
|
LDAP_RESULTS_TOO_LARGE = 0x46,
|
|
LDAP_AFFECTS_MULTIPLE_DSAS = 0x47,
|
|
|
|
LDAP_OTHER = 0x50,
|
|
LDAP_SERVER_DOWN = 0x51,
|
|
LDAP_LOCAL_ERROR = 0x52,
|
|
LDAP_ENCODING_ERROR = 0x53,
|
|
LDAP_DECODING_ERROR = 0x54,
|
|
LDAP_TIMEOUT = 0x55,
|
|
LDAP_AUTH_UNKNOWN = 0x56,
|
|
LDAP_FILTER_ERROR = 0x57,
|
|
LDAP_USER_CANCELLED = 0x58,
|
|
LDAP_PARAM_ERROR = 0x59,
|
|
LDAP_NO_MEMORY = 0x5a,
|
|
LDAP_CONNECT_ERROR = 0x5b,
|
|
LDAP_NOT_SUPPORTED = 0x5c,
|
|
LDAP_NO_RESULTS_RETURNED = 0x5e,
|
|
LDAP_CONTROL_NOT_FOUND = 0x5d,
|
|
LDAP_MORE_RESULTS_TO_RETURN = 0x5f,
|
|
|
|
LDAP_CLIENT_LOOP = 0x60,
|
|
LDAP_REFERRAL_LIMIT_EXCEEDED = 0x61
|
|
} LDAP_RETCODE;
|
|
|
|
//
|
|
// Bind methods. We support the following methods :
|
|
//
|
|
// Simple Clear text password... try not to use as it's not secure.
|
|
//
|
|
// MSN MSN (Microsoft Network) authentication. This package
|
|
// may bring up UI to prompt the user for MSN credentials.
|
|
//
|
|
// DPA Normandy authentication... new MSN authentication. Same
|
|
// usage as MSN.
|
|
//
|
|
// NTLM NT domain authentication. Use NULL credentials and
|
|
// we'll try to use default logged in user credentials.
|
|
//
|
|
// Sicily Negotiate with the server for any of: MSN, DPA, NTLM
|
|
// Should be used for LDAPv2 servers only.
|
|
//
|
|
// Negotiate Use GSSAPI Negotiate package to negotiate security
|
|
// package of either Kerberos v5 or NTLM (or any other
|
|
// package the client and server negotiate). Pass in
|
|
// NULL credentials to specify default logged in user.
|
|
// If Negotiate package is not installed on server or
|
|
// client, this will fall back to Sicily negotiation.
|
|
//
|
|
// For all bind methods except for Simple, you may pass in a
|
|
// SEC_WINNT_AUTH_IDENTITY_W (defined in rpcdce.h) or the newer
|
|
// SEC_WINNT_AUTH_IDENTITY_EXW (defined in secext.h) to specify alternate
|
|
// credentials.
|
|
//
|
|
// All bind methods other than simple are synchronous only calls.
|
|
// Calling the asynchronous bind call for any of these messages will
|
|
// return LDAP_PARAM_ERROR.
|
|
//
|
|
// Using any other method besides simple will cause WLDAP32 to pull in
|
|
// the SSPI security DLLs (SECURITY.DLL etc).
|
|
//
|
|
// On non-Simple methods, if you specify NULL credentials, we'll attempt to use
|
|
// the default logged in user.
|
|
//
|
|
|
|
#define LDAP_AUTH_SIMPLE 0x80L
|
|
#define LDAP_AUTH_SASL 0x83L // don't use... should go away
|
|
|
|
#define LDAP_AUTH_OTHERKIND 0x86L
|
|
|
|
// The SICILY type covers package negotiation to MSN servers.
|
|
// Each of the supported types can also be specified without
|
|
// doing the package negotiation, assuming the caller knows
|
|
// what the server supports.
|
|
|
|
#define LDAP_AUTH_SICILY (LDAP_AUTH_OTHERKIND | 0x0200)
|
|
|
|
#define LDAP_AUTH_MSN (LDAP_AUTH_OTHERKIND | 0x0800)
|
|
#define LDAP_AUTH_NTLM (LDAP_AUTH_OTHERKIND | 0x1000)
|
|
#define LDAP_AUTH_DPA (LDAP_AUTH_OTHERKIND | 0x2000)
|
|
|
|
// This will cause the client to use the GSSAPI negotiation
|
|
// package to determine the most appropriate authentication type.
|
|
// This type should be used when talking to NT5.
|
|
|
|
#define LDAP_AUTH_NEGOTIATE (LDAP_AUTH_OTHERKIND | 0x0400)
|
|
|
|
// backward compatible #define for older constant name.
|
|
|
|
#define LDAP_AUTH_SSPI LDAP_AUTH_NEGOTIATE
|
|
|
|
//
|
|
// Client applications typically don't have to encode/decode LDAP filters,
|
|
// but if they do, we define the operators here.
|
|
//
|
|
// Filter types.
|
|
|
|
#define LDAP_FILTER_AND 0xa0 // context specific + constructed - SET OF Filters.
|
|
#define LDAP_FILTER_OR 0xa1 // context specific + constructed - SET OF Filters.
|
|
#define LDAP_FILTER_NOT 0xa2 // context specific + constructed - Filter
|
|
#define LDAP_FILTER_EQUALITY 0xa3 // context specific + constructed - AttributeValueAssertion.
|
|
#define LDAP_FILTER_SUBSTRINGS 0xa4 // context specific + constructed - SubstringFilter
|
|
#define LDAP_FILTER_GE 0xa5 // context specific + constructed - AttributeValueAssertion.
|
|
#define LDAP_FILTER_LE 0xa6 // context specific + constructed - AttributeValueAssertion.
|
|
#define LDAP_FILTER_PRESENT 0x87 // context specific + primitive - AttributeType.
|
|
#define LDAP_FILTER_APPROX 0xa8 // context specific + constructed - AttributeValueAssertion.
|
|
#define LDAP_FILTER_EXTENSIBLE 0xa9 // context specific + constructed - MatchingRuleAssertion.
|
|
|
|
// Substring filter types
|
|
|
|
#define LDAP_SUBSTRING_INITIAL 0x80L // class context specific
|
|
#define LDAP_SUBSTRING_ANY 0x81L // class context specific
|
|
#define LDAP_SUBSTRING_FINAL 0x82L // class context specific
|
|
|
|
//
|
|
// Possible values for ld_deref field.
|
|
// "Never" - never deref aliases. return only the alias.
|
|
// "Searching" - only deref aliases when searching, not when locating
|
|
// the base object of a search.
|
|
// "Finding" - dereference the alias when locating the base object but
|
|
// not during a search.
|
|
// "Always" - always dereference aliases.
|
|
//
|
|
|
|
#define LDAP_DEREF_NEVER 0
|
|
#define LDAP_DEREF_SEARCHING 1
|
|
#define LDAP_DEREF_FINDING 2
|
|
#define LDAP_DEREF_ALWAYS 3
|
|
|
|
// Special values for ld_sizelimit :
|
|
|
|
#define LDAP_NO_LIMIT 0
|
|
|
|
// Flags for ld_options field :
|
|
|
|
#define LDAP_OPT_DNS 0x00000001 // utilize DN & DNS
|
|
#define LDAP_OPT_CHASE_REFERRALS 0x00000002 // chase referrals
|
|
#define LDAP_OPT_RETURN_REFS 0x00000004 // return referrals to calling app
|
|
|
|
//
|
|
// LDAP structure per connection
|
|
//
|
|
|
|
#if !defined(_WIN64)
|
|
#pragma pack(push, 4)
|
|
#endif
|
|
|
|
typedef struct ldap {
|
|
|
|
struct {
|
|
|
|
UINT_PTR sb_sd;
|
|
|
|
UCHAR Reserved1[(10*sizeof(ULONG))+1];
|
|
|
|
ULONG_PTR sb_naddr; // notzero implies CLDAP available
|
|
|
|
UCHAR Reserved2[(6*sizeof(ULONG))];
|
|
|
|
} ld_sb;
|
|
|
|
//
|
|
// Following parameters MAY match up to reference implementation of LDAP
|
|
//
|
|
|
|
PCHAR ld_host;
|
|
ULONG ld_version;
|
|
UCHAR ld_lberoptions;
|
|
|
|
//
|
|
// Safe to assume that these parameters are in same location as
|
|
// reference implementation of LDAP API.
|
|
//
|
|
|
|
ULONG ld_deref;
|
|
|
|
ULONG ld_timelimit;
|
|
ULONG ld_sizelimit;
|
|
|
|
ULONG ld_errno;
|
|
PCHAR ld_matched;
|
|
PCHAR ld_error;
|
|
ULONG ld_msgid;
|
|
|
|
UCHAR Reserved3[(6*sizeof(ULONG))+1];
|
|
|
|
//
|
|
// Following parameters may match up to reference implementation of LDAP API.
|
|
//
|
|
|
|
ULONG ld_cldaptries;
|
|
ULONG ld_cldaptimeout;
|
|
ULONG ld_refhoplimit;
|
|
ULONG ld_options;
|
|
|
|
} LDAP, * PLDAP;
|
|
|
|
//
|
|
// Our timeval structure is a bit different from the reference implementation
|
|
// since Win32 defines a _timeval structure that is different from the LDAP
|
|
// one.
|
|
//
|
|
|
|
typedef struct l_timeval {
|
|
LONG tv_sec;
|
|
LONG tv_usec;
|
|
} LDAP_TIMEVAL, * PLDAP_TIMEVAL;
|
|
|
|
//
|
|
// The berval structure is used to pass in any arbitrary octet string. It
|
|
// is useful for attributes that cannot be represented using a null
|
|
// terminated string.
|
|
//
|
|
|
|
typedef struct berval {
|
|
ULONG bv_len;
|
|
PCHAR bv_val;
|
|
} LDAP_BERVAL, * PLDAP_BERVAL, BERVAL, * PBERVAL;
|
|
|
|
//
|
|
// The following structure has to be compatible with reference implementation.
|
|
//
|
|
|
|
typedef struct ldapmsg {
|
|
|
|
ULONG lm_msgid; // message number for given connection
|
|
ULONG lm_msgtype; // message type of the form LDAP_RES_xxx
|
|
|
|
PVOID lm_ber; // ber form of message
|
|
|
|
struct ldapmsg *lm_chain; // pointer to next result value
|
|
struct ldapmsg *lm_next; // pointer to next message
|
|
ULONG lm_time;
|
|
|
|
//
|
|
// new fields below not in reference implementation
|
|
//
|
|
|
|
PLDAP Connection; // connection from which we received response
|
|
PVOID Request; // owning request (opaque structure)
|
|
ULONG lm_returncode; // server's return code
|
|
USHORT lm_referral; // index of referral within ref table
|
|
BOOLEAN lm_chased; // has referral been chased already?
|
|
BOOLEAN lm_eom; // is this the last entry for this message?
|
|
BOOLEAN ConnectionReferenced; // is the Connection still valid?
|
|
|
|
} LDAPMessage, *PLDAPMessage;
|
|
|
|
//
|
|
// Controls... there are three types :
|
|
//
|
|
// 1) those passed to the server
|
|
// 2) those passed to the client and handled by the client API
|
|
// 3) those returned by the server
|
|
//
|
|
|
|
typedef struct ldapcontrolA {
|
|
|
|
PCHAR ldctl_oid;
|
|
struct berval ldctl_value;
|
|
BOOLEAN ldctl_iscritical;
|
|
|
|
} LDAPControlA, *PLDAPControlA;
|
|
|
|
typedef struct ldapcontrolW {
|
|
|
|
PWCHAR ldctl_oid;
|
|
struct berval ldctl_value;
|
|
BOOLEAN ldctl_iscritical;
|
|
|
|
} LDAPControlW, *PLDAPControlW;
|
|
|
|
#if LDAP_UNICODE
|
|
#define LDAPControl LDAPControlW
|
|
#define PLDAPControl PLDAPControlW
|
|
#else
|
|
#define LDAPControl LDAPControlA
|
|
#define PLDAPControl PLDAPControlA
|
|
#endif
|
|
|
|
//
|
|
// Client controls section : these are the client controls that wldap32.dll
|
|
// supports.
|
|
//
|
|
// If you specify LDAP_CONTROL_REFERRALS in a control, the value field should
|
|
// point to a ULONG of the following flags :
|
|
//
|
|
// LDAP_CHASE_SUBORDINATE_REFERRALS
|
|
// LDAP_CHASE_EXTERNAL_REFERRALS
|
|
//
|
|
|
|
#define LDAP_CONTROL_REFERRALS_W L"1.2.840.113556.1.4.616"
|
|
#define LDAP_CONTROL_REFERRALS "1.2.840.113556.1.4.616"
|
|
|
|
//
|
|
// Values required for Modification command These are options for the
|
|
// mod_op field of LDAPMod structure
|
|
//
|
|
|
|
#define LDAP_MOD_ADD 0x00
|
|
#define LDAP_MOD_DELETE 0x01
|
|
#define LDAP_MOD_REPLACE 0x02
|
|
#define LDAP_MOD_BVALUES 0x80 // AND in this flag if berval structure used
|
|
|
|
typedef struct ldapmodW {
|
|
ULONG mod_op;
|
|
PWCHAR mod_type;
|
|
union {
|
|
PWCHAR *modv_strvals;
|
|
struct berval **modv_bvals;
|
|
} mod_vals;
|
|
} LDAPModW, *PLDAPModW;
|
|
|
|
typedef struct ldapmodA {
|
|
ULONG mod_op;
|
|
PCHAR mod_type;
|
|
union {
|
|
PCHAR *modv_strvals;
|
|
struct berval **modv_bvals;
|
|
} mod_vals;
|
|
} LDAPModA, *PLDAPModA;
|
|
|
|
#if LDAP_UNICODE
|
|
#define LDAPMod LDAPModW
|
|
#define PLDAPMod PLDAPModW
|
|
#else
|
|
#define LDAPMod LDAPModA
|
|
#define PLDAPMod PLDAPModA
|
|
#endif
|
|
|
|
#if !defined(_WIN64)
|
|
#pragma pack(pop)
|
|
#endif
|
|
|
|
//
|
|
// macros compatible with reference implementation...
|
|
//
|
|
|
|
#define LDAP_IS_CLDAP( ld ) ( (ld)->ld_sb.sb_naddr > 0 )
|
|
#define mod_values mod_vals.modv_strvals
|
|
#define mod_bvalues mod_vals.modv_bvals
|
|
#define NAME_ERROR(n) ((n & 0xf0) == 0x20)
|
|
|
|
//
|
|
// function definitions for LDAP API
|
|
//
|
|
|
|
//
|
|
// Create a connection block to an LDAP server. HostName can be NULL, in
|
|
// which case we'll try to go off and find the "default" LDAP server.
|
|
//
|
|
// Note that if we have to go off and find the default server, we'll pull
|
|
// in NETAPI32.DLL and ADVAPI32.DLL.
|
|
//
|
|
// If it returns NULL, an error occurred. Pick up error code with
|
|
// GetLastError().
|
|
//
|
|
// ldap_open actually opens the connection at the time of the call,
|
|
// whereas ldap_init only opens the connection when an operation is performed
|
|
// that requires it.
|
|
//
|
|
// multi-thread: ldap_open*, ldap_init*, and ldap_sslinit* calls are safe.
|
|
//
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_openW( const PWCHAR HostName, ULONG PortNumber );
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_openA( const PCHAR HostName, ULONG PortNumber );
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_initW( const PWCHAR HostName, ULONG PortNumber );
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_initA( const PCHAR HostName, ULONG PortNumber );
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_sslinitW( PWCHAR HostName, ULONG PortNumber, int secure );
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_sslinitA( PCHAR HostName, ULONG PortNumber, int secure );
|
|
|
|
//
|
|
// when calling ldap_init, you can call ldap_connect explicitly to have the
|
|
// library contact the server. This is useful for checking for server
|
|
// availability. This call is not required however, since the other functions
|
|
// will call it internally if it hasn't already been called.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_connect( LDAP *ld,
|
|
struct l_timeval *timeout
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_open ldap_openW
|
|
#define ldap_init ldap_initW
|
|
#define ldap_sslinit ldap_sslinitW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_open( PCHAR HostName, ULONG PortNumber );
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_init( PCHAR HostName, ULONG PortNumber );
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_sslinit( PCHAR HostName, ULONG PortNumber, int secure );
|
|
|
|
#endif
|
|
|
|
//
|
|
// This is similar to ldap_open except it creates a connection block for
|
|
// UDP based Connectionless LDAP services. No TCP session is maintained.
|
|
//
|
|
// If it returns NULL, an error occurred. Pick up error code with
|
|
// GetLastError().
|
|
//
|
|
// multi-thread: cldap_open* calls are safe.
|
|
//
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI cldap_openW( PWCHAR HostName, ULONG PortNumber );
|
|
WINLDAPAPI LDAP * LDAPAPI cldap_openA( PCHAR HostName, ULONG PortNumber );
|
|
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define cldap_open cldap_openW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI cldap_open( PCHAR HostName, ULONG PortNumber );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
// Call unbind when you're done with the connection, it will free all
|
|
// resources associated with the connection.
|
|
//
|
|
// There is no ldap_close... use ldap_unbind even if you haven't called
|
|
// ldap_bind on the connection.
|
|
//
|
|
// multi-thread: ldap_unbind* calls are safe EXCEPT don't use the LDAP *
|
|
// stucture after it's been freed.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_unbind( LDAP *ld );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_unbind_s( LDAP *ld ); // calls ldap_unbind
|
|
|
|
//
|
|
// Calls to get and set options on connection blocks... use them rather
|
|
// than modifying the LDAP block directly.
|
|
//
|
|
//
|
|
// multi-thread: ldap_get_option is safe
|
|
// multi-thread: ldap_set_option is not safe in that it affects the
|
|
// connection as a whole. beware if threads share connections.
|
|
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_get_option( LDAP *ld, int option, void *outvalue );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_get_optionW( LDAP *ld, int option, void *outvalue );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_set_option( LDAP *ld, int option, const void *invalue );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_set_optionW( LDAP *ld, int option, const void *invalue );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_get_option ldap_get_optionW
|
|
#define ldap_set_option ldap_set_optionW
|
|
|
|
#endif
|
|
|
|
//
|
|
// These are the values to pass to ldap_get/set_option :
|
|
//
|
|
|
|
#define LDAP_OPT_DESC 0x01
|
|
#define LDAP_OPT_DEREF 0x02
|
|
#define LDAP_OPT_SIZELIMIT 0x03
|
|
#define LDAP_OPT_TIMELIMIT 0x04
|
|
#define LDAP_OPT_THREAD_FN_PTRS 0x05
|
|
#define LDAP_OPT_REBIND_FN 0x06
|
|
#define LDAP_OPT_REBIND_ARG 0x07
|
|
#define LDAP_OPT_REFERRALS 0x08
|
|
#define LDAP_OPT_RESTART 0x09
|
|
|
|
#define LDAP_OPT_SSL 0x0a
|
|
#define LDAP_OPT_IO_FN_PTRS 0x0b
|
|
#define LDAP_OPT_CACHE_FN_PTRS 0x0d
|
|
#define LDAP_OPT_CACHE_STRATEGY 0x0e
|
|
#define LDAP_OPT_CACHE_ENABLE 0x0f
|
|
#define LDAP_OPT_REFERRAL_HOP_LIMIT 0x10
|
|
|
|
#define LDAP_OPT_PROTOCOL_VERSION 0x11 // known by two names.
|
|
#define LDAP_OPT_VERSION 0x11
|
|
|
|
//
|
|
// These are new ones that we've defined, not in current RFC draft.
|
|
//
|
|
|
|
#define LDAP_OPT_HOST_NAME 0x30
|
|
#define LDAP_OPT_ERROR_NUMBER 0x31
|
|
#define LDAP_OPT_ERROR_STRING 0x32
|
|
#define LDAP_OPT_SERVER_ERROR 0x33
|
|
#define LDAP_OPT_SERVER_EXT_ERROR 0x34
|
|
#define LDAP_OPT_HOST_REACHABLE 0x3E
|
|
|
|
//
|
|
// These options control the keep-alive logic. Keep alives are sent as
|
|
// ICMP ping messages (which currently don't go through firewalls).
|
|
//
|
|
// There are three values that control how this works :
|
|
// PING_KEEP_ALIVE : min number of seconds since we last received a response
|
|
// from the server before we send a keep-alive ping
|
|
// PING_WAIT_TIME : number of milliseconds we wait for the response to
|
|
// come back when we send a ping
|
|
// PING_LIMIT : number of unanswered pings we send before we close the
|
|
// connection.
|
|
//
|
|
// To disable the keep-alive logic, set any of the values (PING_KEEP_ALIVE,
|
|
// PING_LIMIT, or PING_WAIT_TIME) to zero.
|
|
//
|
|
// The current default/min/max for these values are as follows :
|
|
//
|
|
// PING_KEEP_ALIVE : 120/5/maxInt seconds (may also be zero)
|
|
// PING_WAIT_TIME : 2000/10/60000 milliseconds (may also be zero)
|
|
// PING_LIMIT : 4/0/maxInt
|
|
//
|
|
|
|
#define LDAP_OPT_PING_KEEP_ALIVE 0x36
|
|
#define LDAP_OPT_PING_WAIT_TIME 0x37
|
|
#define LDAP_OPT_PING_LIMIT 0x38
|
|
|
|
//
|
|
// These won't be in the RFC. Only use these if you're going to be dependent
|
|
// on our implementation.
|
|
//
|
|
|
|
#define LDAP_OPT_DNSDOMAIN_NAME 0x3B // return DNS name of domain
|
|
#define LDAP_OPT_GETDSNAME_FLAGS 0x3D // flags for DsGetDcName
|
|
|
|
#define LDAP_OPT_PROMPT_CREDENTIALS 0x3F // prompt for creds? currently
|
|
// only for DPA & NTLM if no creds
|
|
// are loaded
|
|
|
|
#define LDAP_OPT_AUTO_RECONNECT 0x91 // enable/disable autoreconnect
|
|
#define LDAP_OPT_SSPI_FLAGS 0x92 // flags to pass to InitSecurityContext
|
|
|
|
//
|
|
// To retrieve information on an secure connection, a pointer to a
|
|
// SecPkgContext_connectionInfo structure (defined in schnlsp.h) must be
|
|
// passed in. On success, it is filled with relevent security information.
|
|
//
|
|
|
|
#define LDAP_OPT_SSL_INFO 0x93
|
|
|
|
//
|
|
// Turing on either the sign or the encrypt option prior to binding using
|
|
// LDAP_AUTH_NEGOTIATE will result in the ensuing LDAP session to be signed
|
|
// or encrypted using either Kerberos or NTLM (as negotiated by the underlying
|
|
// security packages). Note that these options can't be used with SSL.
|
|
//
|
|
|
|
#define LDAP_OPT_SIGN 0x95
|
|
#define LDAP_OPT_ENCRYPT 0x96
|
|
|
|
//
|
|
// The user can set a preferred SASL method prior to binding using LDAP_AUTH_NEGOTIATE
|
|
// We will try to use this mechanism while binding. One example is "GSSAPI".
|
|
//
|
|
|
|
#define LDAP_OPT_SASL_METHOD 0x97
|
|
|
|
//
|
|
// Setting this option to LDAP_OPT_ON will instruct the library to only perform an
|
|
// A-Record DNS lookup on the supplied host string. This option is OFF by default.
|
|
//
|
|
|
|
#define LDAP_OPT_AREC_EXCLUSIVE 0x98
|
|
|
|
//
|
|
// Retrieve the security context associated with the connection.
|
|
//
|
|
|
|
#define LDAP_OPT_SECURITY_CONTEXT 0x99
|
|
|
|
//
|
|
// End of Microsoft only options
|
|
//
|
|
|
|
#define LDAP_OPT_ON ((void *) 1)
|
|
#define LDAP_OPT_OFF ((void *) 0)
|
|
|
|
//
|
|
// For chasing referrals, we extend this a bit for LDAP_OPT_REFERRALS. If
|
|
// the value is not LDAP_OPT_ON or LDAP_OPT_OFF, we'll treat them as the
|
|
// following :
|
|
//
|
|
// LDAP_CHASE_SUBORDINATE_REFERRALS : chase subordinate referrals (or
|
|
// references) returned in a v3 search
|
|
// LDAP_CHASE_EXTERNAL_REFERRALS : chase external referrals. These are
|
|
// returned possibly on any operation except bind.
|
|
//
|
|
// If you OR these flags together, it's equivalent to setting referrals to
|
|
// LDAP_OPT_ON.
|
|
//
|
|
|
|
#define LDAP_CHASE_SUBORDINATE_REFERRALS 0x00000020
|
|
#define LDAP_CHASE_EXTERNAL_REFERRALS 0x00000040
|
|
|
|
//
|
|
// Bind is required as the first operation to v2 servers, not so for v3
|
|
// servers. See above description of authentication methods.
|
|
//
|
|
// multi-thread: bind calls are not safe in that it affects the
|
|
// connection as a whole. beware if threads share connections
|
|
// and try to mulithread binds with other operations.
|
|
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bindW( LDAP *ld, PWCHAR dn, PWCHAR passwd );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bindA( LDAP *ld, PCHAR dn, PCHAR passwd );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bind_sW( LDAP *ld, PWCHAR dn, PWCHAR passwd );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bind_sA( LDAP *ld, PCHAR dn, PCHAR passwd );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bindW( LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bindA( LDAP *ld, PCHAR dn, PCHAR cred, ULONG method );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bind_sW( LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bind_sA( LDAP *ld, PCHAR dn, PCHAR cred, ULONG method );
|
|
|
|
|
|
//
|
|
// The following functions can be used to pass in any arbitrary credentials
|
|
// to the server. The application must be ready to interpret the response
|
|
// sent back from the server.
|
|
//
|
|
|
|
WINLDAPAPI INT LDAPAPI ldap_sasl_bindA(
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistName,
|
|
const PCHAR AuthMechanism,
|
|
const BERVAL *cred,
|
|
PLDAPControlA *ServerCtrls,
|
|
PLDAPControlA *ClientCtrls,
|
|
int *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI INT LDAPAPI ldap_sasl_bindW(
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistName,
|
|
const PWCHAR AuthMechanism,
|
|
const BERVAL *cred,
|
|
PLDAPControlW *ServerCtrls,
|
|
PLDAPControlW *ClientCtrls,
|
|
int *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI INT LDAPAPI ldap_sasl_bind_sA(
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistName,
|
|
const PCHAR AuthMechanism,
|
|
const BERVAL *cred,
|
|
PLDAPControlA *ServerCtrls,
|
|
PLDAPControlA *ClientCtrls,
|
|
PBERVAL *ServerData
|
|
);
|
|
|
|
WINLDAPAPI INT LDAPAPI ldap_sasl_bind_sW(
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistName,
|
|
const PWCHAR AuthMechanism,
|
|
const BERVAL *cred,
|
|
PLDAPControlW *ServerCtrls,
|
|
PLDAPControlW *ClientCtrls,
|
|
PBERVAL *ServerData
|
|
);
|
|
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_simple_bind ldap_simple_bindW
|
|
#define ldap_simple_bind_s ldap_simple_bind_sW
|
|
|
|
#define ldap_bind ldap_bindW
|
|
#define ldap_bind_s ldap_bind_sW
|
|
|
|
#define ldap_sasl_bind ldap_sasl_bindW
|
|
#define ldap_sasl_bind_s ldap_sasl_bind_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bind( LDAP *ld, const PCHAR dn, const PCHAR passwd );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_simple_bind_s( LDAP *ld, const PCHAR dn, const PCHAR passwd );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bind( LDAP *ld, const PCHAR dn, const PCHAR cred, ULONG method );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_bind_s( LDAP *ld, const PCHAR dn, const PCHAR cred, ULONG method );
|
|
|
|
#define ldap_sasl_bind ldap_sasl_bindA
|
|
#define ldap_sasl_bind_s ldap_sasl_bind_sA
|
|
|
|
#endif
|
|
|
|
//
|
|
// Synchronous and asynch search routines.
|
|
//
|
|
// filter follows RFC 1960 with the addition that '(' ')' '*' ' ' '\' and
|
|
// '\0' are all escaped with '\'
|
|
//
|
|
// Scope of search. This corresponds to the "scope" parameter on search
|
|
|
|
#define LDAP_SCOPE_BASE 0x00
|
|
#define LDAP_SCOPE_ONELEVEL 0x01
|
|
#define LDAP_SCOPE_SUBTREE 0x02
|
|
|
|
//
|
|
// multi-thread: ldap_search calls are not safe in that the message number
|
|
// is returned rather than the return code. You have to look
|
|
// at the connection block in an error case and the return code
|
|
// may be overwritten by another thread inbetween.
|
|
//
|
|
// Use ldap_search_ext instead, as these are thread safe.
|
|
//
|
|
// ldap_search_s and ldap_search_ext* calls are thread safe.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_searchW(
|
|
LDAP *ld,
|
|
const PWCHAR base, // distinguished name or ""
|
|
ULONG scope, // LDAP_SCOPE_xxxx
|
|
const PWCHAR filter,
|
|
PWCHAR attrs[], // pointer to an array of PCHAR attribute names
|
|
ULONG attrsonly // boolean on whether to only return attr names
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_searchA(
|
|
LDAP *ld,
|
|
const PCHAR base, // distinguished name or ""
|
|
ULONG scope, // LDAP_SCOPE_xxxx
|
|
const PCHAR filter,
|
|
PCHAR attrs[], // pointer to an array of PCHAR attribute names
|
|
ULONG attrsonly // boolean on whether to only return attr names
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_sW(
|
|
LDAP *ld,
|
|
const PWCHAR base,
|
|
ULONG scope,
|
|
const PWCHAR filter,
|
|
PWCHAR attrs[],
|
|
ULONG attrsonly,
|
|
LDAPMessage **res
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_sA(
|
|
LDAP *ld,
|
|
const PCHAR base,
|
|
ULONG scope,
|
|
const PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_stW(
|
|
LDAP *ld,
|
|
const PWCHAR base,
|
|
ULONG scope,
|
|
const PWCHAR filter,
|
|
PWCHAR attrs[],
|
|
ULONG attrsonly,
|
|
struct l_timeval *timeout,
|
|
LDAPMessage **res
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_stA(
|
|
LDAP *ld,
|
|
const PCHAR base,
|
|
ULONG scope,
|
|
const PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
struct l_timeval *timeout,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_extW(
|
|
LDAP *ld,
|
|
const PWCHAR base,
|
|
ULONG scope,
|
|
const PWCHAR filter,
|
|
PWCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG TimeLimit,
|
|
ULONG SizeLimit,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_extA(
|
|
LDAP *ld,
|
|
const PCHAR base,
|
|
ULONG scope,
|
|
const PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG TimeLimit,
|
|
ULONG SizeLimit,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR base,
|
|
ULONG scope,
|
|
const PWCHAR filter,
|
|
PWCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
struct l_timeval *timeout,
|
|
ULONG SizeLimit,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR base,
|
|
ULONG scope,
|
|
const PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
struct l_timeval *timeout,
|
|
ULONG SizeLimit,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_search ldap_searchW
|
|
#define ldap_search_s ldap_search_sW
|
|
#define ldap_search_st ldap_search_stW
|
|
|
|
#define ldap_search_ext ldap_search_extW
|
|
#define ldap_search_ext_s ldap_search_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search(
|
|
LDAP *ld,
|
|
PCHAR base, // distinguished name or ""
|
|
ULONG scope, // LDAP_SCOPE_xxxx
|
|
PCHAR filter,
|
|
PCHAR attrs[], // pointer to an array of PCHAR attribute names
|
|
ULONG attrsonly // boolean on whether to only return attr names
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_s(
|
|
LDAP *ld,
|
|
PCHAR base,
|
|
ULONG scope,
|
|
PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_st(
|
|
LDAP *ld,
|
|
PCHAR base,
|
|
ULONG scope,
|
|
PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
struct l_timeval *timeout,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_ext(
|
|
LDAP *ld,
|
|
PCHAR base,
|
|
ULONG scope,
|
|
PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG TimeLimit,
|
|
ULONG SizeLimit,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_ext_s(
|
|
LDAP *ld,
|
|
PCHAR base,
|
|
ULONG scope,
|
|
PCHAR filter,
|
|
PCHAR attrs[],
|
|
ULONG attrsonly,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
struct l_timeval *timeout,
|
|
ULONG SizeLimit,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Extended API to check filter syntax. Returns LDAP error code if syntax
|
|
// is invalid or LDAP_SUCCESS if it's ok.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI
|
|
ldap_check_filterW(
|
|
LDAP *ld,
|
|
PWCHAR SearchFilter
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI
|
|
ldap_check_filterA(
|
|
LDAP *ld,
|
|
PCHAR SearchFilter
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
#define ldap_check_filter ldap_check_filterW
|
|
#else
|
|
#define ldap_check_filter ldap_check_filterA
|
|
#endif
|
|
|
|
|
|
//
|
|
// modify an existing entry
|
|
//
|
|
|
|
//
|
|
// multi-thread: ldap_modify calls are not safe in that the message number
|
|
// is returned rather than the return code. You have to look
|
|
// at the connection block in an error case and the return code
|
|
// may be overwritten by another thread inbetween.
|
|
//
|
|
// Use ldap_modify_ext instead, as these are thread safe.
|
|
//
|
|
// ldap_modify_s and ldap_modify_ext* calls are thread safe.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modifyW( LDAP *ld, PWCHAR dn, LDAPModW *mods[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modifyA( LDAP *ld, PCHAR dn, LDAPModA *mods[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_sW( LDAP *ld, PWCHAR dn, LDAPModW *mods[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_sA( LDAP *ld, PCHAR dn, LDAPModA *mods[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_extW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
LDAPModW *mods[],
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_extA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *mods[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
LDAPModW *mods[],
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *mods[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_modify ldap_modifyW
|
|
#define ldap_modify_s ldap_modify_sW
|
|
|
|
#define ldap_modify_ext ldap_modify_extW
|
|
#define ldap_modify_ext_s ldap_modify_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify( LDAP *ld, PCHAR dn, LDAPModA *mods[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_s( LDAP *ld, PCHAR dn, LDAPModA *mods[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_ext(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *mods[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modify_ext_s(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *mods[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// modrdn and modrdn2 function both as RenameObject and MoveObject.
|
|
//
|
|
// Note that to LDAP v2 servers, only rename within a given container
|
|
// is supported... therefore NewDistinguishedName is actually NewRDN.
|
|
// Here are some examples :
|
|
//
|
|
// This works to both v2 and v3 servers :
|
|
//
|
|
// DN = CN=Bob,OU=FOO,O=BAR
|
|
// NewDN = CN=Joe
|
|
//
|
|
// result is: CN=Joe,OU=FOO,O=BAR
|
|
//
|
|
// This works to only v3 and above servers :
|
|
//
|
|
// DN = CN=Bob,OU=FOO,O=BAR
|
|
// NewDN = CN=Joe,OU=FOOBAR,O=BAR
|
|
//
|
|
// result is: CN=Joe,OU=FOOBAR,O=BAR
|
|
//
|
|
// If you try the second example to a v2 server, we'll send the whole
|
|
// NewDN over as the new RDN (rather than break up the parent OU and
|
|
// child). The server will then give you back some unknown error.
|
|
//
|
|
|
|
//
|
|
// multi-thread: ldap_modrdn and ldap_modrdn2 calls are not safe in that
|
|
// the message number is returned rather than the return code.
|
|
// You have to look at the connection block in an error case
|
|
// and the return code may be overwritten by another thread
|
|
// inbetween.
|
|
//
|
|
// Use ldap_rename_ext instead, as these are thread safe.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2W (
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistinguishedName,
|
|
const PWCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2A (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
|
|
//
|
|
// ldap_modrdn simply calls ldap_modrdn2 with a value of 1 for DeleteOldRdn.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdnW (
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistinguishedName,
|
|
const PWCHAR NewDistinguishedName
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdnA (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2_sW (
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistinguishedName,
|
|
const PWCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2_sA (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn_sW (
|
|
LDAP *ExternalHandle,
|
|
const PWCHAR DistinguishedName,
|
|
const PWCHAR NewDistinguishedName
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn_sA (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_modrdn2 ldap_modrdn2W
|
|
#define ldap_modrdn ldap_modrdnW
|
|
#define ldap_modrdn2_s ldap_modrdn2_sW
|
|
#define ldap_modrdn_s ldap_modrdn_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2 (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn2_s (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName,
|
|
INT DeleteOldRdn
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_modrdn_s (
|
|
LDAP *ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
const PCHAR NewDistinguishedName
|
|
);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Extended Rename operations. These take controls and separate out the
|
|
// parent from the RDN, for clarity.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_extW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
const PWCHAR NewRDN,
|
|
const PWCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_extA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR NewRDN,
|
|
const PCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
const PWCHAR NewRDN,
|
|
const PWCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR NewRDN,
|
|
const PCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_rename ldap_rename_extW
|
|
#define ldap_rename_s ldap_rename_ext_sW
|
|
|
|
#else
|
|
|
|
#define ldap_rename ldap_rename_extA
|
|
#define ldap_rename_s ldap_rename_ext_sA
|
|
|
|
#endif
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_rename_ext ldap_rename_extW
|
|
#define ldap_rename_ext_s ldap_rename_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_ext(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR NewRDN,
|
|
const PCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_rename_ext_s(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR NewRDN,
|
|
const PCHAR NewParent,
|
|
INT DeleteOldRdn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Add an entry to the tree
|
|
//
|
|
|
|
//
|
|
// multi-thread: ldap_add calls are not safe in that the message number
|
|
// is returned rather than the return code. You have to look
|
|
// at the connection block in an error case and the return code
|
|
// may be overwritten by another thread inbetween.
|
|
//
|
|
// Use ldap_add_ext instead, as these are thread safe.
|
|
//
|
|
// ldap_add_s and ldap_add_ext* calls are thread safe.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_addW( LDAP *ld, PWCHAR dn, LDAPModW *attrs[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_addA( LDAP *ld, PCHAR dn, LDAPModA *attrs[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_sW( LDAP *ld, PWCHAR dn, LDAPModW *attrs[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_sA( LDAP *ld, PCHAR dn, LDAPModA *attrs[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_extW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
LDAPModW *attrs[],
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_extA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *attrs[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
LDAPModW *attrs[],
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *attrs[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_add ldap_addW
|
|
#define ldap_add_s ldap_add_sW
|
|
|
|
#define ldap_add_ext ldap_add_extW
|
|
#define ldap_add_ext_s ldap_add_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add( LDAP *ld, PCHAR dn, LDAPMod *attrs[] );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_s( LDAP *ld, PCHAR dn, LDAPMod *attrs[] );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_ext(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *attrs[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_add_ext_s(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
LDAPModA *attrs[],
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// Compare the attribute for a given entry to a known value.
|
|
//
|
|
|
|
//
|
|
// multi-thread: ldap_compare calls are not safe in that the message number
|
|
// is returned rather than the return code. You have to look
|
|
// at the connection block in an error case and the return code
|
|
// may be overwritten by another thread inbetween.
|
|
//
|
|
// Use ldap_compare_ext instead, as these are thread safe.
|
|
//
|
|
// ldap_compare_s and ldap_compare_ext* calls are thread safe.
|
|
//
|
|
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compareW( LDAP *ld, const PWCHAR dn, const PWCHAR attr, PWCHAR value );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compareA( LDAP *ld, const PCHAR dn, const PCHAR attr, PCHAR value );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_sW( LDAP *ld, const PWCHAR dn, const PWCHAR attr, PWCHAR value );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_sA( LDAP *ld, const PCHAR dn, const PCHAR attr, PCHAR value );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_compare ldap_compareW
|
|
#define ldap_compare_s ldap_compare_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare( LDAP *ld, const PCHAR dn, const PCHAR attr, PCHAR value );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_s( LDAP *ld, const PCHAR dn, const PCHAR attr, PCHAR value );
|
|
|
|
#endif
|
|
|
|
//
|
|
// Extended Compare operations. These take controls and are thread safe.
|
|
// They also allow you to specify a bval structure for the data, so that it
|
|
// isn't translated from Unicode or ANSI to UTF8. Allows for comparison of
|
|
// raw binary data.
|
|
//
|
|
// Specify either Data or Value as not NULL. If both are not NULL, the
|
|
// berval Data will be used.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_extW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
const PWCHAR Attr,
|
|
const PWCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_extA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR Attr,
|
|
const PCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
const PWCHAR Attr,
|
|
const PWCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR Attr,
|
|
const PCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_compare_ext ldap_compare_extW
|
|
#define ldap_compare_ext_s ldap_compare_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_ext(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR Attr,
|
|
const PCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_compare_ext_s(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
const PCHAR Attr,
|
|
const PCHAR Value, // either value or Data is not null, not both
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
#endif
|
|
|
|
|
|
//
|
|
// Delete an object out of the tree
|
|
//
|
|
|
|
//
|
|
// multi-thread: ldap_delete calls are not safe in that the message number
|
|
// is returned rather than the return code. You have to look
|
|
// at the connection block in an error case and the return code
|
|
// may be overwritten by another thread inbetween.
|
|
//
|
|
// Use ldap_delete_ext instead, as these are thread safe.
|
|
//
|
|
// ldap_delete_s and ldap_delete_ext* calls are thread safe.
|
|
//
|
|
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_deleteW( LDAP *ld, const PWCHAR dn );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_deleteA( LDAP *ld, const PCHAR dn );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_sW( LDAP *ld, const PWCHAR dn );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_sA( LDAP *ld, const PCHAR dn );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_extW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_extA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_ext_sW(
|
|
LDAP *ld,
|
|
const PWCHAR dn,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_ext_sA(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_delete ldap_deleteW
|
|
#define ldap_delete_ext ldap_delete_extW
|
|
#define ldap_delete_s ldap_delete_sW
|
|
#define ldap_delete_ext_s ldap_delete_ext_sW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete( LDAP *ld, PCHAR dn );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_s( LDAP *ld, PCHAR dn );
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_ext(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_delete_ext_s(
|
|
LDAP *ld,
|
|
const PCHAR dn,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls
|
|
);
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
// Give up on a request. No guarentee that it got there as there is no
|
|
// response from the server.
|
|
//
|
|
|
|
// multi-thread: ldap_abandon calls are thread safe
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_abandon( LDAP *ld, ULONG msgid );
|
|
|
|
|
|
|
|
//
|
|
// Possible values for "all" field in ldap_result. We've enhanced it such
|
|
// that if someone passes in LDAP_MSG_RECEIVED, we'll pass all values we've
|
|
// received up to that point.
|
|
//
|
|
|
|
#define LDAP_MSG_ONE 0
|
|
#define LDAP_MSG_ALL 1
|
|
#define LDAP_MSG_RECEIVED 2
|
|
|
|
//
|
|
// Get a response from a connection. One enhancement here is that ld can
|
|
// be null, in which case we'll return responses from any server. Free
|
|
// responses here with ldap_msgfree.
|
|
//
|
|
// For connection-less LDAP, you should pass in both a LDAP connection
|
|
// handle and a msgid. This will ensure we know which request the app
|
|
// is waiting on a reply to. ( we actively resend request until we get
|
|
// a response.)
|
|
//
|
|
|
|
// multi-thread: ldap_result calls are thread safe
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_result(
|
|
LDAP *ld,
|
|
ULONG msgid,
|
|
ULONG all,
|
|
struct l_timeval *timeout,
|
|
LDAPMessage **res
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_msgfree( LDAPMessage *res );
|
|
|
|
//
|
|
// This parses a message and returns the error code. It optionally frees
|
|
// the message by calling ldap_msgfree.
|
|
//
|
|
|
|
// multi-thread: ldap_result2error call is thread safe
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_result2error(
|
|
LDAP *ld,
|
|
LDAPMessage *res,
|
|
ULONG freeit // boolean.. free the message?
|
|
);
|
|
|
|
|
|
//
|
|
// Similar to ldap_result2error, this parses responses from the server and
|
|
// returns the appropriate fields. Use this one if you want to get at the
|
|
// referrals, matchingDNs, or server controls returned.
|
|
//
|
|
|
|
// multi-thread: ldap_parse_result call is thread safe
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_resultW (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
ULONG *ReturnCode OPTIONAL, // returned by server
|
|
PWCHAR *MatchedDNs OPTIONAL, // free with ldap_memfree
|
|
PWCHAR *ErrorMessage OPTIONAL, // free with ldap_memfree
|
|
PWCHAR **Referrals OPTIONAL, // free with ldap_value_freeW
|
|
PLDAPControlW **ServerControls OPTIONAL, // free with ldap_free_controlsW
|
|
BOOLEAN Freeit
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_resultA (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
ULONG *ReturnCode OPTIONAL, // returned by server
|
|
PCHAR *MatchedDNs OPTIONAL, // free with ldap_memfree
|
|
PCHAR *ErrorMessage OPTIONAL, // free with ldap_memfree
|
|
PCHAR **Referrals OPTIONAL, // free with ldap_value_freeA
|
|
PLDAPControlA **ServerControls OPTIONAL, // free with ldap_free_controlsA
|
|
BOOLEAN Freeit
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_extended_resultA (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage, // returned by server
|
|
PCHAR *ResultOID, // free with ldap_memfree
|
|
struct berval **ResultData, // free with ldap_memfree
|
|
BOOLEAN Freeit // Don't need the message anymore
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_extended_resultW (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage, // returned by server
|
|
PWCHAR *ResultOID, // free with ldap_memfree
|
|
struct berval **ResultData, // free with ldap_memfree
|
|
BOOLEAN Freeit // Don't need the message anymore
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_controls_freeA (
|
|
LDAPControlA **Controls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_control_freeA (
|
|
LDAPControlA *Controls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_controls_freeW (
|
|
LDAPControlW **Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_control_freeW (
|
|
LDAPControlW *Control
|
|
);
|
|
|
|
//
|
|
// ldap_free_controls are old, use ldap_controls_free
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_free_controlsW (
|
|
LDAPControlW **Controls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_free_controlsA (
|
|
LDAPControlA **Controls
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_parse_result ldap_parse_resultW
|
|
#define ldap_controls_free ldap_controls_freeW
|
|
#define ldap_control_free ldap_control_freeW
|
|
#define ldap_free_controls ldap_free_controlsW
|
|
#define ldap_parse_extended_result ldap_parse_extended_resultW
|
|
|
|
#else
|
|
|
|
#define ldap_parse_extended_result ldap_parse_extended_resultA
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_result (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
ULONG *ReturnCode OPTIONAL, // returned by server
|
|
PCHAR *MatchedDNs OPTIONAL, // free with ldap_memfree
|
|
PCHAR *ErrorMessage OPTIONAL, // free with ldap_memfree
|
|
PCHAR **Referrals OPTIONAL, // free with ldap_value_free
|
|
PLDAPControlA **ServerControls OPTIONAL, // free with ldap_free_controls
|
|
BOOLEAN Freeit
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_controls_free (
|
|
LDAPControlA **Controls
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_control_free (
|
|
LDAPControlA *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_free_controls (
|
|
LDAPControlA **Controls
|
|
);
|
|
|
|
#endif
|
|
|
|
//
|
|
// ldap_err2string returns a pointer to a string describing the error. This
|
|
// string should not be freed.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR LDAPAPI ldap_err2stringW( ULONG err );
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_err2stringA( ULONG err );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_err2string ldap_err2stringW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_err2string( ULONG err );
|
|
|
|
#endif
|
|
|
|
//
|
|
// ldap_perror does nothing and is here just for compatibility.
|
|
//
|
|
|
|
WINLDAPAPI void LDAPAPI ldap_perror( LDAP *ld, const PCHAR msg );
|
|
|
|
//
|
|
// Return the first entry of a message. It is freed when the message is
|
|
// freed so should not be freed explicitly.
|
|
//
|
|
|
|
WINLDAPAPI LDAPMessage *LDAPAPI ldap_first_entry( LDAP *ld, LDAPMessage *res );
|
|
|
|
//
|
|
// Return the next entry of a message. It is freed when the message is
|
|
// freed so should not be freed explicitly.
|
|
//
|
|
|
|
WINLDAPAPI LDAPMessage *LDAPAPI ldap_next_entry( LDAP *ld, LDAPMessage *entry );
|
|
|
|
//
|
|
// Count the number of search entries returned by the server in a response
|
|
// to a server request.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_entries( LDAP *ld, LDAPMessage *res );
|
|
|
|
//
|
|
// A BerElement really maps out to a C++ class object that does BER encoding.
|
|
// Don't mess with it as it's opaque.
|
|
//
|
|
|
|
typedef struct berelement {
|
|
PCHAR opaque; // this is an opaque structure used just for
|
|
// compatibility with reference implementation
|
|
} BerElement;
|
|
#define NULLBER ((BerElement *) 0)
|
|
|
|
//
|
|
// For a given entry, return the first attribute. The pointer returned is
|
|
// actually a buffer in the connection block (with allowances for
|
|
// multi-threaded apps) so it should not be freed.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR LDAPAPI ldap_first_attributeW(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement **ptr
|
|
);
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_first_attributeA(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement **ptr
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_first_attribute ldap_first_attributeW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_first_attribute(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement **ptr
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Return the next attribute... again, the attribute pointer should not be
|
|
// freed.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR LDAPAPI ldap_next_attributeW(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement *ptr
|
|
);
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_next_attributeA(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement *ptr
|
|
);
|
|
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_next_attribute ldap_next_attributeW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_next_attribute(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
BerElement *ptr
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Get a given attribute's list of values. This is used during parsing of
|
|
// a search response. It returns a list of pointers to values, the list is
|
|
// null terminated.
|
|
//
|
|
// If the values are generic octet strings and not null terminated strings,
|
|
// use ldap_get_values_len instead.
|
|
//
|
|
// The returned value should be freed when your done with it by calling
|
|
// ldap_value_free.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR *LDAPAPI ldap_get_valuesW(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
const PWCHAR attr
|
|
);
|
|
WINLDAPAPI PCHAR *LDAPAPI ldap_get_valuesA(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
const PCHAR attr
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_get_values ldap_get_valuesW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR *LDAPAPI ldap_get_values(
|
|
LDAP *ld,
|
|
LDAPMessage *entry,
|
|
const PCHAR attr
|
|
);
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
// Get a given attribute's list of values. This is used during parsing of
|
|
// a search response. It returns a list of berval structures to values,
|
|
// the list is null terminated.
|
|
//
|
|
// If the values are null terminated strings, it may be easier to process them
|
|
// by calling ldap_get_values instead.
|
|
//
|
|
// The returned value should be freed when your done with it by calling
|
|
// ldap_value_free_len.
|
|
//
|
|
|
|
WINLDAPAPI struct berval **LDAPAPI ldap_get_values_lenW (
|
|
LDAP *ExternalHandle,
|
|
LDAPMessage *Message,
|
|
const PWCHAR attr
|
|
);
|
|
WINLDAPAPI struct berval **LDAPAPI ldap_get_values_lenA (
|
|
LDAP *ExternalHandle,
|
|
LDAPMessage *Message,
|
|
const PCHAR attr
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_get_values_len ldap_get_values_lenW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI struct berval **LDAPAPI ldap_get_values_len (
|
|
LDAP *ExternalHandle,
|
|
LDAPMessage *Message,
|
|
const PCHAR attr
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// Return the number of values in a list returned by ldap_get_values.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_valuesW( PWCHAR *vals );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_valuesA( PCHAR *vals );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_count_values ldap_count_valuesW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_values( PCHAR *vals );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
// Return the number of values in a list returned by ldap_get_values_len.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_values_len( struct berval **vals );
|
|
|
|
//
|
|
// Free structures returned by ldap_get_values.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_value_freeW( PWCHAR *vals );
|
|
WINLDAPAPI ULONG LDAPAPI ldap_value_freeA( PCHAR *vals );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_value_free ldap_value_freeW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_value_free( PCHAR *vals );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
// Free structures returned by ldap_get_values_len.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_value_free_len( struct berval **vals );
|
|
|
|
//
|
|
// Get the distinguished name for a given search entry. It should be freed
|
|
// by calling ldap_memfree.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR LDAPAPI ldap_get_dnW( LDAP *ld, LDAPMessage *entry );
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_get_dnA( LDAP *ld, LDAPMessage *entry );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_get_dn ldap_get_dnW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_get_dn( LDAP *ld, LDAPMessage *entry );
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// When using ldap_explode_dn, you should free the returned string by
|
|
// calling ldap_value_free.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR *LDAPAPI ldap_explode_dnW( const PWCHAR dn, ULONG notypes );
|
|
WINLDAPAPI PCHAR *LDAPAPI ldap_explode_dnA( const PCHAR dn, ULONG notypes );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_explode_dn ldap_explode_dnW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR *LDAPAPI ldap_explode_dn( const PCHAR dn, ULONG notypes );
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// When calling ldap_dn2ufn, you should free the returned string by calling
|
|
// ldap_memfree.
|
|
//
|
|
|
|
WINLDAPAPI PWCHAR LDAPAPI ldap_dn2ufnW( const PWCHAR dn );
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_dn2ufnA( const PCHAR dn );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_dn2ufn ldap_dn2ufnW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PCHAR LDAPAPI ldap_dn2ufn( const PCHAR dn );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
// This is used to free strings back to the LDAP API heap. Don't pass in
|
|
// values that you've gotten from ldap_open, ldap_get_values, etc.
|
|
//
|
|
|
|
WINLDAPAPI VOID LDAPAPI ldap_memfreeW( PWCHAR Block );
|
|
WINLDAPAPI VOID LDAPAPI ldap_memfreeA( PCHAR Block );
|
|
|
|
WINLDAPAPI VOID LDAPAPI ber_bvfree( struct berval *bv );
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_memfree ldap_memfreeW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI VOID LDAPAPI ldap_memfree( PCHAR Block );
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// The function ldap_ufn2dn attempts to "normalize" a user specified DN
|
|
// to make it "proper". It follows RFC 1781 (add CN= if not present,
|
|
// add OU= if none present, etc). If it runs into any problems at all
|
|
// while normalizing, it simply returns a copy of what was passed in.
|
|
//
|
|
// It allocates the output string from the LDAP memory pool. If the pDn
|
|
// comes back as non-NULL, you should free it when you're done with a call
|
|
// to ldap_memfree.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_ufn2dnW (
|
|
const PWCHAR ufn,
|
|
PWCHAR *pDn
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_ufn2dnA (
|
|
const PCHAR ufn,
|
|
PCHAR *pDn
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_ufn2dn ldap_ufn2dnW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_ufn2dn (
|
|
const PCHAR ufn,
|
|
PCHAR *pDn
|
|
);
|
|
|
|
#endif
|
|
|
|
#define LBER_USE_DER 0x01
|
|
#define LBER_USE_INDEFINITE_LEN 0x02
|
|
#define LBER_TRANSLATE_STRINGS 0x04
|
|
|
|
//
|
|
// Call to initialize the LDAP library. Pass in a version structure with
|
|
// lv_size set to sizeof( LDAP_VERSION ), lv_major set to LAPI_MAJOR_VER1,
|
|
// and lv_minor set to LAPI_MINOR_VER1. Return value will be either
|
|
// LDAP_SUCCESS if OK or LDAP_OPERATIONS_ERROR if can't be supported.
|
|
//
|
|
|
|
#define LAPI_MAJOR_VER1 1
|
|
#define LAPI_MINOR_VER1 1
|
|
|
|
typedef struct ldap_version_info {
|
|
ULONG lv_size;
|
|
ULONG lv_major;
|
|
ULONG lv_minor;
|
|
} LDAP_VERSION_INFO, *PLDAP_VERSION_INFO;
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_startup (
|
|
PLDAP_VERSION_INFO version,
|
|
HANDLE *Instance
|
|
);
|
|
|
|
//
|
|
// ldap_cleanup unloads the library when the refcount of opens goes to zero.
|
|
// (i.e. if a DLL calls it within a program that is also using it, it won't
|
|
// free all resources)
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_cleanup (
|
|
HANDLE hInstance
|
|
);
|
|
|
|
//
|
|
// Extended API to support allowing opaque blobs of data in search filters.
|
|
// This API takes any filter element and converts it to a safe text string that
|
|
// can safely be passed in a search filter.
|
|
// An example of using this is :
|
|
//
|
|
// filter is something like guid=4826BF6CF0123444
|
|
// this will put out on the wire guid of binary 0x4826BF6CF0123444
|
|
//
|
|
// call ldap_escape_filter_element with sourceFilterElement pointing to
|
|
// raw data, sourceCount set appropriately to length of data.
|
|
//
|
|
// if destFilterElement is NULL, then return value is length required for
|
|
// output buffer.
|
|
//
|
|
// if destFilterElement is not NULL, then the function will copy the source
|
|
// into the dest buffer and ensure that it is of a safe format.
|
|
//
|
|
// then simply insert the dest buffer into your search filter after the
|
|
// "attributetype=".
|
|
//
|
|
// this will put out on the wire guid of binary 0x004826BF6CF000123444
|
|
//
|
|
// Note : don't call this for attribute values that are really strings, as
|
|
// we won't do any conversion from what you passed in to UTF-8. Should only
|
|
// be used for attributes that really are raw binary.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_escape_filter_elementW (
|
|
PCHAR sourceFilterElement,
|
|
ULONG sourceLength,
|
|
PWCHAR destFilterElement,
|
|
ULONG destLength
|
|
);
|
|
WINLDAPAPI ULONG LDAPAPI ldap_escape_filter_elementA (
|
|
PCHAR sourceFilterElement,
|
|
ULONG sourceLength,
|
|
PCHAR destFilterElement,
|
|
ULONG destLength
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_escape_filter_element ldap_escape_filter_elementW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_escape_filter_element (
|
|
PCHAR sourceFilterElement,
|
|
ULONG sourceLength,
|
|
PCHAR destFilterElement,
|
|
ULONG destLength
|
|
);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Misc extensions for additional debugging.
|
|
//
|
|
// Note that these do nothing on free builds.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_set_dbg_flags( ULONG NewFlags );
|
|
|
|
typedef ULONG (_cdecl *DBGPRINT)( PCH Format, ... );
|
|
|
|
WINLDAPAPI VOID LDAPAPI ldap_set_dbg_routine( DBGPRINT DebugPrintRoutine );
|
|
|
|
//
|
|
// These routines are possibly useful by other modules. Note that Win95
|
|
// doesn't by default have the UTF-8 codepage loaded. So a good way to
|
|
// convert from UTF-8 to Unicode.
|
|
//
|
|
|
|
|
|
WINLDAPAPI int LDAPAPI
|
|
LdapUTF8ToUnicode(
|
|
LPCSTR lpSrcStr,
|
|
int cchSrc,
|
|
LPWSTR lpDestStr,
|
|
int cchDest
|
|
);
|
|
|
|
WINLDAPAPI
|
|
int LDAPAPI
|
|
LdapUnicodeToUTF8(
|
|
LPCWSTR lpSrcStr,
|
|
int cchSrc,
|
|
LPSTR lpDestStr,
|
|
int cchDest
|
|
);
|
|
|
|
//
|
|
// LDAPv3 features :
|
|
//
|
|
// Sort Keys... these are used to ask the server to sort the results
|
|
// before sending the results back. LDAPv3 only and optional to implement
|
|
// on the server side. Check supportedControl for an OID of
|
|
// "1.2.840.113556.1.4.473" to see if the server supports it.
|
|
//
|
|
|
|
#define LDAP_SERVER_SORT_OID "1.2.840.113556.1.4.473"
|
|
#define LDAP_SERVER_SORT_OID_W L"1.2.840.113556.1.4.473"
|
|
|
|
#define LDAP_SERVER_RESP_SORT_OID "1.2.840.113556.1.4.474"
|
|
#define LDAP_SERVER_RESP_SORT_OID_W L"1.2.840.113556.1.4.474"
|
|
|
|
typedef struct ldapsearch LDAPSearch, *PLDAPSearch;
|
|
|
|
typedef struct ldapsortkeyW {
|
|
|
|
PWCHAR sk_attrtype;
|
|
PWCHAR sk_matchruleoid;
|
|
BOOLEAN sk_reverseorder;
|
|
|
|
} LDAPSortKeyW, *PLDAPSortKeyW;
|
|
|
|
typedef struct ldapsortkeyA {
|
|
|
|
PCHAR sk_attrtype;
|
|
PCHAR sk_matchruleoid;
|
|
BOOLEAN sk_reverseorder;
|
|
|
|
} LDAPSortKeyA, *PLDAPSortKeyA;
|
|
|
|
#if LDAP_UNICODE
|
|
#define LDAPSortKey LDAPSortKeyW
|
|
#define PLDAPSortKey PLDAPSortKeyW
|
|
#else
|
|
#define LDAPSortKey LDAPSortKeyA
|
|
#define PLDAPSortKey PLDAPSortKeyA
|
|
#endif
|
|
|
|
//
|
|
// This API formats a list of sort keys into a search control. Call
|
|
// ldap_control_free when you're finished with the control.
|
|
//
|
|
// Use this one rather than ldap_encode_sort_control as this is per RFC.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_sort_controlA (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyA *SortKeys,
|
|
UCHAR IsCritical,
|
|
PLDAPControlA *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_sort_controlW (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyW *SortKeys,
|
|
UCHAR IsCritical,
|
|
PLDAPControlW *Control
|
|
);
|
|
|
|
//
|
|
// This API parses the sort control returned by the server. Use ldap_memfree
|
|
// to free the attribute value, if it's returned.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_sort_controlA (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlA *Control,
|
|
ULONG *Result,
|
|
PCHAR *Attribute
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_sort_controlW (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlW *Control,
|
|
ULONG *Result,
|
|
PWCHAR *Attribute
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_create_sort_control ldap_create_sort_controlW
|
|
#define ldap_parse_sort_control ldap_parse_sort_controlW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_sort_control (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyA *SortKeys,
|
|
UCHAR IsCritical,
|
|
PLDAPControlA *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_sort_control (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlA *Control,
|
|
ULONG *Result,
|
|
PCHAR *Attribute
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// This API formats a list of sort keys into a search control. Call
|
|
// ldap_memfree for both Control->ldctl_value.bv_val and
|
|
// Control->currentControl->ldctl_oid when you're finished with the control.
|
|
//
|
|
// This is the old sort API that will be shortly pulled. Please use
|
|
// ldap_create_sort_control defined above.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_encode_sort_controlW (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyW *SortKeys,
|
|
PLDAPControlW Control,
|
|
BOOLEAN Criticality
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_encode_sort_controlA (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyA *SortKeys,
|
|
PLDAPControlA Control,
|
|
BOOLEAN Criticality
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_encode_sort_control ldap_encode_sort_controlW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_encode_sort_control (
|
|
PLDAP ExternalHandle,
|
|
PLDAPSortKeyA *SortKeys,
|
|
PLDAPControlA Control,
|
|
BOOLEAN Criticality
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// LDAPv3: This is the RFC defined API for the simple paging of results
|
|
// control. Use ldap_control_free to free the control allocated by
|
|
// ldap_create_page_control.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_page_controlW(
|
|
PLDAP ExternalHandle,
|
|
ULONG PageSize,
|
|
struct berval *Cookie,
|
|
UCHAR IsCritical,
|
|
PLDAPControlW *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_page_controlA(
|
|
PLDAP ExternalHandle,
|
|
ULONG PageSize,
|
|
struct berval *Cookie,
|
|
UCHAR IsCritical,
|
|
PLDAPControlA *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_page_controlW (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlW *ServerControls,
|
|
ULONG *TotalCount,
|
|
struct berval **Cookie // Use ber_bvfree to free
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_page_controlA (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlA *ServerControls,
|
|
ULONG *TotalCount,
|
|
struct berval **Cookie // Use ber_bvfree to free
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_create_page_control ldap_create_page_controlW
|
|
#define ldap_parse_page_control ldap_parse_page_controlW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_create_page_control(
|
|
PLDAP ExternalHandle,
|
|
ULONG PageSize,
|
|
struct berval *Cookie,
|
|
UCHAR IsCritical,
|
|
PLDAPControlA *Control
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_page_control (
|
|
PLDAP ExternalHandle,
|
|
PLDAPControlA *ServerControls,
|
|
ULONG *TotalCount,
|
|
struct berval **Cookie // Use ber_bvfree to free
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// LDAPv3: This is the interface for simple paging of results. To ensure
|
|
// that the server supports it, check the supportedControl property off of
|
|
// the root for an OID of 1.2.840.113556.1.4.319. If it is there, then it
|
|
// supports this feature.
|
|
//
|
|
// If you're going to specify sort keys, see section above on sort keys on
|
|
// now to tell if they're supported by the server.
|
|
//
|
|
// You first call ldap_search_init_page. If it returns a non-NULL LDAPSearch
|
|
// block, then it worked ok. Otherwise call LdapGetLastError to find error.
|
|
//
|
|
// With a valid LDAPSearch block (there are opaque), call ldap_get_next_page
|
|
// or ldap_get_next_page_s. If you call ldap_get_next_page, you MUST call
|
|
// ldap_get_paged_count for each set of results that you get for that message.
|
|
// This allows the library to save off the cookie that the server sent to
|
|
// resume the search.
|
|
//
|
|
// Other than calling ldap_get_paged_count, the results you get back from
|
|
// ldap_get_next_page can be treated as any other search result, and should
|
|
// be freed when you're done by calling ldap_msgfree.
|
|
//
|
|
// When the end of the search is hit, you'll get a return code of
|
|
// LDAP_NO_RESULTS_RETURNED. At this point, (or any point after LDAPSearch
|
|
// structure has been allocated), you call ldap_search_abandon_page. You
|
|
// need to call this even after you get a return code of
|
|
// LDAP_NO_RESULTS_RETURNED.
|
|
//
|
|
// If you call ldap_get_next_page_s, you don't need to call
|
|
// ldap_get_paged_count.
|
|
//
|
|
|
|
#define LDAP_PAGED_RESULT_OID_STRING "1.2.840.113556.1.4.319"
|
|
#define LDAP_PAGED_RESULT_OID_STRING_W L"1.2.840.113556.1.4.319"
|
|
|
|
WINLDAPAPI PLDAPSearch LDAPAPI ldap_search_init_pageW(
|
|
PLDAP ExternalHandle,
|
|
const PWCHAR DistinguishedName,
|
|
ULONG ScopeOfSearch,
|
|
const PWCHAR SearchFilter,
|
|
PWCHAR AttributeList[],
|
|
ULONG AttributesOnly,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG PageTimeLimit,
|
|
ULONG TotalSizeLimit,
|
|
PLDAPSortKeyW *SortKeys
|
|
);
|
|
|
|
WINLDAPAPI PLDAPSearch LDAPAPI ldap_search_init_pageA(
|
|
PLDAP ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
ULONG ScopeOfSearch,
|
|
const PCHAR SearchFilter,
|
|
PCHAR AttributeList[],
|
|
ULONG AttributesOnly,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG PageTimeLimit,
|
|
ULONG TotalSizeLimit,
|
|
PLDAPSortKeyA *SortKeys
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_search_init_page ldap_search_init_pageW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI PLDAPSearch LDAPAPI ldap_search_init_page(
|
|
PLDAP ExternalHandle,
|
|
const PCHAR DistinguishedName,
|
|
ULONG ScopeOfSearch,
|
|
const PCHAR SearchFilter,
|
|
PCHAR AttributeList[],
|
|
ULONG AttributesOnly,
|
|
PLDAPControl *ServerControls,
|
|
PLDAPControl *ClientControls,
|
|
ULONG PageTimeLimit,
|
|
ULONG TotalSizeLimit,
|
|
PLDAPSortKey *SortKeys
|
|
);
|
|
|
|
#endif
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_get_next_page(
|
|
PLDAP ExternalHandle,
|
|
PLDAPSearch SearchHandle,
|
|
ULONG PageSize,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_get_next_page_s(
|
|
PLDAP ExternalHandle,
|
|
PLDAPSearch SearchHandle,
|
|
struct l_timeval *timeout,
|
|
ULONG PageSize,
|
|
ULONG *TotalCount,
|
|
LDAPMessage **Results
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_get_paged_count(
|
|
PLDAP ExternalHandle,
|
|
PLDAPSearch SearchBlock,
|
|
ULONG *TotalCount,
|
|
PLDAPMessage Results
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_search_abandon_page(
|
|
PLDAP ExternalHandle,
|
|
PLDAPSearch SearchBlock
|
|
);
|
|
|
|
//
|
|
// These functions return subordinate referrals (references) that are returned
|
|
// in search responses. There are two types of referrals. External referrals
|
|
// where the naming context doesn't reside on the server (e.g. server says "I
|
|
// don't have the data, look over there") and Subordinate referrals (or
|
|
// references) where some data has been returned and the referrals are passed
|
|
// to other naming contexts below the current one (e.g. servers says "Here's
|
|
// some data from the tree I hold, go look here, there, and over there for
|
|
// more data that is further down in the tree.").
|
|
//
|
|
// These routines handle the latter. For external references, use
|
|
// ldap_parse_result.
|
|
//
|
|
// Return the first reference from a message. It is freed when the message is
|
|
// freed so should not be freed explicitly.
|
|
//
|
|
|
|
WINLDAPAPI LDAPMessage *LDAPAPI ldap_first_reference( LDAP *ld, LDAPMessage *res );
|
|
|
|
//
|
|
// Return the next entry of a message. It is freed when the message is
|
|
// freed so should not be freed explicitly.
|
|
//
|
|
|
|
WINLDAPAPI LDAPMessage *LDAPAPI ldap_next_reference( LDAP *ld, LDAPMessage *entry );
|
|
|
|
//
|
|
// Count the number of subordinate references returned by the server in a
|
|
// response to a search request.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_count_references( LDAP *ld, LDAPMessage *res );
|
|
|
|
//
|
|
// We return the list of subordinate referrals in a search response message.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_referenceW (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
PWCHAR **Referrals // free with ldap_value_freeW
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_referenceA (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
PCHAR **Referrals // free with ldap_value_freeA
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_parse_reference ldap_parse_referenceW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_parse_reference (
|
|
LDAP *Connection,
|
|
LDAPMessage *ResultMessage,
|
|
PCHAR **Referrals // free with ldap_value_free
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// These APIs allow a client to send an extended request (free for all) to
|
|
// an LDAPv3 (or above) server. The functionality is fairly open... you can
|
|
// send any request you'd like. Note that since we don't know if you'll
|
|
// be receiving a single or multiple responses, you'll have to explicitly tell
|
|
// us when you're done with the request by calling ldap_close_extended_op.
|
|
//
|
|
// These are thread safe.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_extended_operationW(
|
|
LDAP *ld,
|
|
const PWCHAR Oid,
|
|
struct berval *Data,
|
|
PLDAPControlW *ServerControls,
|
|
PLDAPControlW *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_extended_operationA(
|
|
LDAP *ld,
|
|
const PCHAR Oid,
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
|
|
#if LDAP_UNICODE
|
|
|
|
#define ldap_extended_operation ldap_extended_operationW
|
|
|
|
#else
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_extended_operation(
|
|
LDAP *ld,
|
|
const PCHAR Oid,
|
|
struct berval *Data,
|
|
PLDAPControlA *ServerControls,
|
|
PLDAPControlA *ClientControls,
|
|
ULONG *MessageNumber
|
|
);
|
|
#endif
|
|
|
|
WINLDAPAPI ULONG LDAPAPI ldap_close_extended_op(
|
|
LDAP *ld,
|
|
ULONG MessageNumber
|
|
);
|
|
|
|
|
|
//
|
|
// Some enhancements that will probably never make it into the RFC related
|
|
// to callouts to allow external caching of connections.
|
|
//
|
|
// Call ldap_set_option( conn, LDAP_OPT_REFERRAL_CALLBACK, &referralRoutines )
|
|
// where referralRoutines is the address of an LDAP_REFERRAL_CALLBACK
|
|
// structure with your routines. They may be NULL, in which case we'll
|
|
// obviously not make the calls.
|
|
//
|
|
// Any connections that are created will inherit the current callbacks from
|
|
// the primary connection that the request was initiated on.
|
|
//
|
|
|
|
#define LDAP_OPT_REFERRAL_CALLBACK 0x70
|
|
|
|
//
|
|
// This first routine is called when we're about to chase a referral. We
|
|
// callout to it to see if there is already a connection cached that we
|
|
// can use. If so, the callback routine returns the pointer to the
|
|
// connection to use in ConnectionToUse. If not, it sets
|
|
// *ConnectionToUse to NULL.
|
|
//
|
|
// For a return code, it should return 0 if we should continue to chase the
|
|
// referral. If it returns a non-zero return code, we'll treat that as the
|
|
// error code for chasing the referral. This allows caching of host names
|
|
// that are not reachable, if we decide to add that in the future.
|
|
//
|
|
|
|
typedef ULONG (_cdecl QUERYFORCONNECTION)(
|
|
PLDAP PrimaryConnection,
|
|
PLDAP ReferralFromConnection,
|
|
PWCHAR NewDN,
|
|
PCHAR HostName,
|
|
ULONG PortNumber,
|
|
PVOID SecAuthIdentity, // if null, use CurrentUser below
|
|
PVOID CurrentUserToken, // pointer to current user's LUID
|
|
PLDAP *ConnectionToUse
|
|
);
|
|
|
|
//
|
|
// This next function is called when we've created a new connection while
|
|
// chasing a referral. Note that it gets assigned the same callback functions
|
|
// as the PrimaryConnection. If the return code is FALSE, then the call
|
|
// back function doesn't want to cache the connection and it will be
|
|
// destroyed after the operation is complete. If TRUE is returned, we'll
|
|
// assume that the callee has taken ownership of the connection and it will
|
|
// not be destroyed after the operation is complete.
|
|
//
|
|
// If the ErrorCodeFromBind field is not 0, then the bind operation to
|
|
// that server failed.
|
|
//
|
|
|
|
typedef BOOLEAN (_cdecl NOTIFYOFNEWCONNECTION) (
|
|
PLDAP PrimaryConnection,
|
|
PLDAP ReferralFromConnection,
|
|
PWCHAR NewDN,
|
|
PCHAR HostName,
|
|
PLDAP NewConnection,
|
|
ULONG PortNumber,
|
|
PVOID SecAuthIdentity, // if null, use CurrentUser below
|
|
PVOID CurrentUser, // pointer to current user's LUID
|
|
ULONG ErrorCodeFromBind
|
|
);
|
|
|
|
//
|
|
// This next function is called when we've successfully called off to the
|
|
// QueryForConnection call and received a connection OR when we called off
|
|
// to the NotifyOfNewConnection call and it returned TRUE. We call this
|
|
// function when we're dereferencing the connection after we're done with it.
|
|
//
|
|
// Return code is currently ignored, but the function should return
|
|
// LDAP_SUCCESS if all went well.
|
|
//
|
|
|
|
typedef ULONG (_cdecl DEREFERENCECONNECTION)(
|
|
PLDAP PrimaryConnection,
|
|
PLDAP ConnectionToDereference
|
|
);
|
|
|
|
typedef struct LdapReferralCallback {
|
|
|
|
ULONG SizeOfCallbacks; // set to sizeof( LDAP_REFERRAL_CALLBACK )
|
|
QUERYFORCONNECTION *QueryForConnection;
|
|
NOTIFYOFNEWCONNECTION *NotifyRoutine;
|
|
DEREFERENCECONNECTION *DereferenceRoutine;
|
|
|
|
} LDAP_REFERRAL_CALLBACK, *PLDAP_REFERRAL_CALLBACK;
|
|
|
|
//
|
|
// Thread Safe way to get last error code returned by LDAP API is to call
|
|
// LdapGetLastError();
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI LdapGetLastError( VOID );
|
|
|
|
//
|
|
// Translate from LdapError to closest Win32 error code.
|
|
//
|
|
|
|
WINLDAPAPI ULONG LDAPAPI LdapMapErrorToWin32( ULONG LdapError );
|
|
|
|
//
|
|
// This is an arrangement for specifying client certificates while establishing
|
|
// an SSL connection.
|
|
// Simply Call ldap_set_option( conn, LDAP_OPT_CLIENT_CERTIFICATE, &CertRoutine )
|
|
// where CertRoutine is the address of your callback routine. If it is NULL,
|
|
// we will obviously not make the call.
|
|
//
|
|
|
|
#define LDAP_OPT_CLIENT_CERTIFICATE 0x80
|
|
|
|
//
|
|
// This callback is invoked when the server demands a client certificate for
|
|
// authorization. We pass a structure containing a list of server-trusted
|
|
// Certificate Authorities. If the client has certificates to provide, it
|
|
// converts them to CERT_CONTEXTs and adds them to the given certificate
|
|
// store. LDAP subsequently passes these credentials to the SSL server as part
|
|
// of the handshake.
|
|
//
|
|
|
|
typedef BOOLEAN (_cdecl QUERYCLIENTCERT) (
|
|
IN PLDAP Connection,
|
|
IN PSecPkgContext_IssuerListInfoEx trusted_CAs,
|
|
IN OUT HCERTSTORE hCertStore,
|
|
IN OUT DWORD *pcCreds
|
|
);
|
|
|
|
//
|
|
// We are also giving an opportunity for the client to verify the certificate
|
|
// of the server. The client registers a callback which is invoked after the
|
|
// secure connection is setup. The server certificate is presented to the
|
|
// client who invokes it and decides it it is acceptable. To register this
|
|
// callback, simply call ldap_set_option( conn, LDAP_OPT_SERVER_CERTIFICATE, &CertRoutine )
|
|
//
|
|
|
|
#define LDAP_OPT_SERVER_CERTIFICATE 0x81
|
|
|
|
//
|
|
// This function is called after the secure connection has been established. The
|
|
// certificate of the server is supplied for examination by the client. If the
|
|
// client approves it, it returns TRUE else, it returns false and the secure
|
|
// connection is torn down.
|
|
//
|
|
|
|
typedef BOOLEAN (_cdecl VERIFYSERVERCERT) (
|
|
PLDAP Connection,
|
|
PCCERT_CONTEXT pServerCert);
|
|
|
|
|
|
|
|
//
|
|
// Given an LDAP message, return the connection pointer where the message
|
|
// came from. It can return NULL if the connection has already been freed.
|
|
//
|
|
|
|
WINLDAPAPI LDAP * LDAPAPI ldap_conn_from_msg (
|
|
LDAP *PrimaryConn,
|
|
LDAPMessage *res
|
|
);
|
|
|
|
//
|
|
// Do we reference the connection for each message so that we can safely get
|
|
// the connection pointer back by calling ldap_conn_from_msg?
|
|
//
|
|
|
|
#define LDAP_OPT_REF_DEREF_CONN_PER_MSG 0x94
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma option pop /*P_O_Pop*/
|
|
#endif // LDAP_CLIENT_DEFINED
|