[PATCH 2/3] adsldp: Add support for IDirectorySearch::SetSearchPreference(ADS_SEARCHPREF_SECURITY_MASK).

Dmitry Timoshkov dmitry at baikal.ru
Thu Apr 2 04:16:59 CDT 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/adsldp.c     | 57 +++++++++++++++++++++++++++++++++++++++-
 dlls/adsldp/tests/ldap.c | 36 ++++++++++++++++++++++++-
 include/iads.idl         |  8 ++++++
 include/winldap.h        |  2 ++
 4 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index b2a8e61815..9a52d78500 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -45,6 +45,10 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(adsldp);
 
+#ifndef LDAP_OPT_SERVER_CONTROLS
+#define LDAP_OPT_SERVER_CONTROLS 0x0012
+#endif
+
 DEFINE_GUID(CLSID_LDAP,0x228d9a81,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
 DEFINE_GUID(CLSID_LDAPNamespace,0x228d9a82,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
 
@@ -1127,6 +1131,7 @@ static ULONG WINAPI search_Release(IDirectorySearch *iface)
 static HRESULT WINAPI search_SetSearchPreference(IDirectorySearch *iface, PADS_SEARCHPREF_INFO prefs, DWORD count)
 {
     LDAP_namespace *ldap = impl_from_IDirectorySearch(iface);
+    HRESULT hr = S_OK;
     DWORD i;
 
     TRACE("%p,%p,%u\n", iface, prefs, count);
@@ -1159,6 +1164,56 @@ static HRESULT WINAPI search_SetSearchPreference(IDirectorySearch *iface, PADS_S
             }
             break;
 
+        case ADS_SEARCHPREF_SECURITY_MASK:
+        {
+            int security_mask;
+            ULONG err;
+            BerElement *ber;
+            struct berval *berval;
+            LDAPControlW *ctrls[2], mask;
+
+            if (prefs[i].vValue.dwType != ADSTYPE_INTEGER)
+            {
+                FIXME("ADS_SEARCHPREF_SECURITY_MASK: not supportd dwType %d\n", prefs[i].vValue.dwType);
+                prefs[i].dwStatus = ADS_STATUS_INVALID_SEARCHPREFVALUE;
+                break;
+            }
+
+            TRACE("SECURITY_MASK: %08x\n", prefs[i].vValue.u.Integer);
+            security_mask = prefs[i].vValue.u.Integer;
+            if (!security_mask)
+                security_mask = ADS_SECURITY_INFO_OWNER;
+
+            ber = ber_alloc_t(LBER_USE_DER);
+            if (!ber || ber_printf(ber, (char *)"{i}", security_mask) == -1 || ber_flatten(ber, &berval) == -1)
+            {
+                ber_free(ber, 1);
+                prefs[i].dwStatus = ADS_STATUS_INVALID_SEARCHPREF;
+                break;
+            }
+            TRACE("ber: %s\n", debugstr_an(berval->bv_val, berval->bv_len));
+
+            mask.ldctl_oid = (WCHAR *)L"1.2.840.113556.1.4.801";
+            mask.ldctl_iscritical = TRUE;
+            mask.ldctl_value.bv_val = berval->bv_val;
+            mask.ldctl_value.bv_len = berval->bv_len;
+            ctrls[0] = &mask;
+            ctrls[1] = NULL;
+            err = ldap_set_optionW(ldap->ld, LDAP_OPT_SERVER_CONTROLS, ctrls);
+            if (err != LDAP_SUCCESS)
+            {
+                TRACE("ldap_set_option error %#x\n", err);
+                prefs[i].dwStatus = ADS_STATUS_INVALID_SEARCHPREF;
+                hr = S_ADS_ERRORSOCCURRED;
+            }
+            else
+                prefs[i].dwStatus = ADS_STATUS_S_OK;
+
+            ber_bvfree(berval);
+            ber_free(ber, 1);
+            break;
+        }
+
         default:
             FIXME("pref %d, type %u: stub\n", prefs[i].dwSearchPref, prefs[i].vValue.dwType);
             prefs[i].dwStatus = ADS_STATUS_INVALID_SEARCHPREF;
@@ -1166,7 +1221,7 @@ static HRESULT WINAPI search_SetSearchPreference(IDirectorySearch *iface, PADS_S
         }
     }
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI search_ExecuteSearch(IDirectorySearch *iface, LPWSTR filter, LPWSTR *names,
diff --git a/dlls/adsldp/tests/ldap.c b/dlls/adsldp/tests/ldap.c
index 998581e2f8..80815b07a0 100644
--- a/dlls/adsldp/tests/ldap.c
+++ b/dlls/adsldp/tests/ldap.c
@@ -465,6 +465,9 @@ static void test_DirectoryObject(void)
     IDirectoryObject *dirobj;
     IUnknown *unk;
     IDirectorySearch *ds;
+    ADS_SEARCHPREF_INFO pref[2];
+    ADS_SEARCH_HANDLE sh;
+    ADS_SEARCH_COLUMN col;
 
     hr = ADsGetObject(L"LDAP://ldap.forumsys.com/OU=scientists,DC=example,DC=com", &IID_IDirectoryObject, (void **)&dirobj);
     if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
@@ -485,8 +488,39 @@ todo_wine
     IUnknown_Release(unk);
     hr = IDirectoryObject_QueryInterface(dirobj, &IID_IDirectorySearch, (void **)&ds);
     ok(hr == S_OK, "got %#x\n", hr);
-    IDirectorySearch_Release(ds);
 
+    pref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
+    pref[0].vValue.dwType = ADSTYPE_INTEGER;
+    pref[0].vValue.Integer = ADS_SCOPE_BASE;
+    pref[0].dwStatus = 0xdeadbeef;
+    pref[1].dwSearchPref = ADS_SEARCHPREF_SECURITY_MASK;
+    pref[1].vValue.dwType = ADSTYPE_INTEGER;
+    pref[1].vValue.Integer = ADS_SECURITY_INFO_OWNER | ADS_SECURITY_INFO_GROUP | ADS_SECURITY_INFO_DACL;
+    pref[1].dwStatus = 0xdeadbeef;
+    hr = IDirectorySearch_SetSearchPreference(ds, pref, ARRAY_SIZE(pref));
+todo_wine
+    ok(hr == S_ADS_ERRORSOCCURRED, "got %#x\n", hr);
+    ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[0].dwStatus);
+    /* ldap.forumsys.com doesn't support NT security, real ADs DC - does  */
+todo_wine
+    ok(pref[1].dwStatus == ADS_STATUS_INVALID_SEARCHPREF, "got %d\n", pref[1].dwStatus);
+
+    hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
+todo_wine
+    ok(hr == S_OK, "got %#x\n", hr);
+    if (hr != S_OK) goto fail;
+
+    hr = IDirectorySearch_GetNextRow(ds, sh);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    hr = IDirectorySearch_GetColumn(ds, sh, (WCHAR *)L"nTSecurityDescriptor", &col);
+    ok(hr == E_ADS_COLUMN_NOT_SET, "got %#x\n", hr);
+
+    hr = IDirectorySearch_CloseSearchHandle(ds, sh);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    IDirectorySearch_Release(ds);
+fail:
     IDirectoryObject_Release(dirobj);
 }
 
diff --git a/include/iads.idl b/include/iads.idl
index b04ed0846a..e9eaab77be 100644
--- a/include/iads.idl
+++ b/include/iads.idl
@@ -362,6 +362,14 @@ typedef struct _ads_attr_info
     DWORD dwNumValues;
 } ADS_ATTR_INFO, *PADS_ATTR_INFO;
 
+typedef enum
+{
+    ADS_SECURITY_INFO_OWNER = 0x1,
+    ADS_SECURITY_INFO_GROUP = 0x2,
+    ADS_SECURITY_INFO_DACL  = 0x4,
+    ADS_SECURITY_INFO_SACL  = 0x8
+} ADS_SECURITY_INFO_ENUM;
+
 /*****************************************************************************
  *    IADsContainer interface
  */
diff --git a/include/winldap.h b/include/winldap.h
index bd5acab767..2d41eaa3fa 100644
--- a/include/winldap.h
+++ b/include/winldap.h
@@ -104,6 +104,8 @@ typedef enum {
 #define LDAP_SCOPE_ONELEVEL     0x01
 #define LDAP_SCOPE_SUBTREE      0x02
 
+#define LBER_USE_DER            0x01
+
 typedef struct berelement
 {
     PCHAR opaque;
-- 
2.25.1




More information about the wine-devel mailing list