Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/adsldp/tests/ldap.c
4393 views
1
/*
2
* LDAPNamespace Tests
3
*
4
* Copyright 2019 Dmitry Timoshkov
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include <stdarg.h>
22
#include <stdio.h>
23
24
#define COBJMACROS
25
26
#include "windef.h"
27
#include "winbase.h"
28
#include "objbase.h"
29
#include "iads.h"
30
#include "adserr.h"
31
#include "adshlp.h"
32
33
#include "wine/test.h"
34
35
#include "initguid.h"
36
DEFINE_GUID(CLSID_LDAP,0x228d9a81,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
37
DEFINE_GUID(CLSID_LDAPNamespace,0x228d9a82,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
38
DEFINE_OLEGUID(CLSID_PointerMoniker,0x306,0,0);
39
40
static BOOL server_down;
41
42
static const struct
43
{
44
const WCHAR *path;
45
HRESULT hr, hr_ads_open, hr_ads_get;
46
const WCHAR *user, *password;
47
LONG flags;
48
} test[] =
49
{
50
{ L"invalid", MK_E_SYNTAX, E_ADS_BAD_PATHNAME, E_FAIL },
51
{ L"LDAP", MK_E_SYNTAX, E_ADS_BAD_PATHNAME, E_FAIL },
52
{ L"LDAP:", S_OK },
53
{ L"LDAP:/", E_ADS_BAD_PATHNAME },
54
{ L"LDAP://", E_ADS_BAD_PATHNAME },
55
{ L"LDAP://ldap.forumsys.com", S_OK },
56
{ L"LDAP:///ldap.forumsys.com", E_ADS_BAD_PATHNAME },
57
{ L"LDAP://ldap.forumsys.com:389", S_OK },
58
{ L"LDAP://ldap.forumsys.com:389/DC=example,DC=com", S_OK },
59
{ L"LDAP://ldap.forumsys.com/", E_ADS_BAD_PATHNAME },
60
{ L"LDAP://ldap.forumsys.com/rootDSE", S_OK },
61
{ L"LDAP://ldap.forumsys.com/rootDSE/", E_ADS_BAD_PATHNAME },
62
{ L"LDAP://ldap.forumsys.com/rootDSE/invalid", E_ADS_BAD_PATHNAME },
63
{ L"LDAP://ldap.forumsys.com/rootDSE", S_OK, S_OK, S_OK, NULL, NULL, 0 },
64
{ L"LDAP://ldap.forumsys.com/rootDSE", S_OK, S_OK, S_OK, L"CN=read-only-admin,DC=example,DC=com", L"password", 0 },
65
};
66
67
static void test_LDAP(void)
68
{
69
HRESULT hr;
70
IUnknown *unk;
71
IADs *ads;
72
IADsOpenDSObject *ads_open;
73
IDispatch *disp;
74
BSTR path, user, password;
75
int i;
76
77
if (server_down) return;
78
79
hr = CoCreateInstance(&CLSID_LDAPNamespace, 0, CLSCTX_INPROC_SERVER, &IID_IADs, (void **)&ads);
80
ok(hr == S_OK, "got %#lx\n", hr);
81
IADs_Release(ads);
82
83
hr = CoCreateInstance(&CLSID_LDAPNamespace, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
84
ok(hr == S_OK, "got %#lx\n", hr);
85
86
hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void **)&disp);
87
ok(hr == S_OK, "got %#lx\n", hr);
88
IDispatch_Release(disp);
89
90
hr = IUnknown_QueryInterface(unk, &IID_IADsOpenDSObject, (void **)&ads_open);
91
ok(hr == S_OK, "got %#lx\n", hr);
92
93
for (i = 0; i < ARRAY_SIZE(test); i++)
94
{
95
path = SysAllocString(test[i].path);
96
user = test[i].user ? SysAllocString(test[i].user) : NULL;
97
password = test[i].password ? SysAllocString(test[i].password) : NULL;
98
99
hr = IADsOpenDSObject_OpenDSObject(ads_open, path, user, password, test[i].flags, &disp);
100
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
101
{
102
SysFreeString(path);
103
skip("server is down\n");
104
server_down = TRUE;
105
break;
106
}
107
ok(hr == test[i].hr || hr == test[i].hr_ads_open, "%d: got %#lx, expected %#lx\n", i, hr, test[i].hr);
108
if (hr == S_OK)
109
IDispatch_Release(disp);
110
111
hr = ADsOpenObject(path, user, password, test[i].flags, &IID_IADs, (void **)&ads);
112
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
113
{
114
SysFreeString(path);
115
skip("server is down\n");
116
server_down = TRUE;
117
break;
118
}
119
ok(hr == test[i].hr || hr == test[i].hr_ads_get, "%d: got %#lx, expected %#lx\n", i, hr, test[i].hr);
120
if (hr == S_OK)
121
IADs_Release(ads);
122
123
hr = ADsGetObject(path, &IID_IDispatch, (void **)&disp);
124
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
125
{
126
SysFreeString(path);
127
skip("server is down\n");
128
server_down = TRUE;
129
break;
130
}
131
ok(hr == test[i].hr || hr == test[i].hr_ads_get, "%d: got %#lx, expected %#lx\n", i, hr, test[i].hr);
132
if (hr == S_OK)
133
IDispatch_Release(disp);
134
135
SysFreeString(path);
136
SysFreeString(user);
137
SysFreeString(password);
138
}
139
140
141
IADsOpenDSObject_Release(ads_open);
142
IUnknown_Release(unk);
143
}
144
145
static void test_ParseDisplayName(void)
146
{
147
HRESULT hr;
148
IBindCtx *bc;
149
IParseDisplayName *parse;
150
IMoniker *mk;
151
IUnknown *unk;
152
CLSID clsid;
153
BSTR path;
154
ULONG count;
155
int i;
156
157
if (server_down) return;
158
159
hr = CoCreateInstance(&CLSID_LDAP, 0, CLSCTX_INPROC_SERVER, &IID_IParseDisplayName, (void **)&parse);
160
ok(hr == S_OK, "got %#lx\n", hr);
161
IParseDisplayName_Release(parse);
162
163
hr = CoCreateInstance(&CLSID_LDAP, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
164
ok(hr == S_OK, "got %#lx\n", hr);
165
hr = IUnknown_QueryInterface(unk, &IID_IParseDisplayName, (void **)&parse);
166
ok(hr == S_OK, "got %#lx\n", hr);
167
IUnknown_Release(unk);
168
169
hr = CreateBindCtx(0, &bc);
170
ok(hr == S_OK, "got %#lx\n", hr);
171
172
for (i = 0; i < ARRAY_SIZE(test); i++)
173
{
174
path = SysAllocString(test[i].path);
175
176
count = 0xdeadbeef;
177
hr = IParseDisplayName_ParseDisplayName(parse, bc, path, &count, &mk);
178
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
179
{
180
SysFreeString(path);
181
skip("server is down\n");
182
server_down = TRUE;
183
break;
184
}
185
ok(hr == test[i].hr || hr == test[i].hr_ads_open, "%d: got %#lx, expected %#lx\n", i, hr, test[i].hr);
186
if (hr == S_OK)
187
{
188
ok(count == lstrlenW(test[i].path), "%d: got %ld\n", i, count);
189
190
hr = IMoniker_GetClassID(mk, &clsid);
191
ok(hr == S_OK, "got %#lx\n", hr);
192
ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "%d: got %s\n", i, wine_dbgstr_guid(&clsid));
193
194
IMoniker_Release(mk);
195
}
196
197
SysFreeString(path);
198
199
count = 0xdeadbeef;
200
hr = MkParseDisplayName(bc, test[i].path, &count, &mk);
201
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
202
{
203
skip("server is down\n");
204
server_down = TRUE;
205
break;
206
}
207
todo_wine_if(i == 0 || i == 1 || i == 11 || i == 12)
208
ok(hr == test[i].hr, "%d: got %#lx, expected %#lx\n", i, hr, test[i].hr);
209
if (hr == S_OK)
210
{
211
ok(count == lstrlenW(test[i].path), "%d: got %ld\n", i, count);
212
213
hr = IMoniker_GetClassID(mk, &clsid);
214
ok(hr == S_OK, "got %#lx\n", hr);
215
ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "%d: got %s\n", i, wine_dbgstr_guid(&clsid));
216
217
IMoniker_Release(mk);
218
}
219
}
220
221
IBindCtx_Release(bc);
222
IParseDisplayName_Release(parse);
223
}
224
225
struct result
226
{
227
const WCHAR *name;
228
ADSTYPEENUM type;
229
const WCHAR *values[16];
230
};
231
232
struct search
233
{
234
const WCHAR *dn;
235
ADS_SCOPEENUM scope;
236
struct result res[16];
237
};
238
239
static void do_search(const struct search *s)
240
{
241
HRESULT hr;
242
IDirectorySearch *ds;
243
ADS_SEARCHPREF_INFO pref[2];
244
ADS_SEARCH_HANDLE sh;
245
ADS_SEARCH_COLUMN col;
246
LPWSTR name;
247
const struct result *res;
248
249
if (server_down) return;
250
251
trace("search DN %s\n", wine_dbgstr_w(s->dn));
252
253
hr = ADsGetObject(s->dn, &IID_IDirectorySearch, (void **)&ds);
254
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
255
{
256
skip("server is down\n");
257
server_down = TRUE;
258
return;
259
}
260
ok(hr == S_OK, "got %#lx\n", hr);
261
262
pref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
263
pref[0].vValue.dwType = ADSTYPE_INTEGER;
264
pref[0].vValue.Integer = s->scope;
265
pref[0].dwStatus = 0xdeadbeef;
266
267
pref[1].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
268
pref[1].vValue.dwType = ADSTYPE_INTEGER;
269
pref[1].vValue.Integer = 5;
270
pref[1].dwStatus = 0xdeadbeef;
271
272
hr = IDirectorySearch_SetSearchPreference(ds, pref, ARRAY_SIZE(pref));
273
ok(hr == S_OK, "got %#lx\n", hr);
274
ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %u\n", pref[0].dwStatus);
275
ok(pref[1].dwStatus == ADS_STATUS_S_OK, "got %u\n", pref[1].dwStatus);
276
277
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
278
ok(hr == S_OK, "got %#lx\n", hr);
279
280
res = s->res;
281
282
while ((hr = IDirectorySearch_GetNextRow(ds, sh)) != S_ADS_NOMORE_ROWS)
283
{
284
ok(hr == S_OK, "got %#lx\n", hr);
285
286
while ((hr = IDirectorySearch_GetNextColumnName(ds, sh, &name)) != S_ADS_NOMORE_COLUMNS)
287
{
288
DWORD i;
289
290
ok(hr == S_OK, "got %#lx\n", hr);
291
ok(res->name != NULL, "got extra row %s\n", wine_dbgstr_w(name));
292
ok(!wcscmp(res->name, name), "expected %s, got %s\n", wine_dbgstr_w(res->name), wine_dbgstr_w(name));
293
294
memset(&col, 0xde, sizeof(col));
295
hr = IDirectorySearch_GetColumn(ds, sh, name, &col);
296
ok(hr == S_OK, "got %#lx\n", hr);
297
298
ok(col.dwADsType == res->type, "got %d for %s\n", col.dwADsType, wine_dbgstr_w(name));
299
300
for (i = 0; i < col.dwNumValues; i++)
301
{
302
ok(col.pADsValues[i].dwType == col.dwADsType, "%lu: got %d for %s\n", i, col.pADsValues[i].dwType, wine_dbgstr_w(name));
303
304
ok(res->values[i] != NULL, "expected to have more values for %s\n", wine_dbgstr_w(name));
305
if (!res->values[i]) break;
306
307
ok(!wcscmp(res->values[i], col.pADsValues[i].CaseIgnoreString),
308
"expected %s, got %s\n", wine_dbgstr_w(res->values[i]), wine_dbgstr_w(col.pADsValues[i].CaseIgnoreString));
309
}
310
311
IDirectorySearch_FreeColumn(ds, &col);
312
FreeADsMem(name);
313
res++;
314
}
315
}
316
317
ok(res->name == NULL, "there are more rows in test data: %s\n", wine_dbgstr_w(res->name));
318
319
hr = IDirectorySearch_CloseSearchHandle(ds, sh);
320
ok(hr == S_OK, "got %#lx\n", hr);
321
322
IDirectorySearch_Release(ds);
323
}
324
325
static void test_DirectorySearch(void)
326
{
327
static const struct search root_base =
328
{
329
L"LDAP://ldap.forumsys.com", ADS_SCOPE_BASE,
330
{
331
{ L"objectClass", ADSTYPE_CASE_IGNORE_STRING, { L"top", L"OpenLDAProotDSE", NULL } },
332
{ L"ADsPath", ADSTYPE_CASE_IGNORE_STRING, { L"LDAP://ldap.forumsys.com/", NULL } },
333
{ NULL }
334
}
335
};
336
static const struct search scientists_base =
337
{
338
L"LDAP://ldap.forumsys.com/OU=scientists,DC=example,DC=com", ADS_SCOPE_BASE,
339
{
340
{ L"uniqueMember", ADSTYPE_CASE_IGNORE_STRING, { L"uid=einstein,dc=example,dc=com",
341
L"uid=tesla,dc=example,dc=com", L"uid=newton,dc=example,dc=com", L"uid=galileo,dc=example,dc=com",
342
L"uid=training,dc=example,dc=com", L"uid=jmacy,dc=example,dc=com", NULL } },
343
{ L"ou", ADSTYPE_CASE_IGNORE_STRING, { L"scientists", NULL } },
344
{ L"cn", ADSTYPE_CASE_IGNORE_STRING, { L"Scientists", NULL } },
345
{ L"objectClass", ADSTYPE_CASE_IGNORE_STRING, { L"groupOfUniqueNames", L"top", NULL } },
346
{ L"ADsPath", ADSTYPE_CASE_IGNORE_STRING, { L"LDAP://ldap.forumsys.com/ou=scientists,dc=example,dc=com", NULL } },
347
{ NULL }
348
}
349
};
350
static const struct search scientists_subtree =
351
{
352
L"LDAP://ldap.forumsys.com/OU=scientists,DC=example,DC=com", ADS_SCOPE_SUBTREE,
353
{
354
{ L"uniqueMember", ADSTYPE_CASE_IGNORE_STRING, { L"uid=einstein,dc=example,dc=com",
355
L"uid=tesla,dc=example,dc=com", L"uid=newton,dc=example,dc=com", L"uid=galileo,dc=example,dc=com",
356
L"uid=training,dc=example,dc=com", L"uid=jmacy,dc=example,dc=com", NULL } },
357
{ L"ou", ADSTYPE_CASE_IGNORE_STRING, { L"scientists", NULL } },
358
{ L"cn", ADSTYPE_CASE_IGNORE_STRING, { L"Scientists", NULL } },
359
{ L"objectClass", ADSTYPE_CASE_IGNORE_STRING, { L"groupOfUniqueNames", L"top", NULL } },
360
{ L"ADsPath", ADSTYPE_CASE_IGNORE_STRING, { L"LDAP://ldap.forumsys.com/ou=scientists,dc=example,dc=com", NULL } },
361
{ L"uniqueMember", ADSTYPE_CASE_IGNORE_STRING, { L"uid=tesla,dc=example,dc=com", NULL } },
362
{ L"ou", ADSTYPE_CASE_IGNORE_STRING, { L"italians", NULL } },
363
{ L"cn", ADSTYPE_CASE_IGNORE_STRING, { L"Italians", NULL } },
364
{ L"objectClass", ADSTYPE_CASE_IGNORE_STRING, { L"groupOfUniqueNames", L"top", NULL } },
365
{ L"ADsPath", ADSTYPE_CASE_IGNORE_STRING, { L"LDAP://ldap.forumsys.com/ou=italians,ou=scientists,dc=example,dc=com", NULL } },
366
{ NULL }
367
}
368
};
369
HRESULT hr;
370
IDirectorySearch *ds;
371
ADS_SEARCHPREF_INFO pref[2];
372
ADS_SEARCH_HANDLE sh;
373
ADS_SEARCH_COLUMN col;
374
LPWSTR name;
375
376
if (server_down) return;
377
378
hr = ADsGetObject(L"LDAP:", &IID_IDirectorySearch, (void **)&ds);
379
ok(hr == E_NOINTERFACE, "got %#lx\n", hr);
380
381
hr = ADsGetObject(L"LDAP://ldap.forumsys.com/rootDSE", &IID_IDirectorySearch, (void **)&ds);
382
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
383
{
384
skip("server is down\n");
385
server_down = TRUE;
386
return;
387
}
388
ok(hr == E_NOINTERFACE, "got %#lx\n", hr);
389
390
hr = ADsGetObject(L"LDAP://ldap.forumsys.com", &IID_IDirectorySearch, (void **)&ds);
391
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
392
{
393
skip("server is down\n");
394
server_down = TRUE;
395
return;
396
}
397
ok(hr == S_OK, "got %#lx\n", hr);
398
399
pref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
400
pref[0].vValue.dwType = ADSTYPE_INTEGER;
401
pref[0].vValue.Integer = ADS_SCOPE_BASE;
402
pref[0].dwStatus = 0xdeadbeef;
403
404
pref[1].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
405
pref[1].vValue.dwType = ADSTYPE_INTEGER;
406
pref[1].vValue.Integer = 5;
407
pref[1].dwStatus = 0xdeadbeef;
408
409
hr = IDirectorySearch_SetSearchPreference(ds, pref, ARRAY_SIZE(pref));
410
ok(hr == S_OK, "got %#lx\n", hr);
411
ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %u\n", pref[0].dwStatus);
412
ok(pref[1].dwStatus == ADS_STATUS_S_OK, "got %u\n", pref[1].dwStatus);
413
414
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, NULL);
415
ok(hr == E_ADS_BAD_PARAMETER, "got %#lx\n", hr);
416
417
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, 1, &sh);
418
ok(hr == E_ADS_BAD_PARAMETER, "got %#lx\n", hr);
419
420
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
421
ok(hr == S_OK, "got %#lx\n", hr);
422
423
hr = IDirectorySearch_GetNextColumnName(ds, sh, &name);
424
ok(hr == E_ADS_BAD_PARAMETER, "got %#lx\n", hr);
425
426
hr = IDirectorySearch_GetPreviousRow(ds, sh);
427
todo_wine
428
ok(hr == E_ADS_BAD_PARAMETER, "got %#lx\n", hr);
429
430
while (IDirectorySearch_GetNextRow(ds, sh) != S_ADS_NOMORE_ROWS)
431
{
432
while (IDirectorySearch_GetNextColumnName(ds, sh, &name) != S_ADS_NOMORE_COLUMNS)
433
{
434
DWORD i;
435
436
hr = IDirectorySearch_GetColumn(ds, sh, name, &col);
437
ok(hr == S_OK, "got %#lx for column %s\n", hr, wine_dbgstr_w(name));
438
439
if (winetest_debug > 1) /* useful to create test arrays */
440
{
441
printf("Column %s (values type %d):\n", wine_dbgstr_w(name), col.dwADsType);
442
printf("{ ");
443
for (i = 0; i < col.dwNumValues; i++)
444
printf("%s, ", wine_dbgstr_w(col.pADsValues[i].CaseIgnoreString));
445
printf("NULL }\n");
446
}
447
448
hr = IDirectorySearch_FreeColumn(ds, &col);
449
ok(hr == S_OK, "got %#lx\n", hr);
450
FreeADsMem(name);
451
}
452
453
name = (void *)0xdeadbeef;
454
hr = IDirectorySearch_GetNextColumnName(ds, sh, &name);
455
ok(hr == S_ADS_NOMORE_COLUMNS, "got %#lx\n", hr);
456
ok(name == NULL, "got %p/%s\n", name, wine_dbgstr_w(name));
457
}
458
459
hr = IDirectorySearch_GetNextRow(ds, sh);
460
ok(hr == S_ADS_NOMORE_ROWS, "got %#lx\n", hr);
461
462
name = NULL;
463
hr = IDirectorySearch_GetNextColumnName(ds, sh, &name);
464
todo_wine
465
ok(hr == S_OK, "got %#lx\n", hr);
466
todo_wine
467
ok(name && !wcscmp(name, L"ADsPath"), "got %s\n", wine_dbgstr_w(name));
468
FreeADsMem(name);
469
470
name = (void *)0xdeadbeef;
471
hr = IDirectorySearch_GetNextColumnName(ds, sh, &name);
472
ok(hr == S_ADS_NOMORE_COLUMNS, "got %#lx\n", hr);
473
ok(name == NULL, "got %p/%s\n", name, wine_dbgstr_w(name));
474
475
hr = IDirectorySearch_GetColumn(ds, sh, NULL, &col);
476
ok(hr == E_ADS_BAD_PARAMETER, "got %#lx\n", hr);
477
478
hr = IDirectorySearch_GetFirstRow(ds, sh);
479
ok(hr == S_OK, "got %#lx\n", hr);
480
481
memset(&col, 0x55, sizeof(col));
482
hr = IDirectorySearch_GetColumn(ds, sh, (WCHAR *)L"deadbeef", &col);
483
ok(hr == E_ADS_COLUMN_NOT_SET, "got %#lx\n", hr);
484
ok(!col.pszAttrName, "got %p\n", col.pszAttrName);
485
ok(col.dwADsType == ADSTYPE_INVALID, "got %d\n", col.dwADsType);
486
ok(!col.pADsValues, "got %p\n", col.pADsValues);
487
ok(!col.dwNumValues, "got %lu\n", col.dwNumValues);
488
ok(!col.hReserved, "got %p\n", col.hReserved);
489
490
hr = IDirectorySearch_CloseSearchHandle(ds, sh);
491
ok(hr == S_OK, "got %#lx\n", hr);
492
493
IDirectorySearch_Release(ds);
494
495
do_search(&root_base);
496
do_search(&scientists_base);
497
do_search(&scientists_subtree);
498
}
499
500
static void test_DirectoryObject(void)
501
{
502
HRESULT hr;
503
IDirectoryObject *dirobj;
504
IUnknown *unk;
505
IDirectorySearch *ds;
506
ADS_SEARCHPREF_INFO pref[3];
507
ADS_SEARCH_HANDLE sh;
508
ADS_SEARCH_COLUMN col;
509
510
if (server_down) return;
511
512
hr = ADsGetObject(L"LDAP://ldap.forumsys.com/OU=scientists,DC=example,DC=com", &IID_IDirectoryObject, (void **)&dirobj);
513
if (hr == HRESULT_FROM_WIN32(ERROR_DS_SERVER_DOWN))
514
{
515
skip("server is down\n");
516
server_down = TRUE;
517
return;
518
}
519
ok(hr == S_OK, "got %#lx\n", hr);
520
521
hr = IDirectoryObject_QueryInterface(dirobj, &IID_IADsOpenDSObject, (void **)&unk);
522
todo_wine
523
ok(hr == E_NOINTERFACE, "got %#lx\n", hr);
524
if (hr == S_OK) IUnknown_Release(unk);
525
hr = IDirectoryObject_QueryInterface(dirobj, &IID_IDispatch, (void **)&unk);
526
ok(hr == S_OK, "got %#lx\n", hr);
527
IUnknown_Release(unk);
528
hr = IDirectoryObject_QueryInterface(dirobj, &IID_IADs, (void **)&unk);
529
ok(hr == S_OK, "got %#lx\n", hr);
530
IUnknown_Release(unk);
531
hr = IDirectoryObject_QueryInterface(dirobj, &IID_IDirectorySearch, (void **)&ds);
532
ok(hr == S_OK, "got %#lx\n", hr);
533
534
pref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
535
pref[0].vValue.dwType = ADSTYPE_INTEGER;
536
pref[0].vValue.Integer = ADS_SCOPE_BASE;
537
pref[0].dwStatus = 0xdeadbeef;
538
539
pref[1].dwSearchPref = ADS_SEARCHPREF_SECURITY_MASK;
540
pref[1].vValue.dwType = ADSTYPE_INTEGER;
541
pref[1].vValue.Integer = ADS_SECURITY_INFO_OWNER | ADS_SECURITY_INFO_GROUP | ADS_SECURITY_INFO_DACL;
542
pref[1].dwStatus = 0xdeadbeef;
543
544
pref[2].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
545
pref[2].vValue.dwType = ADSTYPE_INTEGER;
546
pref[2].vValue.Integer = 5;
547
pref[2].dwStatus = 0xdeadbeef;
548
549
hr = IDirectorySearch_SetSearchPreference(ds, pref, ARRAY_SIZE(pref));
550
ok(hr == S_ADS_ERRORSOCCURRED, "got %#lx\n", hr);
551
ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[0].dwStatus);
552
/* ldap.forumsys.com doesn't support NT security, real ADs DC - does */
553
ok(pref[1].dwStatus == ADS_STATUS_INVALID_SEARCHPREF, "got %d\n", pref[1].dwStatus);
554
ok(pref[2].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[2].dwStatus);
555
556
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
557
ok(hr == S_OK, "got %#lx\n", hr);
558
559
hr = IDirectorySearch_GetNextRow(ds, sh);
560
ok(hr == S_OK, "got %#lx\n", hr);
561
562
hr = IDirectorySearch_GetColumn(ds, sh, (WCHAR *)L"nTSecurityDescriptor", &col);
563
ok(hr == E_ADS_COLUMN_NOT_SET, "got %#lx\n", hr);
564
565
hr = IDirectorySearch_CloseSearchHandle(ds, sh);
566
ok(hr == S_OK, "got %#lx\n", hr);
567
568
pref[0].dwSearchPref = ADS_SEARCHPREF_TOMBSTONE;
569
pref[0].vValue.dwType = ADSTYPE_BOOLEAN;
570
pref[0].vValue.Integer = 1;
571
pref[0].dwStatus = 0xdeadbeef;
572
573
pref[1].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
574
pref[1].vValue.dwType = ADSTYPE_INTEGER;
575
pref[1].vValue.Integer = 5;
576
pref[1].dwStatus = 0xdeadbeef;
577
578
hr = IDirectorySearch_SetSearchPreference(ds, pref, 2);
579
ok(hr == S_OK, "got %#lx\n", hr);
580
ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[0].dwStatus);
581
ok(pref[1].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[1].dwStatus);
582
583
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
584
todo_wine ok(hr == S_OK, "got %#lx\n", hr);
585
if (hr == S_OK)
586
{
587
hr = IDirectorySearch_GetNextRow(ds, sh);
588
ok(hr == HRESULT_FROM_WIN32(ERROR_DS_UNAVAILABLE_CRIT_EXTENSION), "got %#lx\n", hr);
589
590
hr = IDirectorySearch_CloseSearchHandle(ds, sh);
591
ok(hr == S_OK, "got %#lx\n", hr);
592
}
593
594
IDirectorySearch_Release(ds);
595
IDirectoryObject_Release(dirobj);
596
}
597
598
START_TEST(ldap)
599
{
600
HRESULT hr;
601
602
hr = CoInitialize(NULL);
603
ok(hr == S_OK, "got %#lx\n", hr);
604
605
test_LDAP();
606
test_ParseDisplayName();
607
test_DirectorySearch();
608
test_DirectoryObject();
609
610
CoUninitialize();
611
}
612
613