Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 22 participants
- 84527 discussions
[PATCH v3 1/4] crypt32/tests: Add a test to verify certificate signature.
by Dmitry Timoshkov April 14, 2021
by Dmitry Timoshkov April 14, 2021
April 14, 2021
v2: Move the tests to crypt32.
v3: Directly link to bcrypt.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/crypt32/tests/Makefile.in | 2 +-
dlls/crypt32/tests/cert.c | 95 +++++++++++++++++++++++++++++++++-
2 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/dlls/crypt32/tests/Makefile.in b/dlls/crypt32/tests/Makefile.in
index d96ad1cd6f1..339cff30e0f 100644
--- a/dlls/crypt32/tests/Makefile.in
+++ b/dlls/crypt32/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = crypt32.dll
-IMPORTS = crypt32 advapi32 user32 shlwapi shell32
+IMPORTS = crypt32 advapi32 user32 shlwapi shell32 bcrypt
C_SRCS = \
base64.c \
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 745770f0095..15ed98e0e30 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -28,6 +28,7 @@
#include <winreg.h>
#include <winerror.h>
#include <wincrypt.h>
+#include <bcrypt.h>
#include "wine/test.h"
@@ -60,7 +61,6 @@ static void init_function_pointers(void)
GET_PROC(hCrypt32, CryptVerifyCertificateSignatureEx)
GET_PROC(hAdvapi32, CryptAcquireContextA)
-
#undef GET_PROC
}
@@ -4237,6 +4237,98 @@ static void testKeyProvInfo(void)
CertCloseStore(store, 0);
}
+static void test_VerifySignature(void)
+{
+ PCCERT_CONTEXT cert;
+ PCERT_SIGNED_CONTENT_INFO info;
+ DWORD size;
+ BOOL ret;
+ HCRYPTPROV prov;
+ HCRYPTKEY key;
+ HCRYPTHASH hash;
+ BYTE hash_value[20], *sig_value;
+ DWORD hash_len, i;
+ BCRYPT_KEY_HANDLE bkey;
+ BCRYPT_HASH_HANDLE bhash;
+ BCRYPT_ALG_HANDLE alg;
+ BCRYPT_PKCS1_PADDING_INFO pad;
+ NTSTATUS status;
+
+ cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
+ ok(cert != NULL, "CertCreateCertificateContext error %#x\n", GetLastError());
+
+ /* 1. Verify certificate signature with Crypto API */
+ ret = CryptVerifyCertificateSignature(0, cert->dwCertEncodingType,
+ cert->pbCertEncoded, cert->cbCertEncoded, &cert->pCertInfo->SubjectPublicKeyInfo);
+ ok(ret, "CryptVerifyCertificateSignature error %#x\n", GetLastError());
+
+ /* 2. Verify certificate signature with Crypto API manually */
+ ret = pCryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ ok(ret, "CryptAcquireContext error %#x\n", GetLastError());
+
+ ret = CryptImportPublicKeyInfoEx(prov, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_CERT,
+ cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
+ ok(ret, "CryptDecodeObjectEx error %#x\n", GetLastError());
+
+ ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+ ok(ret, "CryptCreateHash error %#x\n", GetLastError());
+
+ ret = CryptHashData(hash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(ret, "CryptHashData error %#x\n", GetLastError());
+
+ ret = CryptVerifySignatureW(hash, info->Signature.pbData, info->Signature.cbData, key, NULL, 0);
+ ok(ret, "CryptVerifySignature error %#x\n", GetLastError());
+
+ CryptDestroyHash(hash);
+ CryptDestroyKey(key);
+ CryptReleaseContext(prov, 0);
+
+ /* 3. Verify certificate signature with CNG */
+ ret = CryptImportPublicKeyInfoEx2(cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &bkey);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = BCryptCreateHash(alg, &bhash, NULL, 0, NULL, 0, 0);
+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Vista */, "got %#x\n", status);
+ if (status == STATUS_INVALID_PARAMETER)
+ {
+ win_skip("broken BCryptCreateHash\n");
+ goto done;
+ }
+
+ status = BCryptHashData(bhash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = BCryptFinishHash(bhash, hash_value, sizeof(hash_value), 0);
+ ok(!status, "got %#x\n", status);
+ ok(!memcmp(hash_value, selfSignedSignatureHash, sizeof(hash_value)), "got wrong hash value\n");
+
+ status = BCryptGetProperty(bhash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &size, 0);
+ ok(!status, "got %#x\n", status);
+ ok(hash_len == sizeof(hash_value), "got %u\n", hash_len);
+
+ sig_value = HeapAlloc(GetProcessHeap(), 0, info->Signature.cbData);
+ for (i = 0; i < info->Signature.cbData; i++)
+ sig_value[i] = info->Signature.pbData[info->Signature.cbData - i - 1];
+
+ pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
+ status = BCryptVerifySignature(bkey, &pad, hash_value, sizeof(hash_value), sig_value, info->Signature.cbData, BCRYPT_PAD_PKCS1);
+ ok(!status, "got %#x\n", status);
+
+ HeapFree(GetProcessHeap(), 0, sig_value);
+ BCryptDestroyHash(bhash);
+done:
+ BCryptCloseAlgorithmProvider(alg, 0);
+
+ LocalFree(info);
+ CertFreeCertificateContext(cert);
+}
+
START_TEST(cert)
{
init_function_pointers();
@@ -4270,4 +4362,5 @@ START_TEST(cert)
testAcquireCertPrivateKey();
testGetPublicKeyLength();
testIsRDNAttrsInCertificateName();
+ test_VerifySignature();
}
--
2.31.1
3
2
Re: [PATCH 1/2] cmd: Use terminated strings in WCMD_ReadAndParseLine()
by Hugh McMaster April 14, 2021
by Hugh McMaster April 14, 2021
April 14, 2021
On Mon, 12 Apr 2021 02:22:36 +0200, Gijs Vermeulen wrote:
> @@ -1870,10 +1865,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
>
> /* Show prompt before batch line IF echo is on and in batch program */
> if (context && echo_mode && *curPos && (*curPos != '@')) {
> - static const WCHAR echoDot[] = {'e','c','h','o','.'};
> - static const WCHAR echoCol[] = {'e','c','h','o',':'};
> - static const WCHAR echoSlash[] = {'e','c','h','o','/'};
> - const DWORD len = ARRAY_SIZE(echoDot);
> + const DWORD len = ARRAY_SIZE(L"echo.") - 1;
This is very unusual. Why not just use lstrlenW(...)?
You should also look at calculating the string length within
WCMD_keyword_ws_found(), instead of passing the length as an argument.
But do this as a separate patch.
--
Hugh McMaster
3
6
[PATCH v2] crypt32/tests: Add a test to verify certificate signature.
by Dmitry Timoshkov April 14, 2021
by Dmitry Timoshkov April 14, 2021
April 14, 2021
v2: Move the tests to crypt32.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/crypt32/tests/cert.c | 116 ++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 745770f0095..3f50fad482c 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -28,6 +28,7 @@
#include <winreg.h>
#include <winerror.h>
#include <wincrypt.h>
+#include <bcrypt.h>
#include "wine/test.h"
@@ -42,10 +43,22 @@ static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
static BOOL (WINAPI * pCryptAcquireContextA)
(HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
+static NTSTATUS (WINAPI *pBCryptCloseAlgorithmProvider)(BCRYPT_ALG_HANDLE, ULONG);
+static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR,
+ ULONG, ULONG);
+static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE);
+static NTSTATUS (WINAPI *pBCryptDestroyKey)(BCRYPT_KEY_HANDLE);
+static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
+static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
+static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG);
+static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG);
+static NTSTATUS (WINAPI *pBCryptVerifySignature)(BCRYPT_KEY_HANDLE, VOID *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG);
+
static void init_function_pointers(void)
{
HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
+ HMODULE hBcrypt = LoadLibraryA("bcrypt.dll");
#define GET_PROC(dll, func) \
p ## func = (void *)GetProcAddress(dll, #func); \
@@ -61,6 +74,16 @@ static void init_function_pointers(void)
GET_PROC(hAdvapi32, CryptAcquireContextA)
+ GET_PROC(hBcrypt, BCryptCloseAlgorithmProvider)
+ GET_PROC(hBcrypt, BCryptCreateHash)
+ GET_PROC(hBcrypt, BCryptDestroyHash)
+ GET_PROC(hBcrypt, BCryptDestroyKey)
+ GET_PROC(hBcrypt, BCryptFinishHash)
+ GET_PROC(hBcrypt, BCryptHashData)
+ GET_PROC(hBcrypt, BCryptGetProperty)
+ GET_PROC(hBcrypt, BCryptOpenAlgorithmProvider)
+ GET_PROC(hBcrypt, BCryptVerifySignature)
+
#undef GET_PROC
}
@@ -4237,6 +4260,98 @@ static void testKeyProvInfo(void)
CertCloseStore(store, 0);
}
+static void test_VerifySignature(void)
+{
+ PCCERT_CONTEXT cert;
+ PCERT_SIGNED_CONTENT_INFO info;
+ DWORD size;
+ BOOL ret;
+ HCRYPTPROV prov;
+ HCRYPTKEY key;
+ HCRYPTHASH hash;
+ BYTE hash_value[20], *sig_value;
+ DWORD hash_len, i;
+ BCRYPT_KEY_HANDLE bkey;
+ BCRYPT_HASH_HANDLE bhash;
+ BCRYPT_ALG_HANDLE alg;
+ BCRYPT_PKCS1_PADDING_INFO pad;
+ NTSTATUS status;
+
+ cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
+ ok(cert != NULL, "CertCreateCertificateContext error %#x\n", GetLastError());
+
+ /* 1. Verify certificate signature with Crypto API */
+ ret = CryptVerifyCertificateSignature(0, cert->dwCertEncodingType,
+ cert->pbCertEncoded, cert->cbCertEncoded, &cert->pCertInfo->SubjectPublicKeyInfo);
+ ok(ret, "CryptVerifyCertificateSignature error %#x\n", GetLastError());
+
+ /* 2. Verify certificate signature with Crypto API manually */
+ ret = pCryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ ok(ret, "CryptAcquireContext error %#x\n", GetLastError());
+
+ ret = CryptImportPublicKeyInfoEx(prov, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_CERT,
+ cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
+ ok(ret, "CryptDecodeObjectEx error %#x\n", GetLastError());
+
+ ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+ ok(ret, "CryptCreateHash error %#x\n", GetLastError());
+
+ ret = CryptHashData(hash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(ret, "CryptHashData error %#x\n", GetLastError());
+
+ ret = CryptVerifySignatureW(hash, info->Signature.pbData, info->Signature.cbData, key, NULL, 0);
+ ok(ret, "CryptVerifySignature error %#x\n", GetLastError());
+
+ CryptDestroyHash(hash);
+ CryptDestroyKey(key);
+ CryptReleaseContext(prov, 0);
+
+ /* 3. Verify certificate signature with CNG */
+ ret = CryptImportPublicKeyInfoEx2(cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &bkey);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ status = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = pBCryptCreateHash(alg, &bhash, NULL, 0, NULL, 0, 0);
+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Vista */, "got %#x\n", status);
+ if (status == STATUS_INVALID_PARAMETER)
+ {
+ win_skip("broken BCryptCreateHash\n");
+ goto done;
+ }
+
+ status = pBCryptHashData(bhash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = pBCryptFinishHash(bhash, hash_value, sizeof(hash_value), 0);
+ ok(!status, "got %#x\n", status);
+ ok(!memcmp(hash_value, selfSignedSignatureHash, sizeof(hash_value)), "got wrong hash value\n");
+
+ status = pBCryptGetProperty(bhash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &size, 0);
+ ok(!status, "got %#x\n", status);
+ ok(hash_len == sizeof(hash_value), "got %u\n", hash_len);
+
+ sig_value = HeapAlloc(GetProcessHeap(), 0, info->Signature.cbData);
+ for (i = 0; i < info->Signature.cbData; i++)
+ sig_value[i] = info->Signature.pbData[info->Signature.cbData - i - 1];
+
+ pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
+ status = pBCryptVerifySignature(bkey, &pad, hash_value, sizeof(hash_value), sig_value, info->Signature.cbData, BCRYPT_PAD_PKCS1);
+ ok(!status, "got %#x\n", status);
+
+ HeapFree(GetProcessHeap(), 0, sig_value);
+ pBCryptDestroyHash(bhash);
+done:
+ pBCryptCloseAlgorithmProvider(alg, 0);
+
+ LocalFree(info);
+ CertFreeCertificateContext(cert);
+}
+
START_TEST(cert)
{
init_function_pointers();
@@ -4270,4 +4385,5 @@ START_TEST(cert)
testAcquireCertPrivateKey();
testGetPublicKeyLength();
testIsRDNAttrsInCertificateName();
+ test_VerifySignature();
}
--
2.31.1
2
3
[PATCH] bcrypt/tests: Add a test to verify certificate signature.
by Dmitry Timoshkov April 14, 2021
by Dmitry Timoshkov April 14, 2021
April 14, 2021
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/bcrypt/tests/Makefile.in | 2 +-
dlls/bcrypt/tests/bcrypt.c | 121 ++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/tests/Makefile.in b/dlls/bcrypt/tests/Makefile.in
index 1bf7d2c48f1..b0f3e57f3ed 100644
--- a/dlls/bcrypt/tests/Makefile.in
+++ b/dlls/bcrypt/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = bcrypt.dll
-IMPORTS = bcrypt user32 advapi32
+IMPORTS = bcrypt user32 advapi32 crypt32
C_SRCS = \
bcrypt.c
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index 456727d04a9..58fc52f55c6 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -24,6 +24,7 @@
#include <windows.h>
#include <bcrypt.h>
#include <ncrypt.h>
+#include <wincrypt.h>
#include "wine/test.h"
@@ -2741,6 +2742,125 @@ static void test_SecretAgreement(void)
ok(status == STATUS_SUCCESS, "got %08x\n", status);
}
+/* Copied from dlls/crypt32/tests/cert.c */
+static const BYTE selfSignedCert[] = {
+ 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+ 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
+ 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
+ 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
+ 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
+ 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
+ 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
+ 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
+ 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
+ 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
+ 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
+ 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
+ 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
+ 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
+ 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
+ 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
+ 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
+ 0xa8, 0x76, 0x57, 0x92, 0x36 };
+static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
+ 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
+
+HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID);
+
+static void test_VerifySignature(void)
+{
+ PCCERT_CONTEXT cert;
+ PCERT_SIGNED_CONTENT_INFO info;
+ DWORD size;
+ BOOL ret;
+ HCRYPTPROV prov;
+ HCRYPTKEY key;
+ HCRYPTHASH hash;
+ BYTE hash_value[20], *sig_value;
+ DWORD hash_len, sig_len, i;
+ BCRYPT_KEY_HANDLE bkey;
+ BCRYPT_HASH_HANDLE bhash;
+ BCRYPT_ALG_HANDLE alg;
+ BCRYPT_PKCS1_PADDING_INFO pad;
+ NTSTATUS status;
+
+ cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
+ ok(cert != NULL, "CertCreateCertificateContext error %#x\n", GetLastError());
+
+ /* 1. Verify certificate signature with Crypto API */
+ ret = CryptVerifyCertificateSignature(0, cert->dwCertEncodingType,
+ cert->pbCertEncoded, cert->cbCertEncoded, &cert->pCertInfo->SubjectPublicKeyInfo);
+ ok(ret, "CryptVerifyCertificateSignature error %#x\n", GetLastError());
+
+ prov = I_CryptGetDefaultCryptProv(0);
+ ok(prov, "hCryptProv can't be NULL\n");
+ ret = CryptImportPublicKeyInfoEx(prov, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_CERT,
+ cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
+ ok(ret, "CryptDecodeObjectEx error %#x\n", GetLastError());
+
+ ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+ ok(ret, "CryptCreateHash error %#x\n", GetLastError());
+
+ ret = CryptHashData(hash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(ret, "CryptHashData error %#x\n", GetLastError());
+
+ ret = CryptVerifySignatureW(hash, info->Signature.pbData, info->Signature.cbData, key, NULL, 0);
+ CryptDestroyHash(hash);
+ CryptDestroyKey(key);
+ CryptReleaseContext(prov, 0);
+
+ /* 2. Verify certificate signature with CNG */
+ ret = CryptImportPublicKeyInfoEx2(cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &bkey);
+ ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError());
+
+ status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = BCryptCreateHash(alg, &bhash, NULL, 0, NULL, 0, 0);
+ ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Vista */, "got %#x\n", status);
+ if (status == STATUS_INVALID_PARAMETER)
+ {
+ win_skip("broken BCryptCreateHash\n");
+ goto done;
+ }
+
+ status = BCryptHashData(bhash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0);
+ ok(!status, "got %#x\n", status);
+
+ status = BCryptFinishHash(bhash, hash_value, sizeof(hash_value), 0);
+ ok(!status, "got %#x\n", status);
+ ok(!memcmp(hash_value, selfSignedSignatureHash, sizeof(hash_value)), "got wrong hash value\n");
+
+ status = BCryptGetProperty(bhash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &size, 0);
+ ok(!status, "got %#x\n", status);
+ ok(hash_len == sizeof(hash_value), "got %u\n", hash_len);
+
+ sig_len = info->Signature.cbData;
+ sig_value = CryptMemAlloc(sig_len);
+ for (i = 0; i < info->Signature.cbData; i++)
+ sig_value[i] = info->Signature.pbData[info->Signature.cbData - i - 1];
+
+ pad.pszAlgId = BCRYPT_SHA1_ALGORITHM;
+ status = BCryptVerifySignature(bkey, &pad, hash_value, sizeof(hash_value), sig_value, sig_len, BCRYPT_PAD_PKCS1);
+ ok(!status, "got %#x\n", status);
+
+ CryptMemFree(sig_value);
+ BCryptDestroyHash(bhash);
+done:
+ BCryptCloseAlgorithmProvider(alg, 0);
+
+ LocalFree(info);
+ CertFreeCertificateContext(cert);
+}
+
START_TEST(bcrypt)
{
HMODULE module;
@@ -2808,6 +2928,7 @@ START_TEST(bcrypt)
test_BcryptDeriveKeyCapi();
test_DSA();
test_SecretAgreement();
+ test_VerifySignature();
FreeLibrary(module);
}
--
2.31.1
3
2
[PATCH 5/5] wldap32: Move support for control functions to the Unix library.
by Hans Leidekker April 14, 2021
by Hans Leidekker April 14, 2021
April 14, 2021
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/control.c | 150 ++++++++++++++++-------------------------
dlls/wldap32/libldap.c | 18 +++++
dlls/wldap32/libldap.h | 6 ++
3 files changed, 81 insertions(+), 93 deletions(-)
diff --git a/dlls/wldap32/control.c b/dlls/wldap32/control.c
index f0e0b05c0d1..42098fc814a 100644
--- a/dlls/wldap32/control.c
+++ b/dlls/wldap32/control.c
@@ -18,25 +18,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
/***********************************************************************
* ldap_control_freeA (WLDAP32.@)
@@ -45,14 +35,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
*/
ULONG CDECL ldap_control_freeA( LDAPControlA *control )
{
- ULONG ret = WLDAP32_LDAP_SUCCESS;
-#ifdef HAVE_LDAP
-
TRACE( "(%p)\n", control );
controlfreeA( control );
-
-#endif
- return ret;
+ return WLDAP32_LDAP_SUCCESS;
}
/***********************************************************************
@@ -68,14 +53,9 @@ ULONG CDECL ldap_control_freeA( LDAPControlA *control )
*/
ULONG CDECL ldap_control_freeW( LDAPControlW *control )
{
- ULONG ret = WLDAP32_LDAP_SUCCESS;
-#ifdef HAVE_LDAP
-
TRACE( "(%p)\n", control );
controlfreeW( control );
-
-#endif
- return ret;
+ return WLDAP32_LDAP_SUCCESS;
}
/***********************************************************************
@@ -85,14 +65,9 @@ ULONG CDECL ldap_control_freeW( LDAPControlW *control )
*/
ULONG CDECL ldap_controls_freeA( LDAPControlA **controls )
{
- ULONG ret = WLDAP32_LDAP_SUCCESS;
-#ifdef HAVE_LDAP
-
TRACE( "(%p)\n", controls );
controlarrayfreeA( controls );
-
-#endif
- return ret;
+ return WLDAP32_LDAP_SUCCESS;
}
/***********************************************************************
@@ -108,14 +83,9 @@ ULONG CDECL ldap_controls_freeA( LDAPControlA **controls )
*/
ULONG CDECL ldap_controls_freeW( LDAPControlW **controls )
{
- ULONG ret = WLDAP32_LDAP_SUCCESS;
-#ifdef HAVE_LDAP
-
TRACE( "(%p)\n", controls );
controlarrayfreeW( controls );
-
-#endif
- return ret;
+ return WLDAP32_LDAP_SUCCESS;
}
/***********************************************************************
@@ -123,31 +93,29 @@ ULONG CDECL ldap_controls_freeW( LDAPControlW **controls )
*
* See ldap_create_sort_controlW.
*/
-ULONG CDECL ldap_create_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkey,
- UCHAR critical, PLDAPControlA *control )
+ULONG CDECL ldap_create_sort_controlA( WLDAP32_LDAP *ld, LDAPSortKeyA **sortkey, UCHAR critical,
+ LDAPControlA **control )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- LDAPSortKeyW **sortkeyW = NULL;
- LDAPControlW *controlW = NULL;
+ ULONG ret;
+ LDAPSortKeyW **sortkeyW;
+ LDAPControlW *controlW;
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
- if (!ld || !sortkey || !control)
- return WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld || !sortkey || !control) return WLDAP32_LDAP_PARAM_ERROR;
- sortkeyW = sortkeyarrayAtoW( sortkey );
- if (!sortkeyW) return WLDAP32_LDAP_NO_MEMORY;
+ if (!(sortkeyW = sortkeyarrayAtoW( sortkey ))) return WLDAP32_LDAP_NO_MEMORY;
ret = ldap_create_sort_controlW( ld, sortkeyW, critical, &controlW );
+ if (ret == WLDAP32_LDAP_SUCCESS)
+ {
+ LDAPControlA *controlA = controlWtoA( controlW );
+ if (controlA) *control = controlA;
+ else ret = WLDAP32_LDAP_NO_MEMORY;
+ ldap_control_freeW( controlW );
+ }
- *control = controlWtoA( controlW );
- if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
-
- ldap_control_freeW( controlW );
sortkeyarrayfreeW( sortkeyW );
-
-#endif
return ret;
}
@@ -173,31 +141,29 @@ ULONG CDECL ldap_create_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkey,
* Pass the created control as a server control in subsequent calls
* to ldap_search_ext(_s) to obtain sorted search results.
*/
-ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkey,
- UCHAR critical, PLDAPControlW *control )
+ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, LDAPSortKeyW **sortkey, UCHAR critical,
+ LDAPControlW **control )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- LDAPSortKey **sortkeyU = NULL;
- LDAPControl *controlU = NULL;
+ ULONG ret;
+ LDAPSortKeyU **sortkeyU;
+ LDAPControlU *controlU;
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
- if (!ld || !sortkey || !control)
- return WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld || !sortkey || !control) return WLDAP32_LDAP_PARAM_ERROR;
- sortkeyU = sortkeyarrayWtoU( sortkey );
- if (!sortkeyU) return WLDAP32_LDAP_NO_MEMORY;
+ if (sortkey && !(sortkeyU = sortkeyarrayWtoU( sortkey ))) return WLDAP32_LDAP_NO_MEMORY;
- ret = map_error( ldap_create_sort_control( ld->ld, sortkeyU, critical, &controlU ));
-
- *control = controlUtoW( controlU );
- if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
+ ret = map_error( ldap_funcs->ldap_create_sort_control( ld->ld, sortkeyU, critical, &controlU ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
+ {
+ LDAPControlW *controlW = controlUtoW( controlU );
+ if (controlW) *control = controlW;
+ else ret = WLDAP32_LDAP_NO_MEMORY;
+ ldap_funcs->ldap_control_free( controlU );
+ }
- ldap_control_free( controlU );
sortkeyarrayfreeU( sortkeyU );
-
-#endif
return ret;
}
@@ -206,27 +172,25 @@ ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkey,
*
* See ldap_create_vlv_controlW.
*/
-INT CDECL ldap_create_vlv_controlA( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
- UCHAR critical, LDAPControlA **control )
+INT CDECL ldap_create_vlv_controlA( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info, UCHAR critical,
+ LDAPControlA **control )
{
- INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- LDAPControlW *controlW = NULL;
+ INT ret;
+ LDAPControlW *controlW;
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
if (!ld || !control) return ~0u;
ret = ldap_create_vlv_controlW( ld, info, critical, &controlW );
-
if (ret == WLDAP32_LDAP_SUCCESS)
{
- *control = controlWtoA( controlW );
- if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
+ LDAPControlA *controlA = controlWtoA( controlW );
+ if (controlA) *control = controlA;
+ else ret = WLDAP32_LDAP_NO_MEMORY;
ldap_control_freeW( controlW );
}
-#endif
return ret;
}
@@ -252,33 +216,35 @@ INT CDECL ldap_create_vlv_controlA( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
* server will then return a sorted, contiguous subset of results
* that meets the criteria specified in the LDAPVLVInfo structure.
*/
-INT CDECL ldap_create_vlv_controlW( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
- UCHAR critical, LDAPControlW **control )
+INT CDECL ldap_create_vlv_controlW( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info, UCHAR critical,
+ LDAPControlW **control )
{
- INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- LDAPControl *controlU = NULL;
+ ULONG ret;
+ LDAPVLVInfoU *infoU = NULL;
+ LDAPControlU *controlU;
TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
if (!ld || !control) return ~0u;
- ret = map_error( ldap_create_vlv_control( ld->ld, (LDAPVLVInfo *)info, &controlU ));
+ if (info && !(infoU = vlvinfoWtoU( info ))) return WLDAP32_LDAP_NO_MEMORY;
+ ret = map_error( ldap_funcs->ldap_create_vlv_control( ld->ld, infoU, &controlU ) );
if (ret == WLDAP32_LDAP_SUCCESS)
{
- *control = controlUtoW( controlU );
- if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
- ldap_control_free( controlU );
+ LDAPControlW *controlW = controlUtoW( controlU );
+ if (controlW) *control = controlW;
+ else ret = WLDAP32_LDAP_NO_MEMORY;
+ ldap_funcs->ldap_control_free( controlU );
}
-#endif
+ vlvinfofreeU( infoU );
return ret;
}
static inline void bv_val_dup( const struct WLDAP32_berval *src, struct WLDAP32_berval *dst )
{
- if ((dst->bv_val = heap_alloc( src->bv_len )))
+ if ((dst->bv_val = RtlAllocateHeap( GetProcessHeap(), 0 , src->bv_len )))
{
memcpy( dst->bv_val, src->bv_val, src->bv_len );
dst->bv_len = src->bv_len;
@@ -292,8 +258,7 @@ static inline void bv_val_dup( const struct WLDAP32_berval *src, struct WLDAP32_
*
* See ldap_encode_sort_controlW.
*/
-ULONG CDECL ldap_encode_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkeys,
- PLDAPControlA ret, BOOLEAN critical )
+ULONG CDECL ldap_encode_sort_controlA( WLDAP32_LDAP *ld, LDAPSortKeyA **sortkeys, LDAPControlA *ret, BOOLEAN critical )
{
LDAPControlA *control;
ULONG result;
@@ -330,8 +295,7 @@ ULONG CDECL ldap_encode_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkeys
* This function is obsolete. Use its equivalent
* ldap_create_sort_control instead.
*/
-ULONG CDECL ldap_encode_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkeys,
- PLDAPControlW ret, BOOLEAN critical )
+ULONG CDECL ldap_encode_sort_controlW( WLDAP32_LDAP *ld, LDAPSortKeyW **sortkeys, LDAPControlW *ret, BOOLEAN critical )
{
LDAPControlW *control;
ULONG result;
@@ -366,7 +330,7 @@ ULONG CDECL ldap_free_controlsA( LDAPControlA **controls )
*
* RETURNS
* LDAP_SUCCESS
- *
+ *
* NOTES
* Obsolete, use ldap_controls_freeW.
*/
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 0ddd4035514..34cd3e98746 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -309,6 +309,11 @@ int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPC
(LDAPControl **)clientctrls );
}
+void CDECL wrap_ldap_control_free( LDAPControlU *control )
+{
+ ldap_control_free( (LDAPControl *)control );
+}
+
int CDECL wrap_ldap_compare_ext( void *ld, const char *dn, const char *attrs, struct bervalU *value,
LDAPControlU **serverctrls, LDAPControlU **clientctrls, ULONG *msg )
{
@@ -324,6 +329,16 @@ int CDECL wrap_ldap_compare_ext_s( void *ld, const char *dn, const char *attrs,
(LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
}
+int CDECL wrap_ldap_create_sort_control( void *ld, LDAPSortKeyU **keylist, int critical, LDAPControlU **control )
+{
+ return ldap_create_sort_control( ld, (LDAPSortKey **)keylist, critical, (LDAPControl **)control );
+}
+
+int CDECL wrap_ldap_create_vlv_control( void *ld, LDAPVLVInfoU *info, LDAPControlU **control )
+{
+ return ldap_create_vlv_control( ld, (LDAPVLVInfo *)info, (LDAPControl **)control );
+}
+
void CDECL wrap_ldap_memfree( void *ptr )
{
return ldap_memfree( ptr );
@@ -392,6 +407,9 @@ static const struct ldap_funcs funcs =
wrap_ldap_add_ext_s,
wrap_ldap_compare_ext,
wrap_ldap_compare_ext_s,
+ wrap_ldap_control_free,
+ wrap_ldap_create_sort_control,
+ wrap_ldap_create_vlv_control,
wrap_ldap_memfree,
wrap_ldap_sasl_bind,
wrap_ldap_sasl_bind_s,
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 0fa1c7e5671..c582e9f923d 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -98,6 +98,9 @@ extern int CDECL wrap_ldap_compare_ext(void *, const char *, const char *, struc
LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_compare_ext_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
LDAPControlU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ldap_control_free(LDAPControlU *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_create_sort_control(void *, LDAPSortKeyU **, int, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_create_vlv_control(void *, LDAPVLVInfoU *, LDAPControlU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
LDAPControlU **, int *) DECLSPEC_HIDDEN;
@@ -130,6 +133,9 @@ struct ldap_funcs
LDAPControlU **, ULONG *);
int (CDECL *ldap_compare_ext_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
LDAPControlU **);
+ void (CDECL *ldap_control_free)(LDAPControlU *);
+ int (CDECL *ldap_create_sort_control)(void *, LDAPSortKeyU **, int, LDAPControlU **);
+ int (CDECL *ldap_create_vlv_control)(void *, LDAPVLVInfoU *, LDAPControlU **);
void (CDECL *ldap_memfree)(void *);
int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
int *);
--
2.30.2
1
0
[PATCH 4/5] wldap32: Move support for compare functions to the Unix library.
by Hans Leidekker April 14, 2021
by Hans Leidekker April 14, 2021
April 14, 2021
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/compare.c | 355 ++++++++++-------------------------------
dlls/wldap32/libldap.c | 17 ++
dlls/wldap32/libldap.h | 8 +
3 files changed, 108 insertions(+), 272 deletions(-)
diff --git a/dlls/wldap32/compare.c b/dlls/wldap32/compare.c
index c725aa3a715..7a366572dc9 100644
--- a/dlls/wldap32/compare.c
+++ b/dlls/wldap32/compare.c
@@ -18,56 +18,33 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
/***********************************************************************
* ldap_compareA (WLDAP32.@)
*
* See ldap_compareW.
*/
-ULONG CDECL ldap_compareA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
+ULONG CDECL ldap_compareA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = ~0u;
WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
- ret = ~0u;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
- debugstr_a(value) );
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr), debugstr_a(value) );
if (!ld || !attr) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
-
- attrW = strAtoW( attr );
- if (!attrW) goto exit;
-
- if (value) {
- valueW = strAtoW( value );
- if (!valueW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (!(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
ret = ldap_compareW( ld, dnW, attrW, valueW );
@@ -75,8 +52,6 @@ exit:
strfreeW( dnW );
strfreeW( attrW );
strfreeW( valueW );
-
-#endif
return ret;
}
@@ -95,51 +70,15 @@ exit:
* Success: Message ID of the compare operation.
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_compareW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+ULONG CDECL ldap_compareW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- struct berval val = { 0, NULL };
- int msg;
-
- ret = ~0u;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
- debugstr_w(value) );
-
- if (!ld || !attr) return ~0u;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
-
- attrU = strWtoU( attr );
- if (!attrU) goto exit;
-
- if (value) {
- valueU = strWtoU( value );
- if (!valueU) goto exit;
-
- val.bv_len = strlen( valueU );
- val.bv_val = valueU;
- }
+ ULONG msg, ret;
- ret = ldap_compare_ext( ld->ld, dn ? dnU : "", attrU, &val, NULL, NULL, &msg );
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value) );
- if (ret == LDAP_SUCCESS)
- ret = msg;
- else
- ret = ~0u;
-
-exit:
- strfreeU( dnU );
- strfreeU( attrU );
- strfreeU( valueU );
-
-#endif
- return ret;
+ ret = ldap_compare_extW( ld, dn, attr, value, NULL, NULL, NULL, &msg );
+ if (ret == WLDAP32_LDAP_SUCCESS) return msg;
+ return ~0u;
}
/***********************************************************************
@@ -147,46 +86,26 @@ exit:
*
* See ldap_compare_extW.
*/
-ULONG CDECL ldap_compare_extA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
- struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls,
+ULONG CDECL ldap_compare_extA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value,
+ struct WLDAP32_berval *data, LDAPControlA **serverctrls, LDAPControlA **clientctrls,
ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
- debugstr_a(attr), debugstr_a(value), data, serverctrls,
- clientctrls, message );
+ TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), debugstr_a(attr), debugstr_a(value),
+ data, serverctrls, clientctrls, message );
if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attr) {
- attrW = strAtoW( attr );
- if (!attrW) goto exit;
- }
- if (value) {
- valueW = strAtoW( value );
- if (!valueW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
- ret = ldap_compare_extW( ld, dnW, attrW, valueW, data,
- serverctrlsW, clientctrlsW, message );
+ ret = ldap_compare_extW( ld, dnW, attrW, valueW, data, serverctrlsW, clientctrlsW, message );
exit:
strfreeW( dnW );
@@ -194,8 +113,6 @@ exit:
strfreeW( valueW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -223,62 +140,45 @@ exit:
* both are non-NULL, data will be used. The serverctrls and clientctrls
* parameters are optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_compare_extW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
- struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls,
- ULONG *message )
+ULONG CDECL ldap_compare_extW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value,
+ struct WLDAP32_berval *data, LDAPControlW **serverctrls, LDAPControlW **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval val = { 0, NULL };
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU = NULL, val = { 0, NULL };
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
- debugstr_w(attr), debugstr_w(value), data, serverctrls,
- clientctrls, message );
+ TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value),
+ data, serverctrls, clientctrls, message );
if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
if (!attr) return WLDAP32_LDAP_NO_MEMORY;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
-
- attrU = strWtoU( attr );
- if (!attrU) goto exit;
-
- if (!data) {
- if (value) {
- valueU = strWtoU( value );
- if (!valueU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (!(attrU = strWtoU( attr ))) goto exit;
+ if (!data)
+ {
+ if (value)
+ {
+ if (!(valueU = strWtoU( value ))) goto exit;
val.bv_len = strlen( valueU );
val.bv_val = valueU;
}
}
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ else if (!(dataU = bervalWtoU( data ))) goto exit;
- ret = map_error( ldap_compare_ext( ld->ld, dn ? dnU : "", attrU, data ? (struct berval *)data : &val,
- serverctrlsU, clientctrlsU, (int *)message ));
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+ ret = map_error( ldap_funcs->ldap_compare_ext( ld->ld, dnU, attrU, dataU ? dataU : &val, serverctrlsU,
+ clientctrlsU, message ) );
exit:
strfreeU( dnU );
strfreeU( attrU );
strfreeU( valueU );
+ bvfreeU( dataU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -287,45 +187,25 @@ exit:
*
* See ldap_compare_ext_sW.
*/
-ULONG CDECL ldap_compare_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
- struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
+ULONG CDECL ldap_compare_ext_sA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value,
+ struct WLDAP32_berval *data, LDAPControlA **serverctrls, LDAPControlA **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_a(dn),
- debugstr_a(attr), debugstr_a(value), data, serverctrls,
- clientctrls );
+ TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_a(dn), debugstr_a(attr), debugstr_a(value),
+ data, serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attr) {
- attrW = strAtoW( attr );
- if (!attrW) goto exit;
- }
- if (value) {
- valueW = strAtoW( value );
- if (!valueW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
- ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW,
- clientctrlsW );
+ ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW, clientctrlsW );
exit:
strfreeW( dnW );
@@ -333,8 +213,6 @@ exit:
strfreeW( valueW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -361,61 +239,44 @@ exit:
* both are non-NULL, data will be used. The serverctrls and clientctrls
* parameters are optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
- struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
+ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value,
+ struct WLDAP32_berval *data, LDAPControlW **serverctrls, LDAPControlW **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval val = { 0, NULL };
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU = NULL, val = { 0, NULL };
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_w(dn),
- debugstr_w(attr), debugstr_w(value), data, serverctrls,
- clientctrls );
+ TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value), data,
+ serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attr) {
- attrU = strWtoU( attr );
- if (!attrU) goto exit;
- }
- if (!data) {
- if (value) {
- valueU = strWtoU( value );
- if (!valueU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attr && !(attrU = strWtoU( attr ))) goto exit;
+ if (!data)
+ {
+ if (value)
+ {
+ if (!(valueU = strWtoU( value ))) goto exit;
val.bv_len = strlen( valueU );
val.bv_val = valueU;
}
}
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ else if (!(dataU = bervalWtoU( data ))) goto exit;
- ret = map_error( ldap_compare_ext_s( ld->ld, dn ? dnU : "", attr ? attrU : "",
- data ? (struct berval *)data : &val,
- serverctrlsU, clientctrlsU ));
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+ ret = map_error( ldap_funcs->ldap_compare_ext_s( ld->ld, dnU, attrU, dataU ? dataU : &val, serverctrlsU,
+ clientctrlsU ) );
exit:
strfreeU( dnU );
strfreeU( attrU );
strfreeU( valueU );
+ bvfreeU( dataU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -426,29 +287,16 @@ exit:
*/
ULONG CDECL ldap_compare_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
- debugstr_a(value) );
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr), debugstr_a(value) );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attr) {
- attrW = strAtoW( attr );
- if (!attrW) goto exit;
- }
- if (value) {
- valueW = strAtoW( value );
- if (!valueW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
ret = ldap_compare_sW( ld, dnW, attrW, valueW );
@@ -456,8 +304,6 @@ exit:
strfreeW( dnW );
strfreeW( attrW );
strfreeW( valueW );
-
-#endif
return ret;
}
@@ -476,43 +322,8 @@ exit:
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- struct berval val = { 0, NULL };
-
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
- debugstr_w(value) );
-
- if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attr) {
- attrU = strWtoU( attr );
- if (!attrU) goto exit;
- }
- if (value) {
- valueU = strWtoU( value );
- if (!valueU) goto exit;
-
- val.bv_len = strlen( valueU );
- val.bv_val = valueU;
- }
-
- ret = map_error( ldap_compare_ext_s( ld->ld, dn ? dnU : "", attr ? attrU : "", &val, NULL, NULL ));
-
-exit:
- strfreeU( dnU );
- strfreeU( attrU );
- strfreeU( valueU );
-
-#endif
- return ret;
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value) );
+ return ldap_compare_ext_sW( ld, dn, attr, value, NULL, NULL, NULL );
}
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 380c589257b..0ddd4035514 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -309,6 +309,21 @@ int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPC
(LDAPControl **)clientctrls );
}
+int CDECL wrap_ldap_compare_ext( void *ld, const char *dn, const char *attrs, struct bervalU *value,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, ULONG *msg )
+{
+ int dummy;
+ return ldap_compare_ext( ld, dn ? dn : "", attrs ? attrs : "", (struct berval *)value,
+ (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
+}
+
+int CDECL wrap_ldap_compare_ext_s( void *ld, const char *dn, const char *attrs, struct bervalU *value,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_compare_ext_s( ld, dn ? dn : "", attrs ? attrs : "", (struct berval *)value,
+ (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
void CDECL wrap_ldap_memfree( void *ptr )
{
return ldap_memfree( ptr );
@@ -375,6 +390,8 @@ static const struct ldap_funcs funcs =
wrap_ber_scanf,
wrap_ldap_add_ext,
wrap_ldap_add_ext_s,
+ wrap_ldap_compare_ext,
+ wrap_ldap_compare_ext_s,
wrap_ldap_memfree,
wrap_ldap_sasl_bind,
wrap_ldap_sasl_bind_s,
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 9b4f941d677..0fa1c7e5671 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -94,6 +94,10 @@ extern int CDECL wrap_ldap_add_ext(void *, const char *, LDAPModU **, LDAPContro
ULONG *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_add_ext_s(void *, const char *, LDAPModU **, LDAPControlU **,
LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_compare_ext(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_compare_ext_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
LDAPControlU **, int *) DECLSPEC_HIDDEN;
@@ -122,6 +126,10 @@ struct ldap_funcs
int (CDECL *ldap_add_ext)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
int (CDECL *ldap_add_ext_s)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+ int (CDECL *ldap_compare_ext)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, ULONG *);
+ int (CDECL *ldap_compare_ext_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **);
void (CDECL *ldap_memfree)(void *);
int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
int *);
--
2.30.2
1
0
[PATCH 3/5] wldap32: Move support for bind functions to the Unix library.
by Hans Leidekker April 14, 2021
by Hans Leidekker April 14, 2021
April 14, 2021
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/bind.c | 419 ++++++++++-----------------------
dlls/wldap32/libldap.c | 58 ++++-
dlls/wldap32/libldap.h | 52 +++-
dlls/wldap32/main.c | 6 +-
dlls/wldap32/option.c | 6 +-
dlls/wldap32/winldap_private.h | 2 +-
6 files changed, 234 insertions(+), 309 deletions(-)
diff --git a/dlls/wldap32/bind.c b/dlls/wldap32/bind.c
index 1498dc49fe6..0078b532e66 100644
--- a/dlls/wldap32/bind.c
+++ b/dlls/wldap32/bind.c
@@ -18,63 +18,40 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "rpc.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
/***********************************************************************
* ldap_bindA (WLDAP32.@)
*
* See ldap_bindW.
*/
-ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *credW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (cred) {
- credW = strAtoW( cred );
- if (!credW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (cred && !(credW = strAtoW( cred ))) goto exit;
ret = ldap_bindW( ld, dnW, credW, method );
exit:
strfreeW( dnW );
strfreeW( credW );
-
-#endif
return ret;
}
@@ -96,36 +73,28 @@ exit:
* NOTES
* Only LDAP_AUTH_SIMPLE is supported (just like native).
*/
-ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *credU = NULL;
- struct berval pwd = { 0, NULL };
+ struct bervalU pwd = { 0, NULL };
int msg;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
if (!ld) return ~0u;
- if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (cred) {
- credU = strWtoU( cred );
- if (!credU) goto exit;
+ if (method != WLDAP32_LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (cred)
+ {
+ if (!(credU = strWtoU( cred ))) goto exit;
pwd.bv_len = strlen( credU );
pwd.bv_val = credU;
}
- ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
ret = msg;
else
ret = ~0u;
@@ -133,8 +102,6 @@ ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
exit:
strfreeU( dnU );
strfreeU( credU );
-
-#endif
return ret;
}
@@ -143,30 +110,23 @@ exit:
*
* See ldap_bind_sW.
*/
-ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *credW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (cred) {
- if (method == LDAP_AUTH_SIMPLE)
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (cred)
+ {
+ if (method == WLDAP32_LDAP_AUTH_SIMPLE)
{
- credW = strAtoW( cred );
- if (!credW) goto exit;
+ if (!(credW = strAtoW( cred ))) goto exit;
}
- else
- credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
+ else credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
}
ret = ldap_bind_sW( ld, dnW, credW, method );
@@ -174,24 +134,19 @@ ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
exit:
strfreeW( dnW );
if (credW != (WCHAR *)cred) strfreeW( credW );
-
-#endif
return ret;
}
-#ifdef HAVE_LDAP
-
-static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
+int CDECL sasl_interact_cb( void *ld, unsigned flags, void *defaults, void *interact )
{
-#ifdef HAVE_SASL_SASL_H
SEC_WINNT_AUTH_IDENTITY_A *id = defaults;
- sasl_interact_t *sasl = interact;
+ struct sasl_interactU *sasl = interact;
- TRACE( "%p,%08x,%p,%p\n", ld, flags, defaults, interact );
+ TRACE( "(%p, 0x%08x, %p, %p)\n", ld, flags, defaults, interact );
while (sasl->id != SASL_CB_LIST_END)
{
- TRACE("sasl->id = %04lx\n", sasl->id);
+ TRACE( "sasl->id = %04lx\n", sasl->id );
if (sasl->id == SASL_CB_GETREALM)
{
@@ -208,19 +163,12 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
sasl->result = id->Password;
sasl->len = id->PasswordLength;
}
-
sasl++;
}
- return LDAP_SUCCESS;
-#else
- FIXME( "%p,%08x,%p,%p: stub\n", ld, flags, defaults, interact );
- return LDAP_SUCCESS;
-#endif /* HAVE_SASL_SASL_H */
+ return WLDAP32_LDAP_SUCCESS;
}
-#endif /* HAVE_LDAP */
-
/***********************************************************************
* ldap_bind_sW (WLDAP32.@)
*
@@ -236,36 +184,27 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *credU = NULL;
- struct berval pwd = { 0, NULL };
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ struct bervalU pwd = { 0, NULL };
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (method == LDAP_AUTH_SIMPLE)
+ if (method == WLDAP32_LDAP_AUTH_SIMPLE)
{
- if (dn)
- {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
if (cred)
{
- credU = strWtoU( cred );
- if (!credU) goto exit;
-
+ if (!(credU = strWtoU( cred ))) goto exit;
pwd.bv_len = strlen( credU );
pwd.bv_val = credU;
}
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
}
else if (method == WLDAP32_LDAP_AUTH_NEGOTIATE)
{
@@ -274,7 +213,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
memset( &idU, 0, sizeof(idU) );
-
if (id)
{
if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
@@ -283,19 +221,17 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
idW.Domain = (unsigned short *)strnAtoW( (char *)id->Domain, id->DomainLength, &idW.DomainLength );
idW.User = (unsigned short *)strnAtoW( (char *)id->User, id->UserLength, &idW.UserLength );
idW.Password = (unsigned short *)strnAtoW( (char *)id->Password, id->PasswordLength, &idW.PasswordLength );
-
id = &idW;
}
-
idU.Domain = (unsigned char *)strnWtoU( id->Domain, id->DomainLength, &idU.DomainLength );
idU.User = (unsigned char *)strnWtoU( id->User, id->UserLength, &idU.UserLength );
idU.Password = (unsigned char *)strnWtoU( id->Password, id->PasswordLength, &idU.PasswordLength );
}
- ret = map_error( ldap_sasl_interactive_bind_s( ld->ld,
- NULL /* server will ignore DN anyway */,
- NULL /* query supportedSASLMechanisms */,
- NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &idU ));
+ ret = map_error( ldap_funcs->ldap_sasl_interactive_bind_s( ld->ld,
+ NULL /* server will ignore DN anyway */,
+ NULL /* query supportedSASLMechanisms */,
+ NULL, NULL, 2 /* LDAP_SASL_QUIET */, &idU ) );
if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
{
@@ -317,8 +253,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
exit:
strfreeU( dnU );
strfreeU( credU );
-
-#endif
return ret;
}
@@ -327,37 +261,23 @@ exit:
*
* See ldap_sasl_bindW.
*/
-ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn,
- const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+ LDAPControlA **serverctrls, LDAPControlA **clientctrls, int *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW, *mechanismW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
debugstr_a(mechanism), cred, serverctrls, clientctrls, message );
if (!ld || !dn || !mechanism || !cred || !message)
return WLDAP32_LDAP_PARAM_ERROR;
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
-
- mechanismW = strAtoW( mechanism );
- if (!mechanismW) goto exit;
-
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (!(dnW = strAtoW( dn ))) goto exit;
+ if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );
@@ -366,8 +286,6 @@ exit:
strfreeW( mechanismW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -383,7 +301,7 @@ exit:
* cred [I] Credentials.
* serverctrls [I] Array of LDAP server controls.
* clientctrls [I] Array of LDAP client controls.
- * message [O] Message ID of the bind operation.
+ * message [O] Message ID of the bind operation.
*
* RETURNS
* Success: LDAP_SUCCESS
@@ -393,17 +311,13 @@ exit:
* The serverctrls and clientctrls parameters are optional and should
* be set to NULL if not used.
*/
-ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
- const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn, const PWCHAR mechanism, const BERVAL *cred,
+ LDAPControlW **serverctrls, LDAPControlW **clientctrls, int *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU, *mechanismU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval credU;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU credU;
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
@@ -411,34 +325,21 @@ ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
if (!ld || !dn || !mechanism || !cred || !message)
return WLDAP32_LDAP_PARAM_ERROR;
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
-
- mechanismU = strWtoU( mechanism );
- if (!mechanismU) goto exit;
-
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ if (!(dnU = strWtoU( dn ))) goto exit;
+ if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
credU.bv_len = cred->bv_len;
credU.bv_val = cred->bv_val;
- ret = map_error( ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU,
- serverctrlsU, clientctrlsU, message ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, message ) );
exit:
strfreeU( dnU );
strfreeU( mechanismU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -447,37 +348,23 @@ exit:
*
* See ldap_sasl_bind_sW.
*/
-ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
- const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, PBERVAL *serverdata )
+ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+ LDAPControlA **serverctrls, LDAPControlA **clientctrls, BERVAL **serverdata )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW, *mechanismW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
if (!ld || !dn || !mechanism || !cred || !serverdata)
return WLDAP32_LDAP_PARAM_ERROR;
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
-
- mechanismW = strAtoW( mechanism );
- if (!mechanismW) goto exit;
-
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (!(dnW = strAtoW( dn ))) goto exit;
+ if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
@@ -486,8 +373,6 @@ exit:
strfreeW( mechanismW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -514,16 +399,13 @@ exit:
* be set to NULL if not used.
*/
ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
- const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, PBERVAL *serverdata )
+ const PWCHAR mechanism, const BERVAL *cred, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls, BERVAL **serverdata )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU, *mechanismU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval credU;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU, credU;
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
@@ -531,34 +413,28 @@ ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
if (!ld || !dn || !mechanism || !cred || !serverdata)
return WLDAP32_LDAP_PARAM_ERROR;
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
-
- mechanismU = strWtoU( mechanism );
- if (!mechanismU) goto exit;
-
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ if (!(dnU = strWtoU( dn ))) goto exit;
+ if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
credU.bv_len = cred->bv_len;
credU.bv_val = cred->bv_val;
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU,
- serverctrlsU, clientctrlsU, (struct berval **)serverdata ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, &dataU ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
+ {
+ BERVAL *ptr;
+ if (!(ptr = bervalUtoW( dataU ))) ret = WLDAP32_LDAP_NO_MEMORY;
+ else *serverdata = ptr;
+ ldap_funcs->ber_bvfree( dataU );
+ }
exit:
strfreeU( dnU );
strfreeU( mechanismU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -567,34 +443,23 @@ exit:
*
* See ldap_simple_bindW.
*/
-ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, char *dn, char *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *passwdW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (passwd) {
- passwdW = strAtoW( passwd );
- if (!passwdW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
ret = ldap_simple_bindW( ld, dnW, passwdW );
exit:
strfreeW( dnW );
strfreeW( passwdW );
-
-#endif
return ret;
}
@@ -613,37 +478,29 @@ exit:
* Failure: An LDAP error code.
*
* NOTES
- * Set dn and passwd to NULL to bind as an anonymous user.
+ * Set dn and passwd to NULL to bind as an anonymous user.
*/
-ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *passwdU = NULL;
- struct berval pwd = { 0, NULL };
+ struct bervalU pwd = { 0, NULL };
int msg;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
if (!ld) return ~0u;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (passwd) {
- passwdU = strWtoU( passwd );
- if (!passwdU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (passwd)
+ {
+ if (!(passwdU = strWtoU( passwd ))) goto exit;
pwd.bv_len = strlen( passwdU );
pwd.bv_val = passwdU;
}
- ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
ret = msg;
else
ret = ~0u;
@@ -651,8 +508,6 @@ ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
exit:
strfreeU( dnU );
strfreeU( passwdU );
-
-#endif
return ret;
}
@@ -661,34 +516,23 @@ exit:
*
* See ldap_simple_bind_sW.
*/
-ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, char *dn, char *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *passwdW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (passwd) {
- passwdW = strAtoW( passwd );
- if (!passwdW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
ret = ldap_simple_bind_sW( ld, dnW, passwdW );
exit:
strfreeW( dnW );
strfreeW( passwdW );
-
-#endif
return ret;
}
@@ -707,40 +551,31 @@ exit:
* Failure: An LDAP error code.
*
* NOTES
- * Set dn and passwd to NULL to bind as an anonymous user.
+ * Set dn and passwd to NULL to bind as an anonymous user.
*/
-ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *passwdU = NULL;
- struct berval pwd = { 0, NULL };
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ struct bervalU pwd = { 0, NULL };
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (passwd) {
- passwdU = strWtoU( passwd );
- if (!passwdU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (passwd)
+ {
+ if (!(passwdU = strWtoU( passwd ))) goto exit;
pwd.bv_len = strlen( passwdU );
pwd.bv_val = passwdU;
}
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
exit:
strfreeU( dnU );
strfreeU( passwdU );
-
-#endif
return ret;
}
@@ -758,22 +593,16 @@ exit:
*/
ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
TRACE( "(%p)\n", ld );
- if (ld)
- {
- ret = map_error( ldap_unbind_ext( ld->ld, NULL, NULL ));
- if ( ld->ld_server_ctrls )
- ldap_value_free_len( ld->ld_server_ctrls );
- heap_free( ld );
- }
- else
- ret = WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+ ret = map_error( ldap_funcs->ldap_unbind_ext( ld->ld, NULL, NULL ));
+ if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
-#endif
+ heap_free( ld );
return ret;
}
@@ -791,21 +620,15 @@ ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
*/
ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
TRACE( "(%p)\n", ld );
- if (ld)
- {
- ret = map_error( ldap_unbind_ext_s( ld->ld, NULL, NULL ));
- if ( ld->ld_server_ctrls )
- ldap_value_free_len( ld->ld_server_ctrls );
- heap_free( ld );
- }
- else
- ret = WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+ ret = map_error( ldap_funcs->ldap_unbind_ext_s( ld->ld, NULL, NULL ) );
+ if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
-#endif
+ heap_free( ld );
return ret;
}
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 3436cffc4a1..380c589257b 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -52,6 +52,8 @@ C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
static LDAPMod *nullattrs[] = { NULL };
+static const struct ldap_callbacks *callbacks;
+
void * CDECL wrap_ber_alloc_t( int options )
{
return ber_alloc_t( options );
@@ -292,7 +294,7 @@ int WINAPIV wrap_ber_scanf( void *ber, char *fmt, ... )
return ret;
}
-int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
LDAPControlU **clientctrls, ULONG *msg )
{
int dummy;
@@ -300,7 +302,7 @@ int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU
(LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
}
-int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
LDAPControlU **clientctrls )
{
return ldap_add_ext_s( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
@@ -312,6 +314,51 @@ void CDECL wrap_ldap_memfree( void *ptr )
return ldap_memfree( ptr );
}
+int CDECL wrap_ldap_sasl_bind( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, int *msgid )
+{
+ return ldap_sasl_bind( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, msgid );
+}
+
+int CDECL wrap_ldap_sasl_bind_s( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, struct bervalU **servercred )
+{
+ return ldap_sasl_bind_s( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, (struct berval **)servercred );
+}
+
+static int wrap_sasl_interact( LDAP *ld, unsigned int flags, void *defaults, void *interact )
+{
+#ifdef HAVE_SASL_SASL_H
+ C_ASSERT( sizeof(struct sasl_interactU) == sizeof(struct sasl_interact) );
+ return callbacks->sasl_interact( ld, flags, defaults, interact );
+#endif
+ return -1;
+}
+
+int CDECL wrap_ldap_sasl_interactive_bind_s( void *ld, const char *dn, const char *mech, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls, unsigned int flags, void *defaults )
+{
+ return ldap_sasl_interactive_bind_s( ld, dn, mech, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, flags,
+ wrap_sasl_interact, defaults );
+}
+
+int CDECL wrap_ldap_unbind_ext( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_unbind_ext( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+int CDECL wrap_ldap_unbind_ext_s( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_unbind_ext_s( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+void CDECL wrap_ldap_value_free_len( struct bervalU **values )
+{
+ ldap_value_free_len( (struct berval **)values );
+}
+
static const struct ldap_funcs funcs =
{
wrap_ber_alloc_t,
@@ -329,11 +376,18 @@ static const struct ldap_funcs funcs =
wrap_ldap_add_ext,
wrap_ldap_add_ext_s,
wrap_ldap_memfree,
+ wrap_ldap_sasl_bind,
+ wrap_ldap_sasl_bind_s,
+ wrap_ldap_sasl_interactive_bind_s,
+ wrap_ldap_unbind_ext,
+ wrap_ldap_unbind_ext_s,
+ wrap_ldap_value_free_len,
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
{
if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ callbacks = ptr_in;
*(const struct ldap_funcs **)ptr_out = &funcs;
return STATUS_SUCCESS;
}
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 4ca90d298a0..9b4f941d677 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -60,6 +60,23 @@ typedef struct
void *ldvlv_extradata;
} LDAPVLVInfoU;
+#ifndef SASL_CB_LIST_END
+#define SASL_CB_LIST_END 0
+#define SASL_CB_USER 0x4001
+#define SASL_CB_PASS 0x4004
+#define SASL_CB_GETREALM 0x4008
+#endif
+
+typedef struct sasl_interactU
+{
+ unsigned long id;
+ const char *challenge;
+ const char *prompt;
+ const char *defresult;
+ const void *result;
+ unsigned int len;
+} sasl_interact_tU;
+
extern void * CDECL wrap_ber_alloc_t(int) DECLSPEC_HIDDEN;
extern void CDECL wrap_ber_bvecfree(struct bervalU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ber_bvfree(struct bervalU *) DECLSPEC_HIDDEN;
@@ -73,9 +90,20 @@ extern unsigned int CDECL wrap_ber_skip_tag(void *, unsigned int *) DECLSPEC_HID
extern int WINAPIV wrap_ber_printf(void *, char *, ...) DECLSPEC_HIDDEN;
extern int WINAPIV wrap_ber_scanf(void *, char *, ...) DECLSPEC_HIDDEN;
-extern int CDECL wrap_ldap_add_ext(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
-extern int CDECL wrap_ldap_add_ext_s(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **,
+ ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext_s(void *, const char *, LDAPModU **, LDAPControlU **,
+ LDAPControlU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, int *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, struct bervalU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_interactive_bind_s(void *, const char *, const char *, LDAPControlU **,
+ LDAPControlU **, unsigned int, void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext_s(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ldap_value_free_len(struct bervalU **) DECLSPEC_HIDDEN;
struct ldap_funcs
{
@@ -92,9 +120,25 @@ struct ldap_funcs
int (WINAPIV *ber_printf)(void *, char *, ...);
int (WINAPIV *ber_scanf)(void *, char *, ...);
- int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
- int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+ int (CDECL *ldap_add_ext)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
+ int (CDECL *ldap_add_ext_s)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
void (CDECL *ldap_memfree)(void *);
+ int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
+ int *);
+ int (CDECL *ldap_sasl_bind_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, struct bervalU **);
+ int (CDECL *ldap_sasl_interactive_bind_s)(void *, const char *, const char *, LDAPControlU **, LDAPControlU **,
+ unsigned int, void *);
+ int (CDECL *ldap_unbind_ext)(void *, LDAPControlU **, LDAPControlU **);
+ int (CDECL *ldap_unbind_ext_s)(void *, LDAPControlU **, LDAPControlU **);
+ void (CDECL *ldap_value_free_len)(struct bervalU **);
+};
+
+extern int CDECL sasl_interact_cb(void *, unsigned int, void *, void *) DECLSPEC_HIDDEN;
+
+struct ldap_callbacks
+{
+ int (CDECL *sasl_interact)(void *, unsigned int, void *, void *);
};
extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/main.c b/dlls/wldap32/main.c
index 55a08c9bad5..c2fdf30f820 100644
--- a/dlls/wldap32/main.c
+++ b/dlls/wldap32/main.c
@@ -31,6 +31,10 @@ HINSTANCE hwldap32;
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
const struct ldap_funcs *ldap_funcs = NULL;
+const struct ldap_callbacks ldap_callbacks =
+{
+ sasl_interact_cb
+};
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
@@ -41,7 +45,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH:
hwldap32 = hinst;
DisableThreadLibraryCalls( hinst );
- if (__wine_init_unix_lib( hinst, reason, NULL, &ldap_funcs ))
+ if (__wine_init_unix_lib( hinst, reason, &ldap_callbacks, &ldap_funcs ))
ERR( "No libldap support, expect problems\n" );
break;
}
diff --git a/dlls/wldap32/option.c b/dlls/wldap32/option.c
index 388432a442c..8398dff67e4 100644
--- a/dlls/wldap32/option.c
+++ b/dlls/wldap32/option.c
@@ -416,8 +416,8 @@ static BOOL query_supported_server_ctrls( WLDAP32_LDAP *ld )
{
ULONG count, i;
- ld->ld_server_ctrls = ldap_get_values_len( ld->ld, entry, attrs[0] );
- count = ldap_count_values_len( ld->ld_server_ctrls );
+ ld->ld_server_ctrls = (struct bervalU **)ldap_get_values_len( ld->ld, entry, attrs[0] );
+ count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
for (i = 0; i < count; i++)
TRACE("%u: %s\n", i, debugstr_an( ld->ld_server_ctrls[i]->bv_val, ld->ld_server_ctrls[i]->bv_len ));
}
@@ -435,7 +435,7 @@ static BOOL is_supported_server_ctrls( WLDAP32_LDAP *ld, LDAPControl **ctrls )
return TRUE; /* can't verify, let the server handle it on next query */
user_count = controlarraylenU( ctrls );
- server_count = ldap_count_values_len( ld->ld_server_ctrls );
+ server_count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
for (n = 0; n < user_count; n++)
{
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 22e981cb26d..20fc676c7e2 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -144,7 +144,7 @@ typedef struct wldap32
ULONG ld_refhoplimit;
ULONG ld_options;
/* internal LDAP context */
- struct berval **ld_server_ctrls;
+ struct bervalU **ld_server_ctrls;
void *ld;
} WLDAP32_LDAP, *WLDAP32_PLDAP;
--
2.30.2
1
0
[PATCH 2/5] wldap32: Move support for ber functions to the Unix library.
by Hans Leidekker April 14, 2021
by Hans Leidekker April 14, 2021
April 14, 2021
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/ber.c | 348 ++++++++++++++-------------------
dlls/wldap32/libldap.c | 260 ++++++++++++++++++++++++
dlls/wldap32/libldap.h | 28 +++
dlls/wldap32/misc.c | 28 ++-
dlls/wldap32/winldap_private.h | 22 +++
include/winber.h | 6 +
6 files changed, 477 insertions(+), 215 deletions(-)
diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c
index 7f39b9cfe17..ae5e9292e04 100644
--- a/dlls/wldap32/ber.c
+++ b/dlls/wldap32/ber.c
@@ -18,24 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
-#include "winldap_private.h"
-#include "wldap32.h"
+#include "winnls.h"
+
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
-
-#define WLDAP32_LBER_ERROR (~0U)
/***********************************************************************
* ber_alloc_t (WLDAP32.@)
@@ -52,13 +44,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
* NOTES
* Free the berelement structure with ber_free.
*/
-WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
+WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t( int options )
{
-#ifdef HAVE_LDAP
- return ber_alloc_t( options );
-#else
- return NULL;
-#endif
+ WLDAP32_BerElement *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ if (!(ret->opaque = ldap_funcs->ber_alloc_t( options )))
+ {
+ heap_free( ret );
+ return NULL;
+ }
+ return ret;
}
@@ -98,7 +94,7 @@ BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
* Use this function only to free an array of berval structures
* returned by a call to ber_scanf with a 'V' in the format string.
*/
-void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
+void CDECL WLDAP32_ber_bvecfree( BERVAL **berval )
{
bvarrayfreeW( berval );
}
@@ -142,26 +138,9 @@ void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
* NOTES
* len and cookie should be passed to ber_next_element.
*/
-ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR **opaque )
+ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *ber, ULONG *len, char **opaque )
{
-#ifdef HAVE_LDAP
- ber_len_t len;
- ber_tag_t ret;
-
- if ((ret = ber_first_element( berelement, &len, opaque )) != LBER_ERROR)
- {
- if (len > ~0u)
- {
- ERR( "len too large\n" );
- return WLDAP32_LBER_ERROR;
- }
- *ret_len = len;
- }
- return ret;
-
-#else
- return WLDAP32_LBER_ERROR;
-#endif
+ return ldap_funcs->ber_first_element( ber->opaque, len, opaque );
}
@@ -181,23 +160,18 @@ ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *re
* NOTES
* Free the berval structure with ber_bvfree.
*/
-INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval )
+int CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *ber, BERVAL **berval )
{
-#ifdef HAVE_LDAP
- struct berval *bervalU;
+ struct bervalU *bervalU;
struct WLDAP32_berval *bervalW;
- if (ber_flatten( berelement, &bervalU )) return WLDAP32_LBER_ERROR;
+ if (ldap_funcs->ber_flatten( ber->opaque, &bervalU )) return WLDAP32_LBER_ERROR;
- bervalW = bervalUtoW( bervalU );
- ber_bvfree( bervalU );
+ if (!(bervalW = bervalUtoW( bervalU ))) return WLDAP32_LBER_ERROR;
+ ldap_funcs->ber_bvfree( bervalU );
if (!bervalW) return WLDAP32_LBER_ERROR;
*berval = bervalW;
return 0;
-
-#else
- return WLDAP32_LBER_ERROR;
-#endif
}
@@ -217,11 +191,10 @@ INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval )
* Set buf to 0 if the berelement was allocated with ldap_first_attribute
* or ldap_next_attribute, otherwise set it to 1.
*/
-void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf )
+void CDECL WLDAP32_ber_free( WLDAP32_BerElement *ber, int freebuf )
{
-#ifdef HAVE_LDAP
- ber_free( berelement, buf );
-#endif
+ ldap_funcs->ber_free( ber->opaque, freebuf );
+ heap_free( ber );
}
@@ -242,17 +215,22 @@ void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf )
*/
WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
{
-#ifdef HAVE_LDAP
- struct berval *bervalU;
+ struct bervalU *bervalU;
WLDAP32_BerElement *ret;
- if (!(bervalU = bervalWtoU( berval ))) return NULL;
- ret = ber_init( bervalU );
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+ if (!(bervalU = bervalWtoU( berval )))
+ {
+ heap_free( ret );
+ return NULL;
+ }
+ if (!(ret->opaque = ldap_funcs->ber_init( bervalU )))
+ {
+ heap_free( ret );
+ ret = NULL;
+ }
heap_free( bervalU );
return ret;
-#else
- return NULL;
-#endif
}
@@ -274,26 +252,9 @@ WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
* len and cookie are initialized by ber_first_element and should
* be passed on in subsequent calls to ber_next_element.
*/
-ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR *opaque )
+ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *ber, ULONG *len, char *opaque )
{
-#ifdef HAVE_LDAP
- ber_len_t len;
- ber_tag_t ret;
-
- if ((ret = ber_next_element( berelement, &len, opaque )) != LBER_ERROR)
- {
- if (len > ~0u)
- {
- ERR( "len too large\n" );
- return WLDAP32_LBER_ERROR;
- }
- *ret_len = len;
- }
- return ret;
-
-#else
- return WLDAP32_LBER_ERROR;
-#endif
+ return ldap_funcs->ber_next_element( ber->opaque, len, opaque );
}
@@ -310,26 +271,9 @@ ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret
* Success: Tag of the next element.
* Failure: LBER_DEFAULT (no more data).
*/
-ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
+ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *ber, ULONG *len )
{
-#ifdef HAVE_LDAP
- ber_len_t len;
- ber_tag_t ret;
-
- if ((ret = ber_peek_tag( berelement, &len )) != LBER_ERROR)
- {
- if (len > ~0u)
- {
- ERR( "len too large\n" );
- return WLDAP32_LBER_ERROR;
- }
- *ret_len = len;
- }
- return ret;
-
-#else
- return WLDAP32_LBER_ERROR;
-#endif
+ return ldap_funcs->ber_peek_tag( ber->opaque, len );
}
@@ -346,26 +290,9 @@ ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len
* Success: Tag of the next element.
* Failure: LBER_DEFAULT (no more data).
*/
-ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
+ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *ber, ULONG *len )
{
-#ifdef HAVE_LDAP
- ber_len_t len;
- ber_tag_t ret;
-
- if ((ret = ber_skip_tag( berelement, &len )) != LBER_ERROR)
- {
- if (len > ~0u)
- {
- ERR( "len too large\n" );
- return WLDAP32_LBER_ERROR;
- }
- *ret_len = len;
- }
- return ret;
-
-#else
- return WLDAP32_LBER_ERROR;
-#endif
+ return ldap_funcs->ber_skip_tag( ber->opaque, len );
}
@@ -380,16 +307,15 @@ ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len
* ... [I] Values to encode.
*
* RETURNS
- * Success: Non-negative number.
+ * Success: Non-negative number.
* Failure: LBER_ERROR
*
* NOTES
* berelement must have been allocated with ber_alloc_t. This function
* can be called multiple times to append data.
*/
-INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
+int WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *ber, char *fmt, ... )
{
-#ifdef HAVE_LDAP
__ms_va_list list;
int ret = 0;
char new_fmt[2];
@@ -399,63 +325,64 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
while (*fmt)
{
new_fmt[0] = *fmt++;
- switch(new_fmt[0])
+ switch (new_fmt[0])
{
case 'b':
case 'e':
case 'i':
- {
- int i = va_arg( list, int );
- ret = ber_printf( berelement, new_fmt, i );
- break;
- }
+ {
+ int i = va_arg( list, int );
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, i );
+ break;
+ }
case 'o':
case 's':
- {
- char *str = va_arg( list, char * );
- ret = ber_printf( berelement, new_fmt, str );
- break;
- }
+ {
+ char *str = va_arg( list, char * );
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, str );
+ break;
+ }
case 't':
- {
- unsigned int tag = va_arg( list, unsigned int );
- ret = ber_printf( berelement, new_fmt, tag );
- break;
- }
+ {
+ unsigned int tag = va_arg( list, unsigned int );
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, tag );
+ break;
+ }
case 'v':
- {
- char **array = va_arg( list, char ** );
- ret = ber_printf( berelement, new_fmt, array );
- break;
- }
+ {
+ char **array = va_arg( list, char ** );
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, array );
+ break;
+ }
case 'V':
+ {
+ struct WLDAP32_berval **array = va_arg( list, struct WLDAP32_berval ** );
+ struct bervalU **arrayU;
+ if (!(arrayU = bvarrayWtoU( array )))
{
- struct WLDAP32_berval **array = va_arg( list, struct WLDAP32_berval ** );
- struct berval **arrayU;
- if (!(arrayU = bvarrayWtoU( array )))
- {
- ret = -1;
- break;
- }
- ret = ber_printf( berelement, new_fmt, arrayU );
- bvarrayfreeU( arrayU );
+ ret = -1;
break;
}
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, arrayU );
+ bvarrayfreeU( arrayU );
+ break;
+ }
case 'X':
- {
- char *str = va_arg( list, char * );
- int len = va_arg( list, int );
- new_fmt[0] = 'B'; /* 'X' is deprecated */
- ret = ber_printf( berelement, new_fmt, str, len );
- break;
- }
+ {
+ char *str = va_arg( list, char * );
+ int len = va_arg( list, int );
+ new_fmt[0] = 'B'; /* 'X' is deprecated */
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, str, len );
+ break;
+ }
case 'n':
case '{':
case '}':
case '[':
case ']':
- ret = ber_printf( berelement, new_fmt );
+ ret = ldap_funcs->ber_printf( ber->opaque, new_fmt );
break;
+
default:
FIXME( "Unknown format '%c'\n", new_fmt[0] );
ret = -1;
@@ -465,9 +392,6 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
}
__ms_va_end( list );
return ret;
-#else
- return WLDAP32_LBER_ERROR;
-#endif
}
@@ -482,16 +406,15 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
* ... [I] Pointers to values to be decoded.
*
* RETURNS
- * Success: Non-negative number.
+ * Success: Non-negative number.
* Failure: LBER_ERROR
*
* NOTES
* berelement must have been allocated with ber_init. This function
* can be called multiple times to decode data.
*/
-INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
+int WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *ber, char *fmt, ... )
{
-#ifdef HAVE_LDAP
__ms_va_list list;
int ret = 0;
char new_fmt[2];
@@ -501,65 +424,81 @@ INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
while (*fmt)
{
new_fmt[0] = *fmt++;
- switch(new_fmt[0])
+ switch (new_fmt[0])
{
case 'a':
- {
- char **ptr = va_arg( list, char ** );
- ret = ber_scanf( berelement, new_fmt, ptr );
- break;
- }
+ {
+ char *str, **ptr = va_arg( list, char ** );
+ if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &str )) == -1) break;
+ *ptr = strdupU( str );
+ ldap_funcs->ldap_memfree( str );
+ break;
+ }
case 'b':
case 'e':
case 'i':
- {
- int *i = va_arg( list, int * );
- ret = ber_scanf( berelement, new_fmt, i );
- break;
- }
+ {
+ int *i = va_arg( list, int * );
+ ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, i );
+ break;
+ }
case 't':
- {
- unsigned int *tag = va_arg( list, unsigned int * );
- ret = ber_scanf( berelement, new_fmt, tag );
- break;
- }
+ {
+ unsigned int *tag = va_arg( list, unsigned int * );
+ ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, tag );
+ break;
+ }
case 'v':
+ {
+ char *str, **arrayU, **ptr, ***array = va_arg( list, char *** );
+ if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &arrayU )) == -1) break;
+ *array = strarrayUtoU( arrayU );
+ ptr = arrayU;
+ while ((str = *ptr))
{
- char ***array = va_arg( list, char *** );
- ret = ber_scanf( berelement, new_fmt, array );
- break;
+ ldap_funcs->ldap_memfree( str );
+ ptr++;
}
+ ldap_funcs->ldap_memfree( arrayU );
+ break;
+ }
case 'B':
- {
- char **str = va_arg( list, char ** );
- int *len = va_arg( list, int * );
- ret = ber_scanf( berelement, new_fmt, str, len );
- break;
- }
+ {
+ char *strU, **str = va_arg( list, char ** );
+ int *len = va_arg( list, int * );
+ if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &strU, len )) == -1) break;
+ *str = heap_alloc( *len );
+ memcpy( *str, strU, *len );
+ ldap_funcs->ldap_memfree( strU );
+ break;
+ }
case 'O':
- {
- struct berval **ptr = va_arg( list, struct berval ** );
- ret = ber_scanf( berelement, new_fmt, ptr );
- break;
- }
+ {
+ struct WLDAP32_berval **berval = va_arg( list, struct WLDAP32_berval ** );
+ struct bervalU *bervalU;
+ if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &bervalU )) == -1) break;
+ *berval = bervalUtoW( bervalU );
+ ldap_funcs->ber_bvfree( bervalU );
+ break;
+ }
case 'V':
- {
- struct WLDAP32_berval **arrayW, ***array = va_arg( list, struct WLDAP32_berval *** );
- struct berval **arrayU;
- if ((ret = ber_scanf( berelement, new_fmt, &arrayU )) == -1) break;
- if ((arrayW = bvarrayUtoW( arrayU ))) *array = arrayW;
- else ret = -1;
- bvarrayfreeU( arrayU );
- break;
- }
+ {
+ struct WLDAP32_berval ***array = va_arg( list, struct WLDAP32_berval *** );
+ struct bervalU **arrayU;
+ if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &arrayU )) == -1) break;
+ *array = bvarrayUtoW( arrayU );
+ ldap_funcs->ber_bvecfree( arrayU );
+ break;
+ }
case 'n':
case 'x':
case '{':
case '}':
case '[':
case ']':
- ret = ber_scanf( berelement, new_fmt );
+ ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt );
break;
+
default:
FIXME( "Unknown format '%c'\n", new_fmt[0] );
ret = -1;
@@ -569,7 +508,4 @@ INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
}
__ms_va_end( list );
return ret;
-#else
- return WLDAP32_LBER_ERROR;
-#endif
}
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 0372206062a..3436cffc4a1 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -42,6 +42,8 @@
#include "wine/debug.h"
#include "winldap_private.h"
+WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
+
C_ASSERT( sizeof(BerValueU) == sizeof(BerValue) );
C_ASSERT( sizeof(LDAPModU) == sizeof(LDAPMod) );
C_ASSERT( sizeof(LDAPControlU) == sizeof(LDAPControl) );
@@ -50,6 +52,246 @@ C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
static LDAPMod *nullattrs[] = { NULL };
+void * CDECL wrap_ber_alloc_t( int options )
+{
+ return ber_alloc_t( options );
+}
+
+void CDECL wrap_ber_bvecfree( struct bervalU **berval )
+{
+ ber_bvecfree( (struct berval **)berval );
+}
+
+void CDECL wrap_ber_bvfree( struct bervalU *berval )
+{
+ ber_bvfree( (struct berval *)berval );
+}
+
+unsigned int CDECL wrap_ber_first_element( void *ber, ULONG *ret_len, char **last )
+{
+ ber_len_t len;
+ ber_tag_t ret;
+
+ if ((ret = ber_first_element( ber, &len, last )) == LBER_ERROR) return WLDAP32_LBER_ERROR;
+ if (ret > ~0u)
+ {
+ ERR( "ret too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+ if (len > ~0u)
+ {
+ ERR( "len too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+
+ *ret_len = len;
+ return ret;
+}
+
+int CDECL wrap_ber_flatten( void *ber, struct bervalU **berval )
+{
+ return ber_flatten( ber, (struct berval **)berval );
+}
+
+void CDECL wrap_ber_free( void *ber, int freebuf )
+{
+ ber_free( ber, freebuf );
+}
+
+void * CDECL wrap_ber_init( struct bervalU *berval )
+{
+ return ber_init( (struct berval *)berval );
+}
+
+unsigned int CDECL wrap_ber_next_element( void *ber, unsigned int *ret_len, char *last )
+{
+ ber_len_t len;
+ ber_tag_t ret;
+
+ if ((ret = ber_next_element( ber, &len, last )) == LBER_ERROR) return WLDAP32_LBER_ERROR;
+ if (ret > ~0u)
+ {
+ ERR( "ret too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+ if (len > ~0u)
+ {
+ ERR( "len too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+
+ *ret_len = len;
+ return ret;
+}
+
+unsigned int CDECL wrap_ber_peek_tag( void *ber, unsigned int *ret_len )
+{
+ ber_len_t len;
+ ber_tag_t ret;
+
+ if ((ret = ber_peek_tag( ber, &len )) == LBER_ERROR) return WLDAP32_LBER_ERROR;
+ if (len > ~0u)
+ {
+ ERR( "len too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+
+ *ret_len = len;
+ return ret;
+}
+
+unsigned int CDECL wrap_ber_skip_tag( void *ber, unsigned int *ret_len )
+{
+ ber_len_t len;
+ ber_tag_t ret;
+
+ if ((ret = ber_skip_tag( ber, &len )) == LBER_ERROR) return WLDAP32_LBER_ERROR;
+ if (len > ~0u)
+ {
+ ERR( "len too large\n" );
+ return WLDAP32_LBER_ERROR;
+ }
+
+ *ret_len = len;
+ return ret;
+}
+
+int WINAPIV wrap_ber_printf( void *ber, char *fmt, ... )
+{
+ int ret;
+ __ms_va_list args;
+
+ assert( strlen(fmt) == 1 );
+
+ __ms_va_start( args, fmt );
+ switch (fmt[0])
+ {
+ case 'b':
+ case 'e':
+ case 'i':
+ {
+ int i = va_arg( args, int );
+ ret = ber_printf( ber, fmt, i );
+ break;
+ }
+ case 'o':
+ case 's':
+ {
+ char *str = va_arg( args, char * );
+ ret = ber_printf( ber, fmt, str );
+ break;
+ }
+ case 't':
+ {
+ unsigned int tag = va_arg( args, unsigned int );
+ ret = ber_printf( ber, fmt, tag );
+ break;
+ }
+ case 'v':
+ {
+ char **array = va_arg( args, char ** );
+ ret = ber_printf( ber, fmt, array );
+ break;
+ }
+ case 'V':
+ {
+ struct berval **array = va_arg( args, struct berval ** );
+ ret = ber_printf( ber, fmt, array );
+ break;
+ }
+ case 'B':
+ {
+ char *str = va_arg( args, char * );
+ int len = va_arg( args, int );
+ ret = ber_printf( ber, fmt, str, len );
+ break;
+ }
+ case 'n':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ ret = ber_printf( ber, fmt );
+ break;
+
+ default:
+ assert( 0 );
+ }
+ __ms_va_end( args );
+ return ret;
+}
+
+int WINAPIV wrap_ber_scanf( void *ber, char *fmt, ... )
+{
+ int ret;
+ __ms_va_list args;
+
+ assert( strlen(fmt) == 1 );
+
+ __ms_va_start( args, fmt );
+ switch (fmt[0])
+ {
+ case 'a':
+ {
+ char **str = va_arg( args, char ** );
+ ret = ber_scanf( ber, fmt, str );
+ break;
+ }
+ case 'b':
+ case 'e':
+ case 'i':
+ {
+ int *i = va_arg( args, int * );
+ ret = ber_scanf( ber, fmt, i );
+ break;
+ }
+ case 't':
+ {
+ unsigned int *tag = va_arg( args, unsigned int * );
+ ret = ber_scanf( ber, fmt, tag );
+ break;
+ }
+ case 'v':
+ {
+ char ***array = va_arg( args, char *** );
+ ret = ber_scanf( ber, fmt, array );
+ break;
+ }
+ case 'B':
+ {
+ char **str = va_arg( args, char ** );
+ int *len = va_arg( args, int * );
+ ret = ber_scanf( ber, fmt, str, len );
+ break;
+ }
+ case 'O':
+ {
+ struct berval **berval = va_arg( args, struct berval ** );
+ ret = ber_scanf( ber, fmt, berval );
+ break;
+ }
+ case 'V':
+ {
+ struct berval ***array = va_arg( args, struct berval *** );
+ ret = ber_scanf( ber, fmt, array );
+ break;
+ }
+ case 'n':
+ case 'x':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ ret = ber_scanf( ber, fmt );
+ break;
+
+ default:
+ assert( 0 );
+ }
+ __ms_va_end( args );
+ return ret;
+}
+
int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
LDAPControlU **clientctrls, ULONG *msg )
{
@@ -65,10 +307,28 @@ int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControl
(LDAPControl **)clientctrls );
}
+void CDECL wrap_ldap_memfree( void *ptr )
+{
+ return ldap_memfree( ptr );
+}
+
static const struct ldap_funcs funcs =
{
+ wrap_ber_alloc_t,
+ wrap_ber_bvecfree,
+ wrap_ber_bvfree,
+ wrap_ber_first_element,
+ wrap_ber_flatten,
+ wrap_ber_free,
+ wrap_ber_init,
+ wrap_ber_next_element,
+ wrap_ber_peek_tag,
+ wrap_ber_skip_tag,
+ wrap_ber_printf,
+ wrap_ber_scanf,
wrap_ldap_add_ext,
wrap_ldap_add_ext_s,
+ wrap_ldap_memfree,
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index d9d833cdcb8..4ca90d298a0 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -60,13 +60,41 @@ typedef struct
void *ldvlv_extradata;
} LDAPVLVInfoU;
+extern void * CDECL wrap_ber_alloc_t(int) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ber_bvecfree(struct bervalU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ber_bvfree(struct bervalU *) DECLSPEC_HIDDEN;
+extern unsigned int CDECL wrap_ber_first_element(void *, unsigned int *, char **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ber_flatten(void *, struct bervalU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ber_free(void *, int) DECLSPEC_HIDDEN;
+extern void * CDECL wrap_ber_init(struct bervalU *) DECLSPEC_HIDDEN;
+extern unsigned int CDECL wrap_ber_next_element(void *, unsigned int *, char *) DECLSPEC_HIDDEN;
+extern unsigned int CDECL wrap_ber_peek_tag(void *, unsigned int *) DECLSPEC_HIDDEN;
+extern unsigned int CDECL wrap_ber_skip_tag(void *, unsigned int *) DECLSPEC_HIDDEN;
+extern int WINAPIV wrap_ber_printf(void *, char *, ...) DECLSPEC_HIDDEN;
+extern int WINAPIV wrap_ber_scanf(void *, char *, ...) DECLSPEC_HIDDEN;
+
extern int CDECL wrap_ldap_add_ext(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_add_ext_s(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
struct ldap_funcs
{
+ void * (CDECL *ber_alloc_t)(int);
+ void (CDECL *ber_bvecfree)(struct bervalU **);
+ void (CDECL *ber_bvfree)(struct bervalU *);
+ unsigned int (CDECL *ber_first_element)(void *, unsigned int *, char **);
+ int (CDECL *ber_flatten)(void *, struct bervalU **);
+ void (CDECL *ber_free)(void *, int);
+ void * (CDECL *ber_init)(struct bervalU *);
+ unsigned int (CDECL *ber_next_element)(void *, unsigned int *, char *);
+ unsigned int (CDECL *ber_peek_tag)(void *, unsigned int *);
+ unsigned int (CDECL *ber_skip_tag)(void *, unsigned int *);
+ int (WINAPIV *ber_printf)(void *, char *, ...);
+ int (WINAPIV *ber_scanf)(void *, char *, ...);
+
int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+ void (CDECL *ldap_memfree)(void *);
};
extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/misc.c b/dlls/wldap32/misc.c
index 39642960955..dd1a1ef3f12 100644
--- a/dlls/wldap32/misc.c
+++ b/dlls/wldap32/misc.c
@@ -328,15 +328,22 @@ PWCHAR CDECL ldap_first_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry
{
PWCHAR ret = NULL;
#ifdef HAVE_LDAP
+ BerElement *berU;
char *retU;
TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
if (!ld || !entry) return NULL;
- retU = ldap_first_attribute( ld->ld, entry, ptr );
- ret = strUtoW( retU );
- ldap_memfree( retU );
+ retU = ldap_first_attribute( ld->ld, entry, &berU );
+ if (retU)
+ {
+ WLDAP32_BerElement *ber = heap_alloc( sizeof(*ber) );
+ ber->opaque = (char *)berU;
+ *ptr = ber;
+ ret = strUtoW( retU );
+ ldap_memfree( retU );
+ }
#endif
return ret;
@@ -487,19 +494,22 @@ PCHAR CDECL ldap_next_attributeA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
* When done iterating and when ptr != NULL, call ber_free( ptr, 0 ).
*/
PWCHAR CDECL ldap_next_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
- WLDAP32_BerElement *ptr )
+ WLDAP32_BerElement *ber )
{
PWCHAR ret = NULL;
#ifdef HAVE_LDAP
char *retU;
- TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
+ TRACE( "(%p, %p, %p)\n", ld, entry, ber );
- if (!ld || !entry || !ptr) return NULL;
- retU = ldap_next_attribute( ld->ld, entry, ptr );
+ if (!ld || !entry) return NULL;
- ret = strUtoW( retU );
- ldap_memfree( retU );
+ retU = ldap_next_attribute( ld->ld, entry, (BerElement *)ber->opaque );
+ if (retU)
+ {
+ ret = strUtoW( retU );
+ ldap_memfree( retU );
+ }
#endif
return ret;
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index d0583c61f50..22e981cb26d 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -27,6 +27,8 @@
#include "winnls.h"
#include "libldap.h"
+#define WLDAP32_LBER_ERROR (~0L)
+
typedef enum {
WLDAP32_LDAP_SUCCESS = 0x00,
WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35,
@@ -1187,6 +1189,26 @@ static inline WCHAR **strarrayUtoW( char **strarray )
return strarrayW;
}
+static inline char **strarrayUtoU( char **strarray )
+{
+ char **strarrayU = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(char *) * (strarraylenU( strarray ) + 1);
+ if ((strarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char **p = strarray;
+ char **q = strarrayU;
+
+ while (*p) *q++ = strdupU( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayU;
+}
+
static inline LDAPControlW *controlUtoW( const LDAPControlU *control )
{
LDAPControlW *controlW;
diff --git a/include/winber.h b/include/winber.h
index 40ab0f40ed8..372cc321269 100644
--- a/include/winber.h
+++ b/include/winber.h
@@ -27,11 +27,17 @@ typedef unsigned int ber_tag_t;
typedef unsigned int ber_len_t;
BerElement * CDECL ber_alloc_t( int );
+BERVAL * CDECL ber_bvdup( BERVAL * );
+void CDECL ber_bvecfree( BERVAL ** );
void CDECL ber_bvfree( BERVAL * );
+ULONG CDECL ber_first_element( BerElement *, ULONG *, char ** );
int CDECL ber_flatten( BerElement *, BERVAL ** );
void CDECL ber_free( BerElement *, int );
BerElement * CDECL ber_init( BERVAL * );
+ULONG CDECL ber_next_element( BerElement *, ULONG *, char ** );
+ULONG CDECL ber_peek_tag( BerElement *, ULONG * );
int WINAPIV ber_printf( BerElement *, char *, ... );
ULONG WINAPIV ber_scanf( BerElement *, char *, ... );
+ULONG CDECL ber_skip_tag( BerElement *, ULONG * );
#endif /* __WINE_WINBER_H */
--
2.30.2
1
0
[PATCH 1/5] wldap32: Move support for add functions to a new Unix library.
by Hans Leidekker April 14, 2021
by Hans Leidekker April 14, 2021
April 14, 2021
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/Makefile.in | 1 +
dlls/wldap32/add.c | 274 ++--------
dlls/wldap32/init.c | 10 +-
dlls/wldap32/libldap.c | 81 +++
dlls/wldap32/libldap.h | 72 +++
dlls/wldap32/main.c | 12 +-
dlls/wldap32/winldap_private.h | 910 ++++++++++++++++++++++++++++++++-
dlls/wldap32/wldap32.h | 30 +-
8 files changed, 1137 insertions(+), 253 deletions(-)
create mode 100644 dlls/wldap32/libldap.c
create mode 100644 dlls/wldap32/libldap.h
diff --git a/dlls/wldap32/Makefile.in b/dlls/wldap32/Makefile.in
index 7dc2984c5aa..18a37151f99 100644
--- a/dlls/wldap32/Makefile.in
+++ b/dlls/wldap32/Makefile.in
@@ -15,6 +15,7 @@ C_SRCS = \
error.c \
extended.c \
init.c \
+ libldap.c \
main.c \
misc.c \
modify.c \
diff --git a/dlls/wldap32/add.c b/dlls/wldap32/add.c
index 0d0c8bfa117..cce7726a241 100644
--- a/dlls/wldap32/add.c
+++ b/dlls/wldap32/add.c
@@ -18,62 +18,39 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-static LDAPMod *nullattrs[] = { NULL };
-#endif
-
/***********************************************************************
* ldap_addA (WLDAP32.@)
*
* See ldap_addW.
*/
-ULONG CDECL ldap_addA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[] )
+ULONG CDECL ldap_addA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), attrs );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
ret = ldap_addW( ld, dnW, attrsW );
exit:
strfreeW( dnW );
modarrayfreeW( attrsW );
-
-#endif
return ret;
}
@@ -97,42 +74,15 @@ exit:
* the operation. Cancel the operation by calling ldap_abandon
* with the message ID.
*/
-ULONG CDECL ldap_addW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[] )
+ULONG CDECL ldap_addW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- int msg;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ ULONG ret, msg;
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), attrs );
- if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
-
- ret = ldap_add_ext( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
- ret = msg;
- else
- ret = ~0u;
-
-exit:
- strfreeU( dnU );
- modarrayfreeU( attrsU );
-
-#endif
- return ret;
+ ret = ldap_add_extW( ld, dn, attrs, NULL, NULL, &msg );
+ if (ret == WLDAP32_LDAP_SUCCESS) return msg;
+ return ~0u;
}
/***********************************************************************
@@ -140,38 +90,22 @@ exit:
*
* See ldap_add_extW.
*/
-ULONG CDECL ldap_add_extA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[],
- PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, ULONG *message )
+ULONG CDECL ldap_add_extA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs, LDAPControlA **serverctrls,
+ LDAPControlA **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), attrs,
- serverctrls, clientctrls, message );
+ TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), attrs, serverctrls, clientctrls, message );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_add_extW( ld, dnW, attrsW, serverctrlsW, clientctrlsW, message );
@@ -180,8 +114,6 @@ exit:
modarrayfreeW( attrsW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -208,50 +140,30 @@ exit:
* the operation. The serverctrls and clientctrls parameters are
* optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_add_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[],
- PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message )
+ULONG CDECL ldap_add_extW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- int dummy;
+ LDAPModU **attrsU = NULL;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), attrs,
- serverctrls, clientctrls, message );
+ TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), attrs, serverctrls, clientctrls, message );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, serverctrlsU,
- clientctrlsU, message ? (int *)message : &dummy ));
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attrs && !(attrsU = modarrayWtoU( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+
+ ret = map_error( ldap_funcs->ldap_add_ext( ld->ld, dnU, attrsU, serverctrlsU, clientctrlsU, message ) );
exit:
strfreeU( dnU );
modarrayfreeU( attrsU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -260,38 +172,22 @@ exit:
*
* See ldap_add_ext_sW.
*/
-ULONG CDECL ldap_add_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[],
- PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
+ULONG CDECL ldap_add_ext_sA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs, LDAPControlA **serverctrls,
+ LDAPControlA **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), attrs,
- serverctrls, clientctrls );
+ TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), attrs, serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_add_ext_sW( ld, dnW, attrsW, serverctrlsW, clientctrlsW );
@@ -300,8 +196,6 @@ exit:
modarrayfreeW( attrsW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -326,49 +220,30 @@ exit:
* The serverctrls and clientctrls parameters are optional and
* should be set to NULL if not used.
*/
-ULONG CDECL ldap_add_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[],
- PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
+ULONG CDECL ldap_add_ext_sW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
+ LDAPModU **attrsU = NULL;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), attrs,
- serverctrls, clientctrls );
+ TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), attrs, serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext_s( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs,
- serverctrlsU, clientctrlsU ));
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attrs && !(attrsU = modarrayWtoU( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+
+ ret = map_error( ldap_funcs->ldap_add_ext_s( ld->ld, dnU, attrsU, serverctrlsU, clientctrlsU ) );
exit:
strfreeU( dnU );
modarrayfreeU( attrsU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -377,35 +252,24 @@ exit:
*
* See ldap_add_sW.
*/
-ULONG CDECL ldap_add_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[] )
+ULONG CDECL ldap_add_sA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), attrs );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
ret = ldap_add_sW( ld, dnW, attrsW );
exit:
strfreeW( dnW );
modarrayfreeW( attrsW );
-
-#endif
return ret;
}
@@ -424,34 +288,8 @@ exit:
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_add_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[] )
+ULONG CDECL ldap_add_sW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL;
- LDAPMod **attrsU = NULL;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), attrs );
-
- if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext_s( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, NULL, NULL ));
-
-exit:
- strfreeU( dnU );
- modarrayfreeU( attrsU );
-
-#endif
- return ret;
+ return ldap_add_ext_sW( ld, dn, attrs, NULL, NULL );
}
diff --git a/dlls/wldap32/init.c b/dlls/wldap32/init.c
index 0072ede6772..6586caa0ef5 100644
--- a/dlls/wldap32/init.c
+++ b/dlls/wldap32/init.c
@@ -128,11 +128,11 @@ static BOOL has_ldap_scheme( char *url )
static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnumber )
{
char *res, *p, *q, **v;
- unsigned int i = 0, size = 0;
+ unsigned int i = 0, size = 0;
static const char sep[] = " ", fmt[] = ":%d";
char port[7];
- sprintf( port, fmt, portnumber );
+ sprintf( port, fmt, portnumber );
for (v = hostnames; *v; v++)
{
@@ -147,7 +147,7 @@ static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnum
size += strlen( *v );
- if (!strchr( q, ':' ))
+ if (!strchr( q, ':' ))
size += strlen( port );
i++;
@@ -212,7 +212,7 @@ static WLDAP32_LDAP *create_context( const char *url )
ld = heap_alloc_zero( sizeof( *ld ));
if (!ld) return NULL;
- if (ldap_initialize( &ld->ld, url ) != LDAP_SUCCESS)
+ if (ldap_initialize( (LDAP **)&ld->ld, url ) != LDAP_SUCCESS)
{
heap_free( ld );
return NULL;
@@ -307,7 +307,7 @@ exit:
/***********************************************************************
* ldap_connect (WLDAP32.@)
*
- * Connect to an LDAP server.
+ * Connect to an LDAP server.
*
* PARAMS
* ld [I] Pointer to an LDAP context.
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
new file mode 100644
index 00000000000..0372206062a
--- /dev/null
+++ b/dlls/wldap32/libldap.c
@@ -0,0 +1,81 @@
+/*
+ * Unix interface for libldap
+ *
+ * Copyright 2021 Hans Leidekker for CodeWeavers
+ *
+ * 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+
+#ifdef HAVE_LDAP
+#include <stdarg.h>
+#ifdef HAVE_LDAP_H
+# include <ldap.h>
+#endif
+#ifdef HAVE_SASL_SASL_H
+# include <sasl/sasl.h>
+#endif
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+#include "winldap_private.h"
+
+C_ASSERT( sizeof(BerValueU) == sizeof(BerValue) );
+C_ASSERT( sizeof(LDAPModU) == sizeof(LDAPMod) );
+C_ASSERT( sizeof(LDAPControlU) == sizeof(LDAPControl) );
+C_ASSERT( sizeof(LDAPSortKeyU) == sizeof(LDAPSortKey) );
+C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
+
+static LDAPMod *nullattrs[] = { NULL };
+
+int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls, ULONG *msg )
+{
+ int dummy;
+ return ldap_add_ext( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
+}
+
+int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls )
+{
+ return ldap_add_ext_s( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls );
+}
+
+static const struct ldap_funcs funcs =
+{
+ wrap_ldap_add_ext,
+ wrap_ldap_add_ext_s,
+};
+
+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
+{
+ if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ *(const struct ldap_funcs **)ptr_out = &funcs;
+ return STATUS_SUCCESS;
+}
+
+#endif /* HAVE_LDAP */
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
new file mode 100644
index 00000000000..d9d833cdcb8
--- /dev/null
+++ b/dlls/wldap32/libldap.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2021 Hans Leidekker for CodeWeavers
+ *
+ * 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* compatible with structures defined in ldap.h */
+typedef struct bervalU
+{
+ unsigned long bv_len;
+ char *bv_val;
+} BerValueU;
+
+typedef struct
+{
+ int mod_op;
+ char *mod_type;
+ union
+ {
+ char **modv_strvals;
+ struct bervalU **modv_bvals;
+ } mod_vals;
+} LDAPModU;
+
+typedef struct
+{
+ char *ldctl_oid;
+ struct bervalU ldctl_value;
+ char ldctl_iscritical;
+} LDAPControlU;
+
+typedef struct
+{
+ char *attributeType;
+ char *orderingRule;
+ int reverseOrder;
+} LDAPSortKeyU;
+
+typedef struct
+{
+ int ldvlv_version;
+ int ldvlv_before_count;
+ int ldvlv_after_count;
+ int ldvlv_offset;
+ int ldvlv_count;
+ struct bervalU *ldvlv_attrvalue;
+ struct bervalU *ldvlv_context;
+ void *ldvlv_extradata;
+} LDAPVLVInfoU;
+
+extern int CDECL wrap_ldap_add_ext(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext_s(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+
+struct ldap_funcs
+{
+ int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
+ int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+};
+
+extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/main.c b/dlls/wldap32/main.c
index ce9e60367b9..55a08c9bad5 100644
--- a/dlls/wldap32/main.c
+++ b/dlls/wldap32/main.c
@@ -18,18 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-
-#include "wine/debug.h"
#include <stdarg.h>
-
#include "windef.h"
+#include "winternl.h"
#include "winbase.h"
+#include "wine/debug.h"
+#include "libldap.h"
+
HINSTANCE hwldap32;
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
+const struct ldap_funcs *ldap_funcs = NULL;
+
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
TRACE( "(%p, %d, %p)\n", hinst, reason, reserved );
@@ -39,6 +41,8 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH:
hwldap32 = hinst;
DisableThreadLibraryCalls( hinst );
+ if (__wine_init_unix_lib( hinst, reason, NULL, &ldap_funcs ))
+ ERR( "No libldap support, expect problems\n" );
break;
}
return TRUE;
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 8cd546b88b5..d0583c61f50 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -22,6 +22,11 @@
* native headers.
*/
+#include <assert.h>
+#include "winternl.h"
+#include "winnls.h"
+#include "libldap.h"
+
typedef enum {
WLDAP32_LDAP_SUCCESS = 0x00,
WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35,
@@ -101,7 +106,9 @@ typedef struct berelement
#define WLDAP32_LDAP_OPT_SECURITY_CONTEXT 0x99
#define WLDAP32_LDAP_OPT_ROOTDSE_CACHE 0x9a
-#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
+#define WLDAP32_LDAP_AUTH_SIMPLE 0x80
+#define WLDAP32_LDAP_AUTH_SASL 0x83
+#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
typedef struct WLDAP32_berval
{
@@ -111,9 +118,6 @@ typedef struct WLDAP32_berval
typedef struct wldap32
{
-#ifdef HAVE_LDAP
- LDAP *ld;
-#endif
struct
{
UINT_PTR sb_sd;
@@ -137,7 +141,9 @@ typedef struct wldap32
ULONG ld_cldaptimeout;
ULONG ld_refhoplimit;
ULONG ld_options;
+ /* internal LDAP context */
struct berval **ld_server_ctrls;
+ void *ld;
} WLDAP32_LDAP, *WLDAP32_PLDAP;
typedef struct ldapmodA {
@@ -424,10 +430,10 @@ ULONG CDECL ldap_rename_ext_sA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR,INT,PLDAPControlA
ULONG CDECL ldap_rename_ext_sW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR,INT,PLDAPControlW*,PLDAPControlW*);
ULONG CDECL WLDAP32_ldap_result(WLDAP32_LDAP*,ULONG,ULONG,struct l_timeval*,WLDAP32_LDAPMessage**);
ULONG CDECL WLDAP32_ldap_result2error(WLDAP32_LDAP*,WLDAP32_LDAPMessage*,ULONG);
-ULONG CDECL ldap_sasl_bindA(WLDAP32_LDAP*,const PCHAR,const PCHAR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,int*);
-ULONG CDECL ldap_sasl_bindW(WLDAP32_LDAP*,const PWCHAR,const PWCHAR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,int*);
-ULONG CDECL ldap_sasl_bind_sA(WLDAP32_LDAP*,const PCHAR,const PCHAR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,PBERVAL*);
-ULONG CDECL ldap_sasl_bind_sW(WLDAP32_LDAP*,const PWCHAR,const PWCHAR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,PBERVAL*);
+ULONG CDECL ldap_sasl_bindA(WLDAP32_LDAP*,const PSTR,const PSTR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,int*);
+ULONG CDECL ldap_sasl_bindW(WLDAP32_LDAP*,const PWSTR,const PWSTR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,int*);
+ULONG CDECL ldap_sasl_bind_sA(WLDAP32_LDAP*,const PSTR,const PSTR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,PBERVAL*);
+ULONG CDECL ldap_sasl_bind_sW(WLDAP32_LDAP*,const PWSTR,const PWSTR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,PBERVAL*);
ULONG CDECL ldap_search_abandon_page(WLDAP32_PLDAP,PLDAPSearch);
ULONG CDECL ldap_searchA(WLDAP32_LDAP*,PCHAR,ULONG,PCHAR,PCHAR[],ULONG);
ULONG CDECL ldap_searchW(WLDAP32_LDAP*,PWCHAR,ULONG,PWCHAR,PWCHAR[],ULONG);
@@ -473,3 +479,891 @@ ULONG CDECL LdapGetLastError(void);
ULONG CDECL LdapMapErrorToWin32(ULONG);
int CDECL LdapUnicodeToUTF8(LPCWSTR,int,LPSTR,int);
int CDECL LdapUTF8ToUnicode(LPCSTR,int,LPWSTR,int);
+
+ULONG map_error( int ) DECLSPEC_HIDDEN;
+
+static inline char *strdupU( const char *src )
+{
+ char *dst;
+ if (!src) return NULL;
+ if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src );
+ return dst;
+}
+
+#ifndef HAVE_LDAP
+static inline WCHAR *strdupW( const WCHAR *src )
+{
+ WCHAR *dst;
+ if (!src) return NULL;
+ if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (lstrlenW( src ) + 1) * sizeof(WCHAR) ))) lstrcpyW( dst, src );
+ return dst;
+}
+
+static inline char *strWtoU( const WCHAR *str )
+{
+ char *ret = NULL;
+ if (str)
+ {
+ int len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_UTF8, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+static inline char *strnWtoU( const WCHAR *str, DWORD in_len, DWORD *out_len )
+{
+ char *ret = NULL;
+ *out_len = 0;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, in_len, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 )))
+ {
+ WideCharToMultiByte( CP_UTF8, 0, str, in_len, ret, len, NULL, NULL );
+ ret[len] = 0;
+ *out_len = len;
+ }
+ }
+ return ret;
+}
+
+static inline void strfreeU( char *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline WCHAR *strAtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+static inline void strfreeW( WCHAR *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline WCHAR *strnAtoW( const char *str, DWORD in_len, DWORD *out_len )
+{
+ WCHAR *ret = NULL;
+ *out_len = 0;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, in_len, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
+ {
+ MultiByteToWideChar( CP_ACP, 0, str, in_len, ret, len );
+ ret[len] = 0;
+ *out_len = len;
+ }
+ }
+ return ret;
+}
+
+static inline DWORD bvarraylenW( struct WLDAP32_berval **bv )
+{
+ struct WLDAP32_berval **p = bv;
+ while (*p) p++;
+ return p - bv;
+}
+
+static inline DWORD strarraylenW( WCHAR **strarray )
+{
+ WCHAR **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline char **strarrayWtoU( WCHAR **strarray )
+{
+ char **strarrayU = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(char *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ char **q = strarrayU;
+
+ while (*p) *q++ = strWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayU;
+}
+
+static inline char *strWtoA( const WCHAR *str )
+{
+ char *ret = NULL;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+static inline char **strarrayWtoA( WCHAR **strarray )
+{
+ char **strarrayA = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(char *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayA = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ char **q = strarrayA;
+
+ while (*p) *q++ = strWtoA( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayA;
+}
+
+#define WLDAP32_LDAP_MOD_BVALUES 0x80
+
+static inline DWORD modarraylenW( LDAPModW **modarray )
+{
+ LDAPModW **p = modarray;
+ while (*p) p++;
+ return p - modarray;
+}
+
+static inline struct bervalU *bervalWtoU( const struct WLDAP32_berval *bv )
+{
+ struct bervalU *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char *val = (char *)(berval + 1);
+
+ berval->bv_len = bv->bv_len;
+ berval->bv_val = val;
+ memcpy( val, bv->bv_val, bv->bv_len );
+ }
+ return berval;
+}
+
+static inline DWORD bvarraylenU( struct bervalU **bv )
+{
+ struct bervalU **p = bv;
+ while (*p) p++;
+ return p - bv;
+}
+
+static inline struct WLDAP32_berval *bervalUtoW( const struct bervalU *bv )
+{
+ struct WLDAP32_berval *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ assert( bv->bv_len <= ~0u );
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char *val = (char *)(berval + 1);
+
+ berval->bv_len = bv->bv_len;
+ berval->bv_val = val;
+ memcpy( val, bv->bv_val, bv->bv_len );
+ }
+ return berval;
+}
+
+static inline struct WLDAP32_berval **bvarrayUtoW( struct bervalU **bv )
+{
+ struct WLDAP32_berval **berval = NULL;
+ DWORD size;
+
+ if (bv)
+ {
+ size = sizeof(*berval) * (bvarraylenU( bv ) + 1);
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct bervalU **p = bv;
+ struct WLDAP32_berval **q = berval;
+
+ while (*p) *q++ = bervalUtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline void bvfreeU( struct bervalU *berval )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, berval );
+}
+
+static inline struct bervalU **bvarrayWtoU( struct WLDAP32_berval **bv )
+{
+ struct bervalU **berval = NULL;
+ DWORD size;
+
+ if (bv)
+ {
+ size = sizeof(*berval) * (bvarraylenW( bv ) + 1);
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct WLDAP32_berval **p = bv;
+ struct bervalU **q = berval;
+
+ while (*p) *q++ = bervalWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline LDAPModU *modWtoU( const LDAPModW *mod )
+{
+ LDAPModU *modU;
+
+ if ((modU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPModU) )))
+ {
+ modU->mod_op = mod->mod_op;
+ modU->mod_type = strWtoU( mod->mod_type );
+
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ modU->mod_vals.modv_bvals = bvarrayWtoU( mod->mod_vals.modv_bvals );
+ else
+ modU->mod_vals.modv_strvals = strarrayWtoU( mod->mod_vals.modv_strvals );
+ }
+ return modU;
+}
+
+static inline LDAPModU **modarrayWtoU( LDAPModW **modarray )
+{
+ LDAPModU **modarrayU = NULL;
+ DWORD size;
+
+ if (modarray)
+ {
+ size = sizeof(LDAPModU *) * (modarraylenW( modarray ) + 1);
+ if ((modarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPModW **p = modarray;
+ LDAPModU **q = modarrayU;
+
+ while (*p) *q++ = modWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return modarrayU;
+}
+
+static inline void bvarrayfreeU( struct bervalU **bv )
+{
+ struct bervalU **p = bv;
+ while (*p) RtlFreeHeap( GetProcessHeap(), 0, *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, bv );
+}
+
+static inline void strarrayfreeU( char **strarray )
+{
+ if (strarray)
+ {
+ char **p = strarray;
+ while (*p) strfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, strarray );
+ }
+}
+
+static inline void modfreeU( LDAPModU *mod )
+{
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ bvarrayfreeU( mod->mod_vals.modv_bvals );
+ else
+ strarrayfreeU( mod->mod_vals.modv_strvals );
+ RtlFreeHeap( GetProcessHeap(), 0, mod );
+}
+
+static inline void modarrayfreeU( LDAPModU **modarray )
+{
+ if (modarray)
+ {
+ LDAPModU **p = modarray;
+ while (*p) modfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, modarray );
+ }
+}
+
+static inline DWORD modarraylenA( LDAPModA **modarray )
+{
+ LDAPModA **p = modarray;
+ while (*p) p++;
+ return p - modarray;
+}
+
+static inline struct WLDAP32_berval *bervalWtoW( const struct WLDAP32_berval *bv )
+{
+ struct WLDAP32_berval *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char *val = (char *)(berval + 1);
+
+ berval->bv_len = bv->bv_len;
+ berval->bv_val = val;
+ memcpy( val, bv->bv_val, bv->bv_len );
+ }
+ return berval;
+}
+
+static inline struct WLDAP32_berval **bvarrayWtoW( struct WLDAP32_berval **bv )
+{
+ struct WLDAP32_berval **berval = NULL;
+ DWORD size;
+
+ if (bv)
+ {
+ size = sizeof(*berval) * (bvarraylenW( bv ) + 1);
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct WLDAP32_berval **p = bv;
+ struct WLDAP32_berval **q = berval;
+
+ while (*p) *q++ = bervalWtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline DWORD strarraylenA( char **strarray )
+{
+ char **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline WCHAR **strarrayAtoW( char **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenA( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
+static inline LDAPModW *modAtoW( const LDAPModA *mod )
+{
+ LDAPModW *modW;
+
+ if ((modW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPModW) )))
+ {
+ modW->mod_op = mod->mod_op;
+ modW->mod_type = strAtoW( mod->mod_type );
+
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ modW->mod_vals.modv_bvals = bvarrayWtoW( mod->mod_vals.modv_bvals );
+ else
+ modW->mod_vals.modv_strvals = strarrayAtoW( mod->mod_vals.modv_strvals );
+ }
+ return modW;
+}
+
+static inline LDAPModW **modarrayAtoW( LDAPModA **modarray )
+{
+ LDAPModW **modarrayW = NULL;
+ DWORD size;
+
+ if (modarray)
+ {
+ size = sizeof(LDAPModW *) * (modarraylenA( modarray ) + 1);
+ if ((modarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPModA **p = modarray;
+ LDAPModW **q = modarrayW;
+
+ while (*p) *q++ = modAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return modarrayW;
+}
+
+static inline void bvarrayfreeW( struct WLDAP32_berval **bv )
+{
+ struct WLDAP32_berval **p = bv;
+ while (*p) RtlFreeHeap( GetProcessHeap(), 0, *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, bv );
+}
+
+static inline void strarrayfreeW( WCHAR **strarray )
+{
+ if (strarray)
+ {
+ WCHAR **p = strarray;
+ while (*p) strfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, strarray );
+ }
+}
+
+static inline void modfreeW( LDAPModW *mod )
+{
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ bvarrayfreeW( mod->mod_vals.modv_bvals );
+ else
+ strarrayfreeW( mod->mod_vals.modv_strvals );
+ RtlFreeHeap( GetProcessHeap(), 0, mod );
+}
+
+static inline void modarrayfreeW( LDAPModW **modarray )
+{
+ if (modarray)
+ {
+ LDAPModW **p = modarray;
+ while (*p) modfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, modarray );
+ }
+}
+
+static inline DWORD controlarraylenA( LDAPControlA **controlarray )
+{
+ LDAPControlA **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline LDAPControlW *controlAtoW( const LDAPControlA *control )
+{
+ LDAPControlW *controlW;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlW) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlW->ldctl_oid = strAtoW( control->ldctl_oid );
+ controlW->ldctl_value.bv_len = len;
+ controlW->ldctl_value.bv_val = val;
+ controlW->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlW;
+}
+
+static inline LDAPControlW **controlarrayAtoW( LDAPControlA **controlarray )
+{
+ LDAPControlW **controlarrayW = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlW *) * (controlarraylenA( controlarray ) + 1);
+ if ((controlarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlA **p = controlarray;
+ LDAPControlW **q = controlarrayW;
+
+ while (*p) *q++ = controlAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayW;
+}
+
+static inline void controlfreeW( LDAPControlW *control )
+{
+ if (control)
+ {
+ strfreeW( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeW( LDAPControlW **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlW **p = controlarray;
+ while (*p) controlfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline DWORD controlarraylenW( LDAPControlW **controlarray )
+{
+ LDAPControlW **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline LDAPControlA *controlWtoA( const LDAPControlW *control )
+{
+ LDAPControlA *controlA;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlA = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlA) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlA->ldctl_oid = strWtoA( control->ldctl_oid );
+ controlA->ldctl_value.bv_len = len;
+ controlA->ldctl_value.bv_val = val;
+ controlA->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlA;
+}
+
+static inline void strfreeA( char *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline void controlfreeA( LDAPControlA *control )
+{
+ if (control)
+ {
+ strfreeA( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeA( LDAPControlA **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlA **p = controlarray;
+ while (*p) controlfreeA( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline LDAPControlU *controlWtoU( const LDAPControlW *control )
+{
+ LDAPControlU *controlU;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlU) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlU->ldctl_oid = strWtoU( control->ldctl_oid );
+ controlU->ldctl_value.bv_len = len;
+ controlU->ldctl_value.bv_val = val;
+ controlU->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlU;
+}
+
+static inline LDAPControlU **controlarrayWtoU( LDAPControlW **controlarray )
+{
+ LDAPControlU **controlarrayU = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlU *) * (controlarraylenW( controlarray ) + 1);
+ if ((controlarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlW **p = controlarray;
+ LDAPControlU **q = controlarrayU;
+
+ while (*p) *q++ = controlWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayU;
+}
+
+static inline void controlfreeU( LDAPControlU *control )
+{
+ if (control)
+ {
+ strfreeU( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeU( LDAPControlU **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlU **p = controlarray;
+ while (*p) controlfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline DWORD controlarraylenU( LDAPControlU **controlarray )
+{
+ LDAPControlU **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline WCHAR *strUtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_UTF8, 0, str, -1, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_UTF8, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+static inline DWORD strarraylenU( char **strarray )
+{
+ char **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline WCHAR **strarrayUtoW( char **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenU( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strUtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
+static inline LDAPControlW *controlUtoW( const LDAPControlU *control )
+{
+ LDAPControlW *controlW;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlW) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlW->ldctl_oid = strUtoW( control->ldctl_oid );
+ controlW->ldctl_value.bv_len = len;
+ controlW->ldctl_value.bv_val = val;
+ controlW->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlW;
+}
+
+static inline DWORD sortkeyarraylenA( LDAPSortKeyA **sortkeyarray )
+{
+ LDAPSortKeyA **p = sortkeyarray;
+ while (*p) p++;
+ return p - sortkeyarray;
+}
+
+static inline LDAPSortKeyW *sortkeyAtoW( const LDAPSortKeyA *sortkey )
+{
+ LDAPSortKeyW *sortkeyW;
+
+ if ((sortkeyW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPSortKeyW) )))
+ {
+ sortkeyW->sk_attrtype = strAtoW( sortkey->sk_attrtype );
+ sortkeyW->sk_matchruleoid = strAtoW( sortkey->sk_matchruleoid );
+ sortkeyW->sk_reverseorder = sortkey->sk_reverseorder;
+ }
+ return sortkeyW;
+}
+
+static inline LDAPSortKeyW **sortkeyarrayAtoW( LDAPSortKeyA **sortkeyarray )
+{
+ LDAPSortKeyW **sortkeyarrayW = NULL;
+ DWORD size;
+
+ if (sortkeyarray)
+ {
+ size = sizeof(LDAPSortKeyW *) * (sortkeyarraylenA( sortkeyarray ) + 1);
+ if ((sortkeyarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPSortKeyA **p = sortkeyarray;
+ LDAPSortKeyW **q = sortkeyarrayW;
+
+ while (*p) *q++ = sortkeyAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return sortkeyarrayW;
+}
+
+static inline void sortkeyfreeW( LDAPSortKeyW *sortkey )
+{
+ if (sortkey)
+ {
+ strfreeW( sortkey->sk_attrtype );
+ strfreeW( sortkey->sk_matchruleoid );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkey );
+ }
+}
+
+static inline void sortkeyarrayfreeW( LDAPSortKeyW **sortkeyarray )
+{
+ if (sortkeyarray)
+ {
+ LDAPSortKeyW **p = sortkeyarray;
+ while (*p) sortkeyfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkeyarray );
+ }
+}
+
+static inline DWORD sortkeyarraylenW( LDAPSortKeyW **sortkeyarray )
+{
+ LDAPSortKeyW **p = sortkeyarray;
+ while (*p) p++;
+ return p - sortkeyarray;
+}
+
+static inline LDAPSortKeyU *sortkeyWtoU( const LDAPSortKeyW *sortkey )
+{
+ LDAPSortKeyU *sortkeyU;
+
+ if ((sortkeyU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPSortKeyU) )))
+ {
+ sortkeyU->attributeType = strWtoU( sortkey->sk_attrtype );
+ sortkeyU->orderingRule = strWtoU( sortkey->sk_matchruleoid );
+ sortkeyU->reverseOrder = sortkey->sk_reverseorder;
+ }
+ return sortkeyU;
+}
+
+static inline LDAPSortKeyU **sortkeyarrayWtoU( LDAPSortKeyW **sortkeyarray )
+{
+ LDAPSortKeyU **sortkeyarrayU = NULL;
+ DWORD size;
+
+ if (sortkeyarray)
+ {
+ size = sizeof(LDAPSortKeyU *) * (sortkeyarraylenW( sortkeyarray ) + 1);
+ if ((sortkeyarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPSortKeyW **p = sortkeyarray;
+ LDAPSortKeyU **q = sortkeyarrayU;
+
+ while (*p) *q++ = sortkeyWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return sortkeyarrayU;
+}
+
+static inline void sortkeyfreeU( LDAPSortKeyU *sortkey )
+{
+ if (sortkey)
+ {
+ strfreeU( sortkey->attributeType );
+ strfreeU( sortkey->orderingRule );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkey );
+ }
+}
+
+static inline void sortkeyarrayfreeU( LDAPSortKeyU **sortkeyarray )
+{
+ if (sortkeyarray)
+ {
+ LDAPSortKeyU **p = sortkeyarray;
+ while (*p) sortkeyfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkeyarray );
+ }
+}
+
+static inline LDAPVLVInfoU *vlvinfoWtoU( const WLDAP32_LDAPVLVInfo *info )
+{
+ LDAPVLVInfoU *infoU;
+
+ if ((infoU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*infoU) )))
+ {
+ infoU->ldvlv_version = info->ldvlv_version;
+ infoU->ldvlv_before_count = info->ldvlv_before_count;
+ infoU->ldvlv_after_count = info->ldvlv_after_count;
+ infoU->ldvlv_offset = info->ldvlv_offset;
+ infoU->ldvlv_count = info->ldvlv_count;
+ if (!(infoU->ldvlv_attrvalue = bervalWtoU( info->ldvlv_attrvalue )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, infoU );
+ return NULL;
+ }
+ if (!(infoU->ldvlv_context = bervalWtoU( info->ldvlv_context )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, infoU->ldvlv_attrvalue );
+ RtlFreeHeap( GetProcessHeap(), 0, infoU );
+ return NULL;
+ }
+ infoU->ldvlv_extradata = info->ldvlv_extradata;
+ }
+ return infoU;
+}
+
+static inline void vlvinfofreeU( LDAPVLVInfoU *info )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, info->ldvlv_attrvalue );
+ RtlFreeHeap( GetProcessHeap(), 0, info->ldvlv_context );
+ RtlFreeHeap( GetProcessHeap(), 0, info );
+}
+#endif
diff --git a/dlls/wldap32/wldap32.h b/dlls/wldap32/wldap32.h
index 5b099c9fabc..17132ff80c1 100644
--- a/dlls/wldap32/wldap32.h
+++ b/dlls/wldap32/wldap32.h
@@ -30,14 +30,7 @@ ULONG map_error( int ) DECLSPEC_HIDDEN;
* to and from ansi (A), wide character (W) and utf8 (U) encodings.
*/
-static inline char *strdupU( const char *src )
-{
- char *dst;
- if (!src) return NULL;
- if ((dst = heap_alloc( (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src );
- return dst;
-}
-
+#ifdef HAVE_LDAP
static inline WCHAR *strdupW( const WCHAR *src )
{
WCHAR *dst;
@@ -264,16 +257,6 @@ static inline LPWSTR *strarraydupW( LPWSTR *strarray )
return strarrayW;
}
-static inline void strarrayfreeA( LPSTR *strarray )
-{
- if (strarray)
- {
- LPSTR *p = strarray;
- while (*p) strfreeA( *p++ );
- heap_free( strarray );
- }
-}
-
static inline void strarrayfreeW( LPWSTR *strarray )
{
if (strarray)
@@ -316,6 +299,17 @@ static inline void bvarrayfreeW( struct WLDAP32_berval **bv )
while (*p) heap_free( *p++ );
heap_free( bv );
}
+#endif
+
+static inline void strarrayfreeA( LPSTR *strarray )
+{
+ if (strarray)
+ {
+ LPSTR *p = strarray;
+ while (*p) strfreeA( *p++ );
+ heap_free( strarray );
+ }
+}
#ifdef HAVE_LDAP
--
2.30.2
1
0
[PATCH 4/5] gdi32: Move common SetLayout() code to nulldrv_SetLayout().
by Zhiyi Zhang April 14, 2021
by Zhiyi Zhang April 14, 2021
April 14, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 12 +-----------
dlls/gdi32/driver.c | 13 ++++++++++++-
dlls/gdi32/enhmfdrv/dc.c | 4 +++-
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 830fabf6e78..eb9dbf85668 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -1922,17 +1922,7 @@ DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
if (dc)
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetLayout );
- layout = physdev->funcs->pSetLayout( physdev, layout );
- if (layout != GDI_ERROR)
- {
- oldlayout = dc->layout;
- dc->layout = layout;
- if (layout != oldlayout)
- {
- if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
- DC_UpdateXforms( dc );
- }
- }
+ oldlayout = physdev->funcs->pSetLayout( physdev, layout );
release_dc_ptr( dc );
}
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 09b051cd6fa..a2ebd018bca 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -795,7 +795,18 @@ static void CDECL nulldrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
static DWORD CDECL nulldrv_SetLayout( PHYSDEV dev, DWORD layout )
{
- return layout;
+ DC *dc = get_nulldrv_dc( dev );
+ DWORD old_layout;
+
+ old_layout = dc->layout;
+ dc->layout = layout;
+ if (layout != old_layout)
+ {
+ if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
+ DC_UpdateXforms( dc );
+ }
+
+ return old_layout;
}
static BOOL CDECL nulldrv_SetDeviceGammaRamp( PHYSDEV dev, void *ramp )
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 2a749418829..72b6afeee8b 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -334,12 +334,14 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMRSETLAYOUT emr;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
- return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
+ return next->funcs->pSetLayout( next, layout );
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
--
2.27.0
1
0