a05529e61bc1408db5a9251699c84e69b4d52c52
[reactos.git] / reactos / dll / win32 / lsasrv / lookup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Local Security Authority (LSA) Server
4 * FILE: reactos/dll/win32/lsasrv/lookup.c
5 * PURPOSE: Sid / Name lookup functions
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "lsasrv.h"
11
12 /* GLOBALS *****************************************************************/
13
14 typedef wchar_t *PSAMPR_SERVER_NAME;
15 typedef void *SAMPR_HANDLE;
16
17 typedef struct _SAMPR_RETURNED_USTRING_ARRAY
18 {
19 unsigned long Count;
20 PRPC_UNICODE_STRING Element;
21 } SAMPR_RETURNED_USTRING_ARRAY, *PSAMPR_RETURNED_USTRING_ARRAY;
22
23 typedef struct _SAMPR_ULONG_ARRAY
24 {
25 unsigned long Count;
26 unsigned long *Element;
27 } SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
28
29
30 VOID
31 NTAPI
32 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr);
33
34 VOID
35 NTAPI
36 SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr);
37
38 NTSTATUS
39 NTAPI
40 SamrConnect(IN PSAMPR_SERVER_NAME ServerName,
41 OUT SAMPR_HANDLE *ServerHandle,
42 IN ACCESS_MASK DesiredAccess);
43
44 NTSTATUS
45 NTAPI
46 SamrCloseHandle(IN OUT SAMPR_HANDLE *SamHandle);
47
48 NTSTATUS
49 NTAPI
50 SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
51 IN ACCESS_MASK DesiredAccess,
52 IN PRPC_SID DomainId,
53 OUT SAMPR_HANDLE *DomainHandle);
54
55 NTSTATUS
56 NTAPI
57 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
58 IN ULONG Count,
59 IN ULONG *RelativeIds,
60 OUT PSAMPR_RETURNED_USTRING_ARRAY Names,
61 OUT PSAMPR_ULONG_ARRAY Use);
62
63 NTSTATUS
64 NTAPI
65 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
66 IN ULONG Count,
67 IN RPC_UNICODE_STRING Names[],
68 OUT PSAMPR_ULONG_ARRAY RelativeIds,
69 OUT PSAMPR_ULONG_ARRAY Use);
70
71
72 typedef struct _WELL_KNOWN_SID
73 {
74 LIST_ENTRY ListEntry;
75 PSID Sid;
76 UNICODE_STRING AccountName;
77 UNICODE_STRING DomainName;
78 SID_NAME_USE Use;
79 } WELL_KNOWN_SID, *PWELL_KNOWN_SID;
80
81
82 LIST_ENTRY WellKnownSidListHead;
83
84
85 /* FUNCTIONS ***************************************************************/
86
87 BOOLEAN
88 LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
89 UCHAR SubAuthorityCount,
90 PULONG SubAuthorities,
91 PWSTR AccountName,
92 PWSTR DomainName,
93 SID_NAME_USE Use)
94 {
95 PWELL_KNOWN_SID SidEntry;
96 PULONG p;
97 ULONG i;
98
99 SidEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WELL_KNOWN_SID));
100 if (SidEntry == NULL)
101 return FALSE;
102
103 InitializeListHead(&SidEntry->ListEntry);
104
105 SidEntry->Sid = RtlAllocateHeap(RtlGetProcessHeap(),
106 0,
107 RtlLengthRequiredSid(SubAuthorityCount));
108 if (SidEntry->Sid == NULL)
109 {
110 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry);
111 return FALSE;
112 }
113
114 RtlInitializeSid(SidEntry->Sid,
115 IdentifierAuthority,
116 SubAuthorityCount);
117
118 for (i = 0; i < (ULONG)SubAuthorityCount; i++)
119 {
120 p = RtlSubAuthoritySid(SidEntry->Sid, i);
121 *p = SubAuthorities[i];
122 }
123
124 // RtlInitUnicodeString(&SidEntry->AccountName,
125 // AccountName);
126 SidEntry->AccountName.Length = wcslen(AccountName) * sizeof(WCHAR);
127 SidEntry->AccountName.MaximumLength = SidEntry->AccountName.Length + sizeof(WCHAR);
128 SidEntry->AccountName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0,
129 SidEntry->AccountName.MaximumLength);
130 if (SidEntry->AccountName.Buffer == NULL)
131 {
132 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry->Sid);
133 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry);
134 return FALSE;
135 }
136
137 wcscpy(SidEntry->AccountName.Buffer,
138 AccountName);
139
140 // RtlInitUnicodeString(&SidEntry->DomainName,
141 // DomainName);
142 SidEntry->DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
143 SidEntry->DomainName.MaximumLength = SidEntry->DomainName.Length + sizeof(WCHAR);
144 SidEntry->DomainName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0,
145 SidEntry->DomainName.MaximumLength);
146 if (SidEntry->DomainName.Buffer == NULL)
147 {
148 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry->AccountName.Buffer);
149 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry->Sid);
150 RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry);
151 return FALSE;
152 }
153
154 wcscpy(SidEntry->DomainName.Buffer,
155 DomainName);
156
157 SidEntry->Use = Use;
158
159 InsertTailList(&WellKnownSidListHead,
160 &SidEntry->ListEntry);
161
162 return TRUE;
163 }
164
165
166 NTSTATUS
167 LsapInitSids(VOID)
168 {
169 WCHAR szAccountName[80];
170 WCHAR szDomainName[80];
171 ULONG SubAuthorities[8];
172 HINSTANCE hInstance;
173
174 InitializeListHead(&WellKnownSidListHead);
175
176 hInstance = GetModuleHandleW(L"lsasrv.dll");
177
178 /* NT Authority */
179
180 LsapLoadString(hInstance, IDS_NT_AUTHORITY, szAccountName, 80);
181 LsapLoadString(hInstance, IDS_NT_AUTHORITY, szDomainName, 80);
182 LsapCreateSid(&NtAuthority,
183 0,
184 NULL,
185 szAccountName,
186 szDomainName,
187 SidTypeDomain);
188
189 /* Null Sid */
190 LsapLoadString(hInstance, IDS_NULL_RID, szAccountName, 80);
191
192 SubAuthorities[0] = SECURITY_NULL_RID;
193 LsapCreateSid(&NullSidAuthority,
194 1,
195 SubAuthorities,
196 szAccountName,
197 L"",
198 SidTypeWellKnownGroup);
199
200 /* World Sid */
201 LsapLoadString(hInstance, IDS_WORLD_RID, szAccountName, 80);
202
203 SubAuthorities[0] = SECURITY_WORLD_RID;
204 LsapCreateSid(&WorldSidAuthority,
205 1,
206 SubAuthorities,
207 szAccountName,
208 L"",
209 SidTypeWellKnownGroup);
210
211 /* Local Sid */
212 LsapLoadString(hInstance, IDS_LOCAL_RID, szAccountName, 80);
213
214 SubAuthorities[0] = SECURITY_LOCAL_RID;
215 LsapCreateSid(&LocalSidAuthority,
216 1,
217 SubAuthorities,
218 szAccountName,
219 L"",
220 SidTypeWellKnownGroup);
221
222 /* Creator Owner Sid */
223 LsapLoadString(hInstance, IDS_CREATOR_OWNER_RID, szAccountName, 80);
224
225 SubAuthorities[0] = SECURITY_CREATOR_OWNER_RID;
226 LsapCreateSid(&CreatorSidAuthority,
227 1,
228 SubAuthorities,
229 szAccountName,
230 L"",
231 SidTypeWellKnownGroup);
232
233 /* Creator Group Sid */
234 LsapLoadString(hInstance, IDS_CREATOR_GROUP_RID, szAccountName, 80);
235
236 SubAuthorities[0] = SECURITY_CREATOR_GROUP_RID;
237 LsapCreateSid(&CreatorSidAuthority,
238 1,
239 SubAuthorities,
240 szAccountName,
241 L"",
242 SidTypeWellKnownGroup);
243
244 /* Creator Owner Server Sid */
245 LsapLoadString(hInstance, IDS_CREATOR_OWNER_SERVER_RID, szAccountName, 80);
246
247 SubAuthorities[0] = SECURITY_CREATOR_OWNER_SERVER_RID;
248 LsapCreateSid(&CreatorSidAuthority,
249 1,
250 SubAuthorities,
251 szAccountName,
252 L"",
253 SidTypeWellKnownGroup);
254
255 /* Creator Group Server Sid */
256 LsapLoadString(hInstance, IDS_CREATOR_GROUP_SERVER_RID, szAccountName, 80);
257
258 SubAuthorities[0] = SECURITY_CREATOR_GROUP_SERVER_RID;
259 LsapCreateSid(&CreatorSidAuthority,
260 1,
261 SubAuthorities,
262 szAccountName,
263 L"",
264 SidTypeWellKnownGroup);
265
266 /* Dialup Sid */
267 LsapLoadString(hInstance, IDS_DIALUP_RID, szAccountName, 80);
268 LsapLoadString(hInstance, IDS_NT_AUTHORITY, szDomainName, 80);
269
270 SubAuthorities[0] = SECURITY_DIALUP_RID;
271 LsapCreateSid(&NtAuthority,
272 1,
273 SubAuthorities,
274 szAccountName,
275 szDomainName,
276 SidTypeWellKnownGroup);
277
278 /* Network Sid */
279 LsapLoadString(hInstance, IDS_DIALUP_RID, szAccountName, 80);
280
281 SubAuthorities[0] = SECURITY_NETWORK_RID;
282 LsapCreateSid(&NtAuthority,
283 1,
284 SubAuthorities,
285 szAccountName,
286 szDomainName,
287 SidTypeWellKnownGroup);
288
289 /* Batch Sid*/
290 LsapLoadString(hInstance, IDS_BATCH_RID, szAccountName, 80);
291
292 SubAuthorities[0] = SECURITY_BATCH_RID;
293 LsapCreateSid(&NtAuthority,
294 1,
295 SubAuthorities,
296 szAccountName,
297 szDomainName,
298 SidTypeWellKnownGroup);
299
300 /* Interactive Sid */
301 LsapLoadString(hInstance, IDS_INTERACTIVE_RID, szAccountName, 80);
302
303 SubAuthorities[0] = SECURITY_INTERACTIVE_RID;
304 LsapCreateSid(&NtAuthority,
305 1,
306 SubAuthorities,
307 szAccountName,
308 szDomainName,
309 SidTypeWellKnownGroup);
310
311 /* Service Sid */
312 LsapLoadString(hInstance, IDS_SERVICE_RID, szAccountName, 80);
313
314 SubAuthorities[0] = SECURITY_SERVICE_RID;
315 LsapCreateSid(&NtAuthority,
316 1,
317 SubAuthorities,
318 szAccountName,
319 szDomainName,
320 SidTypeWellKnownGroup);
321
322 /* Anonymous Logon Sid */
323 LsapLoadString(hInstance, IDS_ANONYMOUS_LOGON_RID, szAccountName, 80);
324
325 SubAuthorities[0] = SECURITY_ANONYMOUS_LOGON_RID;
326 LsapCreateSid(&NtAuthority,
327 1,
328 SubAuthorities,
329 szAccountName,
330 szDomainName,
331 SidTypeWellKnownGroup);
332
333 /* Proxy Sid */
334 LsapLoadString(hInstance, IDS_PROXY_RID, szAccountName, 80);
335
336 SubAuthorities[0] = SECURITY_PROXY_RID;
337 LsapCreateSid(&NtAuthority,
338 1,
339 SubAuthorities,
340 szAccountName,
341 szDomainName,
342 SidTypeWellKnownGroup);
343
344 /* Enterprise Controllers Sid */
345 LsapLoadString(hInstance, IDS_ENTERPRISE_CONTROLLERS_RID, szAccountName, 80);
346
347 SubAuthorities[0] = SECURITY_ENTERPRISE_CONTROLLERS_RID;
348 LsapCreateSid(&NtAuthority,
349 1,
350 SubAuthorities,
351 szAccountName,
352 szDomainName,
353 SidTypeWellKnownGroup);
354
355 /* Principal Self Sid */
356 LsapLoadString(hInstance, IDS_PRINCIPAL_SELF_RID, szAccountName, 80);
357
358 SubAuthorities[0] = SECURITY_PRINCIPAL_SELF_RID;
359 LsapCreateSid(&NtAuthority,
360 1,
361 SubAuthorities,
362 szAccountName,
363 szDomainName,
364 SidTypeWellKnownGroup);
365
366 /* Authenticated Users Sid */
367 LsapLoadString(hInstance, IDS_AUTHENTICATED_USER_RID, szAccountName, 80);
368
369 SubAuthorities[0] = SECURITY_AUTHENTICATED_USER_RID;
370 LsapCreateSid(&NtAuthority,
371 1,
372 SubAuthorities,
373 szAccountName,
374 szDomainName,
375 SidTypeWellKnownGroup);
376
377 /* Restricted Code Sid */
378 LsapLoadString(hInstance, IDS_RESTRICTED_CODE_RID, szAccountName, 80);
379
380 SubAuthorities[0] = SECURITY_RESTRICTED_CODE_RID;
381 LsapCreateSid(&NtAuthority,
382 1,
383 SubAuthorities,
384 szAccountName,
385 szDomainName,
386 SidTypeWellKnownGroup);
387
388 /* Terminal Server Sid */
389 LsapLoadString(hInstance, IDS_TERMINAL_SERVER_RID, szAccountName, 80);
390
391 SubAuthorities[0] = SECURITY_TERMINAL_SERVER_RID;
392 LsapCreateSid(&NtAuthority,
393 1,
394 SubAuthorities,
395 szAccountName,
396 szDomainName,
397 SidTypeWellKnownGroup);
398
399 /* Remote Logon Sid */
400 LsapLoadString(hInstance, IDS_REMOTE_LOGON_RID, szAccountName, 80);
401
402 SubAuthorities[0] = SECURITY_REMOTE_LOGON_RID;
403 LsapCreateSid(&NtAuthority,
404 1,
405 SubAuthorities,
406 szAccountName,
407 szDomainName,
408 SidTypeWellKnownGroup);
409
410 /* This Organization Sid */
411 LsapLoadString(hInstance, IDS_THIS_ORGANIZATION_RID, szAccountName, 80);
412
413 SubAuthorities[0] = SECURITY_THIS_ORGANIZATION_RID;
414 LsapCreateSid(&NtAuthority,
415 1,
416 SubAuthorities,
417 szAccountName,
418 szDomainName,
419 SidTypeWellKnownGroup);
420
421 /* Local System Sid */
422 LsapLoadString(hInstance, IDS_LOCAL_SYSTEM_RID, szAccountName, 80);
423
424 SubAuthorities[0] = SECURITY_LOCAL_SYSTEM_RID;
425 LsapCreateSid(&NtAuthority,
426 1,
427 SubAuthorities,
428 szAccountName,
429 szDomainName,
430 SidTypeWellKnownGroup);
431
432 /* Local Service Sid */
433 LsapLoadString(hInstance, IDS_LOCAL_SERVICE_RID, szAccountName, 80);
434
435 SubAuthorities[0] = SECURITY_LOCAL_SERVICE_RID;
436 LsapCreateSid(&NtAuthority,
437 1,
438 SubAuthorities,
439 szAccountName,
440 szDomainName,
441 SidTypeWellKnownGroup);
442
443 LsapCreateSid(&NtAuthority,
444 1,
445 SubAuthorities,
446 L"LOCALSERVICE",
447 L"NT AUTHORITY",
448 SidTypeWellKnownGroup);
449
450 /* Network Service Sid */
451 LsapLoadString(hInstance, IDS_NETWORK_SERVICE_RID, szAccountName, 80);
452
453 SubAuthorities[0] = SECURITY_NETWORK_SERVICE_RID;
454 LsapCreateSid(&NtAuthority,
455 1,
456 SubAuthorities,
457 szAccountName,
458 szDomainName,
459 SidTypeWellKnownGroup);
460
461 LsapCreateSid(&NtAuthority,
462 1,
463 SubAuthorities,
464 L"NETWORKSERVICE",
465 L"NT AUTHORITY",
466 SidTypeWellKnownGroup);
467
468 /* Builtin Domain Sid */
469 LsapLoadString(hInstance, IDS_BUILTIN_DOMAIN_RID, szAccountName, 80);
470 LsapLoadString(hInstance, IDS_BUILTIN_DOMAIN_RID, szDomainName, 80);
471
472 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
473 LsapCreateSid(&NtAuthority,
474 1,
475 SubAuthorities,
476 szAccountName,
477 szDomainName,
478 SidTypeDomain);
479
480 /* Administrators Alias Sid */
481 LsapLoadString(hInstance, IDS_ALIAS_RID_ADMINS, szAccountName, 80);
482
483 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
484 SubAuthorities[1] = DOMAIN_ALIAS_RID_ADMINS;
485 LsapCreateSid(&NtAuthority,
486 2,
487 SubAuthorities,
488 szAccountName,
489 szDomainName,
490 SidTypeAlias);
491
492 /* Users Alias Sid */
493 LsapLoadString(hInstance, IDS_ALIAS_RID_USERS, szAccountName, 80);
494
495 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
496 SubAuthorities[1] = DOMAIN_ALIAS_RID_USERS;
497 LsapCreateSid(&NtAuthority,
498 2,
499 SubAuthorities,
500 szAccountName,
501 szDomainName,
502 SidTypeAlias);
503
504 /* Guests Alias Sid */
505 LsapLoadString(hInstance, IDS_ALIAS_RID_GUESTS, szAccountName, 80);
506
507 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
508 SubAuthorities[1] = DOMAIN_ALIAS_RID_GUESTS;
509 LsapCreateSid(&NtAuthority,
510 2,
511 SubAuthorities,
512 szAccountName,
513 szDomainName,
514 SidTypeAlias);
515
516 /* Power User Alias Sid */
517 LsapLoadString(hInstance, IDS_ALIAS_RID_POWER_USERS, szAccountName, 80);
518
519 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
520 SubAuthorities[1] = DOMAIN_ALIAS_RID_POWER_USERS;
521 LsapCreateSid(&NtAuthority,
522 2,
523 SubAuthorities,
524 szAccountName,
525 szDomainName,
526 SidTypeAlias);
527
528 /* Account Operators Alias Sid */
529 LsapLoadString(hInstance, IDS_ALIAS_RID_ACCOUNT_OPS, szAccountName, 80);
530
531 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
532 SubAuthorities[1] = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
533 LsapCreateSid(&NtAuthority,
534 2,
535 SubAuthorities,
536 szAccountName,
537 szDomainName,
538 SidTypeAlias);
539
540 /* System Operators Alias Sid */
541 LsapLoadString(hInstance, IDS_ALIAS_RID_SYSTEM_OPS, szAccountName, 80);
542
543 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
544 SubAuthorities[1] = DOMAIN_ALIAS_RID_SYSTEM_OPS;
545 LsapCreateSid(&NtAuthority,
546 2,
547 SubAuthorities,
548 szAccountName,
549 szDomainName,
550 SidTypeAlias);
551
552 /* Print Operators Alias Sid */
553 LsapLoadString(hInstance, IDS_ALIAS_RID_PRINT_OPS, szAccountName, 80);
554
555 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
556 SubAuthorities[1] = DOMAIN_ALIAS_RID_PRINT_OPS;
557 LsapCreateSid(&NtAuthority,
558 2,
559 SubAuthorities,
560 szAccountName,
561 szDomainName,
562 SidTypeAlias);
563
564 /* Backup Operators Alias Sid */
565 LsapLoadString(hInstance, IDS_ALIAS_RID_BACKUP_OPS, szAccountName, 80);
566
567 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
568 SubAuthorities[1] = DOMAIN_ALIAS_RID_BACKUP_OPS;
569 LsapCreateSid(&NtAuthority,
570 2,
571 SubAuthorities,
572 szAccountName,
573 szDomainName,
574 SidTypeAlias);
575
576 /* Replicators Alias Sid */
577 LsapLoadString(hInstance, IDS_ALIAS_RID_REPLICATOR, szAccountName, 80);
578
579 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
580 SubAuthorities[1] = DOMAIN_ALIAS_RID_REPLICATOR;
581 LsapCreateSid(&NtAuthority,
582 2,
583 SubAuthorities,
584 szAccountName,
585 szDomainName,
586 SidTypeAlias);
587
588 /* RAS Servers Alias Sid */
589 LsapLoadString(hInstance, IDS_ALIAS_RID_RAS_SERVERS, szAccountName, 80);
590
591 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
592 SubAuthorities[1] = DOMAIN_ALIAS_RID_RAS_SERVERS;
593 LsapCreateSid(&NtAuthority,
594 2,
595 SubAuthorities,
596 szAccountName,
597 szDomainName,
598 SidTypeAlias);
599
600 /* Pre-Windows 2000 Compatible Access Alias Sid */
601 LsapLoadString(hInstance, IDS_ALIAS_RID_PREW2KCOMPACCESS, szAccountName, 80);
602
603 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
604 SubAuthorities[1] = DOMAIN_ALIAS_RID_PREW2KCOMPACCESS;
605 LsapCreateSid(&NtAuthority,
606 2,
607 SubAuthorities,
608 szAccountName,
609 szDomainName,
610 SidTypeAlias);
611
612 /* Remote Desktop Users Alias Sid */
613 LsapLoadString(hInstance, IDS_ALIAS_RID_REMOTE_DESKTOP_USERS, szAccountName, 80);
614
615 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
616 SubAuthorities[1] = DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS;
617 LsapCreateSid(&NtAuthority,
618 2,
619 SubAuthorities,
620 szAccountName,
621 szDomainName,
622 SidTypeAlias);
623
624 /* Network Configuration Operators Alias Sid */
625 LsapLoadString(hInstance, IDS_ALIAS_RID_NETWORK_CONFIGURATION_OPS, szAccountName, 80);
626
627 SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
628 SubAuthorities[1] = DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS;
629 LsapCreateSid(&NtAuthority,
630 2,
631 SubAuthorities,
632 szAccountName,
633 szDomainName,
634 SidTypeAlias);
635
636 /* FIXME: Add more well known sids */
637
638 return STATUS_SUCCESS;
639 }
640
641
642 PWELL_KNOWN_SID
643 LsapLookupWellKnownSid(PSID Sid)
644 {
645 PLIST_ENTRY ListEntry;
646 PWELL_KNOWN_SID Ptr;
647
648 ListEntry = WellKnownSidListHead.Flink;
649 while (ListEntry != &WellKnownSidListHead)
650 {
651 Ptr = CONTAINING_RECORD(ListEntry,
652 WELL_KNOWN_SID,
653 ListEntry);
654 if (RtlEqualSid(Sid, Ptr->Sid))
655 {
656 return Ptr;
657 }
658
659 ListEntry = ListEntry->Flink;
660 }
661
662 return NULL;
663 }
664
665
666 PWELL_KNOWN_SID
667 LsapLookupIsolatedWellKnownName(PUNICODE_STRING AccountName)
668 {
669 PLIST_ENTRY ListEntry;
670 PWELL_KNOWN_SID Ptr;
671
672 ListEntry = WellKnownSidListHead.Flink;
673 while (ListEntry != &WellKnownSidListHead)
674 {
675 Ptr = CONTAINING_RECORD(ListEntry,
676 WELL_KNOWN_SID,
677 ListEntry);
678 if (RtlEqualUnicodeString(AccountName, &Ptr->AccountName, TRUE))
679 {
680 return Ptr;
681 }
682
683 ListEntry = ListEntry->Flink;
684 }
685
686 return NULL;
687 }
688
689
690 PWELL_KNOWN_SID
691 LsapLookupFullyQualifiedWellKnownName(PUNICODE_STRING AccountName,
692 PUNICODE_STRING DomainName)
693 {
694 PLIST_ENTRY ListEntry;
695 PWELL_KNOWN_SID Ptr;
696
697 ListEntry = WellKnownSidListHead.Flink;
698 while (ListEntry != &WellKnownSidListHead)
699 {
700 Ptr = CONTAINING_RECORD(ListEntry,
701 WELL_KNOWN_SID,
702 ListEntry);
703 if (RtlEqualUnicodeString(AccountName, &Ptr->AccountName, TRUE) &&
704 RtlEqualUnicodeString(DomainName, &Ptr->DomainName, TRUE))
705 {
706 return Ptr;
707 }
708
709 ListEntry = ListEntry->Flink;
710 }
711
712 return NULL;
713 }
714
715
716 static
717 NTSTATUS
718 LsapSplitNames(DWORD Count,
719 PRPC_UNICODE_STRING Names,
720 PRPC_UNICODE_STRING *DomainNames,
721 PRPC_UNICODE_STRING *AccountNames)
722 {
723 PRPC_UNICODE_STRING DomainsBuffer = NULL;
724 PRPC_UNICODE_STRING AccountsBuffer = NULL;
725 ULONG DomainLength;
726 ULONG AccountLength;
727 ULONG i;
728 LPWSTR Ptr;
729 NTSTATUS Status = STATUS_SUCCESS;
730
731 DomainsBuffer = MIDL_user_allocate(Count * sizeof(RPC_UNICODE_STRING));
732 if (DomainsBuffer == NULL)
733 {
734 Status = STATUS_INSUFFICIENT_RESOURCES;
735 goto done;
736 }
737
738 AccountsBuffer = MIDL_user_allocate(Count * sizeof(RPC_UNICODE_STRING));
739 if (AccountsBuffer == NULL)
740 {
741 Status = STATUS_INSUFFICIENT_RESOURCES;
742 goto done;
743 }
744
745 for (i = 0; i < Count; i++)
746 {
747 //TRACE("Name: %wZ\n", &Names[i]);
748
749 Ptr = wcschr(Names[i].Buffer, L'\\');
750 if (Ptr == NULL)
751 {
752 AccountLength = Names[i].Length / sizeof(WCHAR);
753
754 AccountsBuffer[i].Length = Names[i].Length;
755 AccountsBuffer[i].MaximumLength = AccountsBuffer[i].Length + sizeof(WCHAR);
756 AccountsBuffer[i].Buffer = MIDL_user_allocate(AccountsBuffer[i].MaximumLength);
757 if (AccountsBuffer[i].Buffer == NULL)
758 {
759 Status = STATUS_INSUFFICIENT_RESOURCES;
760 goto done;
761 }
762
763 CopyMemory(AccountsBuffer[i].Buffer,
764 Names[i].Buffer,
765 AccountsBuffer[i].Length);
766 AccountsBuffer[i].Buffer[AccountLength] = UNICODE_NULL;
767
768 //TRACE("Account name: %wZ\n", &AccountsBuffer[i]);
769 }
770 else
771 {
772 DomainLength = (ULONG)(ULONG_PTR)(Ptr - Names[i].Buffer);
773 AccountLength = (Names[i].Length / sizeof(WCHAR)) - DomainLength - 1;
774 //TRACE("DomainLength: %u\n", DomainLength);
775 //TRACE("AccountLength: %u\n", AccountLength);
776
777 if (DomainLength > 0)
778 {
779 DomainsBuffer[i].Length = (USHORT)DomainLength * sizeof(WCHAR);
780 DomainsBuffer[i].MaximumLength = DomainsBuffer[i].Length + sizeof(WCHAR);
781 DomainsBuffer[i].Buffer = MIDL_user_allocate(DomainsBuffer[i].MaximumLength);
782 if (DomainsBuffer[i].Buffer == NULL)
783 {
784 Status = STATUS_INSUFFICIENT_RESOURCES;
785 goto done;
786 }
787
788 CopyMemory(DomainsBuffer[i].Buffer,
789 Names[i].Buffer,
790 DomainsBuffer[i].Length);
791 DomainsBuffer[i].Buffer[DomainLength] = UNICODE_NULL;
792
793 //TRACE("Domain name: %wZ\n", &DomainsBuffer[i]);
794 }
795
796 AccountsBuffer[i].Length = (USHORT)AccountLength * sizeof(WCHAR);
797 AccountsBuffer[i].MaximumLength = AccountsBuffer[i].Length + sizeof(WCHAR);
798 AccountsBuffer[i].Buffer = MIDL_user_allocate(AccountsBuffer[i].MaximumLength);
799 if (AccountsBuffer[i].Buffer == NULL)
800 {
801 Status = STATUS_INSUFFICIENT_RESOURCES;
802 goto done;
803 }
804
805 CopyMemory(AccountsBuffer[i].Buffer,
806 &(Names[i].Buffer[DomainLength + 1]),
807 AccountsBuffer[i].Length);
808 AccountsBuffer[i].Buffer[AccountLength] = UNICODE_NULL;
809
810 //TRACE("Account name: %wZ\n", &AccountsBuffer[i]);
811 }
812 }
813
814 done:
815 if (!NT_SUCCESS(Status))
816 {
817 if (AccountsBuffer != NULL)
818 {
819 for (i = 0; i < Count; i++)
820 {
821 if (AccountsBuffer[i].Buffer != NULL)
822 MIDL_user_free(AccountsBuffer[i].Buffer);
823 }
824
825 MIDL_user_free(AccountsBuffer);
826 }
827
828 if (DomainsBuffer != NULL)
829 {
830 for (i = 0; i < Count; i++)
831 {
832 if (DomainsBuffer[i].Buffer != NULL)
833 MIDL_user_free(DomainsBuffer[i].Buffer);
834 }
835
836 MIDL_user_free(DomainsBuffer);
837 }
838 }
839 else
840 {
841 *DomainNames = DomainsBuffer;
842 *AccountNames = AccountsBuffer;
843 }
844
845 return Status;
846 }
847
848
849 static NTSTATUS
850 LsapAddDomainToDomainsList(PLSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains,
851 PUNICODE_STRING Name,
852 PSID Sid,
853 PULONG Index)
854 {
855 ULONG i;
856
857 i = 0;
858 while (i < ReferencedDomains->Entries &&
859 ReferencedDomains->Domains[i].Sid != NULL)
860 {
861 if (RtlEqualSid(Sid, ReferencedDomains->Domains[i].Sid))
862 {
863 *Index = i;
864 return STATUS_SUCCESS;
865 }
866
867 i++;
868 }
869
870 ReferencedDomains->Domains[i].Sid = MIDL_user_allocate(RtlLengthSid(Sid));
871 if (ReferencedDomains->Domains[i].Sid == NULL)
872 return STATUS_INSUFFICIENT_RESOURCES;
873
874 RtlCopySid(RtlLengthSid(Sid), ReferencedDomains->Domains[i].Sid, Sid);
875
876 ReferencedDomains->Domains[i].Name.Length = Name->Length;
877 ReferencedDomains->Domains[i].Name.MaximumLength = Name->MaximumLength;
878 ReferencedDomains->Domains[i].Name.Buffer = MIDL_user_allocate(Name->MaximumLength);
879 if (ReferencedDomains->Domains[i].Sid == NULL)
880 {
881 MIDL_user_free(ReferencedDomains->Domains[i].Sid);
882 ReferencedDomains->Domains[i].Sid = NULL;
883 return STATUS_INSUFFICIENT_RESOURCES;
884 }
885
886 RtlCopyMemory(ReferencedDomains->Domains[i].Name.Buffer,
887 Name->Buffer,
888 Name->MaximumLength);
889
890 ReferencedDomains->Entries++;
891 *Index = i;
892
893 return STATUS_SUCCESS;
894 }
895
896
897 static BOOLEAN
898 LsapIsPrefixSid(IN PSID PrefixSid,
899 IN PSID Sid)
900 {
901 PISID Sid1 = PrefixSid, Sid2 = Sid;
902 ULONG i;
903
904 if (Sid1->Revision != Sid2->Revision)
905 return FALSE;
906
907 if ((Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0]) ||
908 (Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1]) ||
909 (Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2]) ||
910 (Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3]) ||
911 (Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4]) ||
912 (Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5]))
913 return FALSE;
914
915 if (Sid1->SubAuthorityCount >= Sid2->SubAuthorityCount)
916 return FALSE;
917
918 if (Sid1->SubAuthorityCount == 0)
919 return TRUE;
920
921 for (i = 0; i < Sid1->SubAuthorityCount; i++)
922 {
923 if (Sid1->SubAuthority[i] != Sid2->SubAuthority[i])
924 return FALSE;
925 }
926
927 return TRUE;
928 }
929
930
931 ULONG
932 LsapGetRelativeIdFromSid(PSID Sid_)
933 {
934 PISID Sid = Sid_;
935
936 if (Sid->SubAuthorityCount != 0)
937 return Sid->SubAuthority[Sid->SubAuthorityCount - 1];
938
939 return 0;
940 }
941
942
943 static PSID
944 CreateSidFromSidAndRid(PSID SrcSid,
945 ULONG RelativeId)
946 {
947 UCHAR RidCount;
948 PSID DstSid;
949 ULONG i;
950 ULONG DstSidSize;
951 PULONG p, q;
952
953 RidCount = *RtlSubAuthorityCountSid(SrcSid);
954 if (RidCount >= 8)
955 return NULL;
956
957 DstSidSize = RtlLengthRequiredSid(RidCount + 1);
958
959 DstSid = MIDL_user_allocate(DstSidSize);
960 if (DstSid == NULL)
961 return NULL;
962
963 RtlInitializeSid(DstSid,
964 RtlIdentifierAuthoritySid(SrcSid),
965 RidCount + 1);
966
967 for (i = 0; i < (ULONG)RidCount; i++)
968 {
969 p = RtlSubAuthoritySid(SrcSid, i);
970 q = RtlSubAuthoritySid(DstSid, i);
971 *q = *p;
972 }
973
974 q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
975 *q = RelativeId;
976
977 return DstSid;
978 }
979
980
981 static PSID
982 CreateDomainSidFromAccountSid(PSID AccountSid)
983 {
984 UCHAR RidCount;
985 PSID DomainSid;
986 ULONG i;
987 ULONG DstSidSize;
988 PULONG p, q;
989
990 RidCount = *RtlSubAuthorityCountSid(AccountSid);
991 if (RidCount > 0)
992 RidCount--;
993
994 DstSidSize = RtlLengthRequiredSid(RidCount);
995
996 DomainSid = MIDL_user_allocate(DstSidSize);
997 if (DomainSid == NULL)
998 return NULL;
999
1000 RtlInitializeSid(DomainSid,
1001 RtlIdentifierAuthoritySid(AccountSid),
1002 RidCount);
1003
1004 for (i = 0; i < (ULONG)RidCount; i++)
1005 {
1006 p = RtlSubAuthoritySid(AccountSid, i);
1007 q = RtlSubAuthoritySid(DomainSid, i);
1008 *q = *p;
1009 }
1010
1011 return DomainSid;
1012 }
1013
1014
1015 static PSID
1016 LsapCopySid(PSID SrcSid)
1017 {
1018 UCHAR RidCount;
1019 PSID DstSid;
1020 ULONG i;
1021 ULONG DstSidSize;
1022 PULONG p, q;
1023
1024 RidCount = *RtlSubAuthorityCountSid(SrcSid);
1025 DstSidSize = RtlLengthRequiredSid(RidCount);
1026
1027 DstSid = MIDL_user_allocate(DstSidSize);
1028 if (DstSid == NULL)
1029 return NULL;
1030
1031 RtlInitializeSid(DstSid,
1032 RtlIdentifierAuthoritySid(SrcSid),
1033 RidCount);
1034
1035 for (i = 0; i < (ULONG)RidCount; i++)
1036 {
1037 p = RtlSubAuthoritySid(SrcSid, i);
1038 q = RtlSubAuthoritySid(DstSid, i);
1039 *q = *p;
1040 }
1041
1042 return DstSid;
1043 }
1044
1045
1046 static
1047 NTSTATUS
1048 LsapLookupIsolatedNames(DWORD Count,
1049 PRPC_UNICODE_STRING DomainNames,
1050 PRPC_UNICODE_STRING AccountNames,
1051 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1052 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1053 PULONG Mapped)
1054 {
1055 UNICODE_STRING EmptyDomainName = RTL_CONSTANT_STRING(L"");
1056 PWELL_KNOWN_SID ptr, ptr2;
1057 PSID DomainSid;
1058 ULONG DomainIndex;
1059 ULONG i;
1060 NTSTATUS Status = STATUS_SUCCESS;
1061
1062 for (i = 0; i < Count; i++)
1063 {
1064 /* Ignore names which were already mapped */
1065 if (SidsBuffer[i].Use != SidTypeUnknown)
1066 continue;
1067
1068 /* Ignore fully qualified account names */
1069 if (DomainNames[i].Length != 0)
1070 continue;
1071
1072 TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1073
1074 /* Look-up all well-known names */
1075 ptr = LsapLookupIsolatedWellKnownName((PUNICODE_STRING)&AccountNames[i]);
1076 if (ptr != NULL)
1077 {
1078 SidsBuffer[i].Use = ptr->Use;
1079 SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
1080 if (SidsBuffer[i].Sid == NULL)
1081 {
1082 Status = STATUS_INSUFFICIENT_RESOURCES;
1083 goto done;
1084 }
1085
1086 SidsBuffer[i].DomainIndex = -1;
1087 SidsBuffer[i].Flags = 0;
1088
1089 if (ptr->Use == SidTypeDomain)
1090 {
1091 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1092 &ptr->AccountName,
1093 ptr->Sid,
1094 &DomainIndex);
1095 if (!NT_SUCCESS(Status))
1096 goto done;
1097
1098 SidsBuffer[i].DomainIndex = DomainIndex;
1099 }
1100 else
1101 {
1102 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
1103 if (ptr2 != NULL)
1104 {
1105 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1106 &ptr2->AccountName,
1107 ptr2->Sid,
1108 &DomainIndex);
1109 if (!NT_SUCCESS(Status))
1110 goto done;
1111
1112 SidsBuffer[i].DomainIndex = DomainIndex;
1113 }
1114 else
1115 {
1116 DomainSid = CreateDomainSidFromAccountSid(ptr->Sid);
1117 if (DomainSid == NULL)
1118 {
1119 Status = STATUS_INSUFFICIENT_RESOURCES;
1120 goto done;
1121 }
1122
1123 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1124 &EmptyDomainName,
1125 DomainSid,
1126 &DomainIndex);
1127
1128 if (DomainSid != NULL)
1129 {
1130 MIDL_user_free(DomainSid);
1131 DomainSid = NULL;
1132 }
1133
1134 if (!NT_SUCCESS(Status))
1135 goto done;
1136
1137 SidsBuffer[i].DomainIndex = DomainIndex;
1138 }
1139 }
1140
1141 (*Mapped)++;
1142 continue;
1143 }
1144
1145 /* Look-up the built-in domain */
1146 if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &BuiltinDomainName, TRUE))
1147 {
1148 SidsBuffer[i].Use = SidTypeDomain;
1149 SidsBuffer[i].Sid = LsapCopySid(BuiltinDomainSid);
1150 if (SidsBuffer[i].Sid == NULL)
1151 {
1152 Status = STATUS_INSUFFICIENT_RESOURCES;
1153 goto done;
1154 }
1155
1156 SidsBuffer[i].DomainIndex = -1;
1157 SidsBuffer[i].Flags = 0;
1158
1159 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1160 &BuiltinDomainName,
1161 BuiltinDomainSid,
1162 &DomainIndex);
1163 if (!NT_SUCCESS(Status))
1164 goto done;
1165
1166 SidsBuffer[i].DomainIndex = DomainIndex;
1167
1168 (*Mapped)++;
1169 continue;
1170 }
1171
1172 /* Look-up the account domain */
1173 if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &AccountDomainName, TRUE))
1174 {
1175 SidsBuffer[i].Use = SidTypeDomain;
1176 SidsBuffer[i].Sid = LsapCopySid(AccountDomainSid);
1177 if (SidsBuffer[i].Sid == NULL)
1178 {
1179 Status = STATUS_INSUFFICIENT_RESOURCES;
1180 goto done;
1181 }
1182 SidsBuffer[i].DomainIndex = -1;
1183 SidsBuffer[i].Flags = 0;
1184
1185 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1186 &AccountDomainName,
1187 AccountDomainSid,
1188 &DomainIndex);
1189 if (!NT_SUCCESS(Status))
1190 goto done;
1191
1192 SidsBuffer[i].DomainIndex = DomainIndex;
1193
1194 (*Mapped)++;
1195 continue;
1196 }
1197
1198 /* FIXME: Look-up the primary domain */
1199
1200 /* FIXME: Look-up the trusted domains */
1201
1202 }
1203
1204 done:
1205
1206 return Status;
1207 }
1208
1209
1210 static
1211 NTSTATUS
1212 LsapLookupIsolatedBuiltinNames(DWORD Count,
1213 PRPC_UNICODE_STRING DomainNames,
1214 PRPC_UNICODE_STRING AccountNames,
1215 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1216 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1217 PULONG Mapped)
1218 {
1219 SAMPR_HANDLE ServerHandle = NULL;
1220 SAMPR_HANDLE DomainHandle = NULL;
1221 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1222 SAMPR_ULONG_ARRAY Use = {0, NULL};
1223 ULONG DomainIndex;
1224 ULONG i;
1225 NTSTATUS Status = STATUS_SUCCESS;
1226
1227 Status = SamrConnect(NULL,
1228 &ServerHandle,
1229 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1230 if (!NT_SUCCESS(Status))
1231 {
1232 TRACE("SamrConnect failed (Status %08lx)\n", Status);
1233 goto done;
1234 }
1235
1236 Status = SamrOpenDomain(ServerHandle,
1237 DOMAIN_LOOKUP,
1238 BuiltinDomainSid,
1239 &DomainHandle);
1240 if (!NT_SUCCESS(Status))
1241 {
1242 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1243 goto done;
1244 }
1245
1246 for (i = 0; i < Count; i++)
1247 {
1248 /* Ignore names which were already mapped */
1249 if (SidsBuffer[i].Use != SidTypeUnknown)
1250 continue;
1251
1252 /* Ignore fully qualified account names */
1253 if (DomainNames[i].Length != 0)
1254 continue;
1255
1256 TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1257
1258 Status = SamrLookupNamesInDomain(DomainHandle,
1259 1,
1260 &AccountNames[i],
1261 &RelativeIds,
1262 &Use);
1263 if (NT_SUCCESS(Status))
1264 {
1265 TRACE("Found relative ID: %lu\n", RelativeIds.Element[0]);
1266
1267 SidsBuffer[i].Use = Use.Element[0];
1268 SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
1269 RelativeIds.Element[0]);
1270 if (SidsBuffer[i].Sid == NULL)
1271 {
1272 Status = STATUS_INSUFFICIENT_RESOURCES;
1273 goto done;
1274 }
1275
1276 SidsBuffer[i].DomainIndex = -1;
1277 SidsBuffer[i].Flags = 0;
1278
1279 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1280 &BuiltinDomainName,
1281 BuiltinDomainSid,
1282 &DomainIndex);
1283 if (!NT_SUCCESS(Status))
1284 goto done;
1285
1286 SidsBuffer[i].DomainIndex = DomainIndex;
1287
1288 (*Mapped)++;
1289 }
1290
1291 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1292 SamIFree_SAMPR_ULONG_ARRAY(&Use);
1293 }
1294
1295 done:
1296 if (DomainHandle != NULL)
1297 SamrCloseHandle(&DomainHandle);
1298
1299 if (ServerHandle != NULL)
1300 SamrCloseHandle(&ServerHandle);
1301
1302 return Status;
1303 }
1304
1305
1306 static
1307 NTSTATUS
1308 LsapLookupIsolatedAccountNames(DWORD Count,
1309 PRPC_UNICODE_STRING DomainNames,
1310 PRPC_UNICODE_STRING AccountNames,
1311 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1312 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1313 PULONG Mapped)
1314 {
1315 SAMPR_HANDLE ServerHandle = NULL;
1316 SAMPR_HANDLE DomainHandle = NULL;
1317 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1318 SAMPR_ULONG_ARRAY Use = {0, NULL};
1319 ULONG DomainIndex;
1320 ULONG i;
1321 NTSTATUS Status = STATUS_SUCCESS;
1322
1323 TRACE("()\n");
1324
1325 Status = SamrConnect(NULL,
1326 &ServerHandle,
1327 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1328 if (!NT_SUCCESS(Status))
1329 {
1330 TRACE("SamrConnect failed (Status %08lx)\n", Status);
1331 goto done;
1332 }
1333
1334 Status = SamrOpenDomain(ServerHandle,
1335 DOMAIN_LOOKUP,
1336 AccountDomainSid,
1337 &DomainHandle);
1338 if (!NT_SUCCESS(Status))
1339 {
1340 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1341 goto done;
1342 }
1343
1344 for (i = 0; i < Count; i++)
1345 {
1346 /* Ignore names which were already mapped */
1347 if (SidsBuffer[i].Use != SidTypeUnknown)
1348 continue;
1349
1350 /* Ignore fully qualified account names */
1351 if (DomainNames[i].Length != 0)
1352 continue;
1353
1354 TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1355
1356 Status = SamrLookupNamesInDomain(DomainHandle,
1357 1,
1358 &AccountNames[i],
1359 &RelativeIds,
1360 &Use);
1361 if (NT_SUCCESS(Status))
1362 {
1363 TRACE("Found relative ID: %lu\n", RelativeIds.Element[0]);
1364
1365 SidsBuffer[i].Use = Use.Element[0];
1366 SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
1367 RelativeIds.Element[0]);
1368 if (SidsBuffer[i].Sid == NULL)
1369 {
1370 Status = STATUS_INSUFFICIENT_RESOURCES;
1371 goto done;
1372 }
1373
1374 SidsBuffer[i].DomainIndex = -1;
1375 SidsBuffer[i].Flags = 0;
1376
1377 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1378 &AccountDomainName,
1379 AccountDomainSid,
1380 &DomainIndex);
1381 if (!NT_SUCCESS(Status))
1382 goto done;
1383
1384 SidsBuffer[i].DomainIndex = DomainIndex;
1385
1386 (*Mapped)++;
1387 }
1388
1389 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1390 SamIFree_SAMPR_ULONG_ARRAY(&Use);
1391 }
1392
1393 done:
1394 if (DomainHandle != NULL)
1395 SamrCloseHandle(&DomainHandle);
1396
1397 if (ServerHandle != NULL)
1398 SamrCloseHandle(&ServerHandle);
1399
1400 return Status;
1401 }
1402
1403
1404 static
1405 NTSTATUS
1406 LsapLookupFullyQualifiedWellKnownNames(DWORD Count,
1407 PRPC_UNICODE_STRING DomainNames,
1408 PRPC_UNICODE_STRING AccountNames,
1409 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1410 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1411 PULONG Mapped)
1412 {
1413 UNICODE_STRING EmptyDomainName = RTL_CONSTANT_STRING(L"");
1414 PWELL_KNOWN_SID ptr, ptr2;
1415 PSID DomainSid;
1416 ULONG DomainIndex;
1417 ULONG i;
1418 NTSTATUS Status = STATUS_SUCCESS;
1419
1420 for (i = 0; i < Count; i++)
1421 {
1422 /* Ignore names which were already mapped */
1423 if (SidsBuffer[i].Use != SidTypeUnknown)
1424 continue;
1425
1426 /* Ignore isolated account names */
1427 if (DomainNames[i].Length == 0)
1428 continue;
1429
1430 TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1431
1432 /* Look-up all well-known names */
1433 ptr = LsapLookupFullyQualifiedWellKnownName((PUNICODE_STRING)&AccountNames[i],
1434 (PUNICODE_STRING)&DomainNames[i]);
1435 if (ptr != NULL)
1436 {
1437 TRACE("Found it! (%wZ\\%wZ)\n", &ptr->DomainName, &ptr->AccountName);
1438
1439 SidsBuffer[i].Use = ptr->Use;
1440 SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
1441 if (SidsBuffer[i].Sid == NULL)
1442 {
1443 Status = STATUS_INSUFFICIENT_RESOURCES;
1444 goto done;
1445 }
1446
1447 SidsBuffer[i].DomainIndex = -1;
1448 SidsBuffer[i].Flags = 0;
1449
1450 if (ptr->Use == SidTypeDomain)
1451 {
1452 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1453 &ptr->AccountName,
1454 ptr->Sid,
1455 &DomainIndex);
1456 if (!NT_SUCCESS(Status))
1457 goto done;
1458
1459 SidsBuffer[i].DomainIndex = DomainIndex;
1460 }
1461 else
1462 {
1463 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
1464 if (ptr2 != NULL)
1465 {
1466 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1467 &ptr2->AccountName,
1468 ptr2->Sid,
1469 &DomainIndex);
1470 if (!NT_SUCCESS(Status))
1471 goto done;
1472
1473 SidsBuffer[i].DomainIndex = DomainIndex;
1474 }
1475 else
1476 {
1477 DomainSid = CreateDomainSidFromAccountSid(ptr->Sid);
1478 if (DomainSid == NULL)
1479 {
1480 Status = STATUS_INSUFFICIENT_RESOURCES;
1481 goto done;
1482 }
1483
1484 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1485 &EmptyDomainName,
1486 DomainSid,
1487 &DomainIndex);
1488
1489 if (DomainSid != NULL)
1490 {
1491 MIDL_user_free(DomainSid);
1492 DomainSid = NULL;
1493 }
1494
1495 if (!NT_SUCCESS(Status))
1496 goto done;
1497
1498 SidsBuffer[i].DomainIndex = DomainIndex;
1499 }
1500 }
1501
1502 (*Mapped)++;
1503 continue;
1504 }
1505 }
1506
1507 done:
1508 return Status;
1509 }
1510
1511
1512 static
1513 NTSTATUS
1514 LsapLookupBuiltinNames(DWORD Count,
1515 PRPC_UNICODE_STRING DomainNames,
1516 PRPC_UNICODE_STRING AccountNames,
1517 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1518 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1519 PULONG Mapped)
1520 {
1521 SAMPR_HANDLE ServerHandle = NULL;
1522 SAMPR_HANDLE DomainHandle = NULL;
1523 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1524 SAMPR_ULONG_ARRAY Use = {0, NULL};
1525 ULONG DomainIndex;
1526 ULONG i;
1527 NTSTATUS Status = STATUS_SUCCESS;
1528
1529 Status = SamrConnect(NULL,
1530 &ServerHandle,
1531 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1532 if (!NT_SUCCESS(Status))
1533 {
1534 TRACE("SamrConnect failed (Status %08lx)\n", Status);
1535 goto done;
1536 }
1537
1538 Status = SamrOpenDomain(ServerHandle,
1539 DOMAIN_LOOKUP,
1540 BuiltinDomainSid,
1541 &DomainHandle);
1542 if (!NT_SUCCESS(Status))
1543 {
1544 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1545 goto done;
1546 }
1547
1548 for (i = 0; i < Count; i++)
1549 {
1550 /* Ignore names which were already mapped */
1551 if (SidsBuffer[i].Use != SidTypeUnknown)
1552 continue;
1553
1554 /* Ignore isolated account names */
1555 if (DomainNames[i].Length == 0)
1556 continue;
1557
1558 if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &BuiltinDomainName, TRUE))
1559 continue;
1560
1561 TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1562
1563 Status = SamrLookupNamesInDomain(DomainHandle,
1564 1,
1565 &AccountNames[i],
1566 &RelativeIds,
1567 &Use);
1568 if (NT_SUCCESS(Status))
1569 {
1570 SidsBuffer[i].Use = Use.Element[0];
1571 SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
1572 RelativeIds.Element[0]);
1573 if (SidsBuffer[i].Sid == NULL)
1574 {
1575 Status = STATUS_INSUFFICIENT_RESOURCES;
1576 goto done;
1577 }
1578
1579 SidsBuffer[i].DomainIndex = -1;
1580 SidsBuffer[i].Flags = 0;
1581
1582 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1583 &BuiltinDomainName,
1584 BuiltinDomainSid,
1585 &DomainIndex);
1586 if (!NT_SUCCESS(Status))
1587 goto done;
1588
1589 SidsBuffer[i].DomainIndex = DomainIndex;
1590
1591 (*Mapped)++;
1592 }
1593
1594 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1595 SamIFree_SAMPR_ULONG_ARRAY(&Use);
1596 }
1597
1598 done:
1599 if (DomainHandle != NULL)
1600 SamrCloseHandle(&DomainHandle);
1601
1602 if (ServerHandle != NULL)
1603 SamrCloseHandle(&ServerHandle);
1604
1605 return Status;
1606 }
1607
1608
1609 static
1610 NTSTATUS
1611 LsapLookupAccountNames(DWORD Count,
1612 PRPC_UNICODE_STRING DomainNames,
1613 PRPC_UNICODE_STRING AccountNames,
1614 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1615 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1616 PULONG Mapped)
1617 {
1618 SAMPR_HANDLE ServerHandle = NULL;
1619 SAMPR_HANDLE DomainHandle = NULL;
1620 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1621 SAMPR_ULONG_ARRAY Use = {0, NULL};
1622 ULONG DomainIndex;
1623 ULONG i;
1624 NTSTATUS Status = STATUS_SUCCESS;
1625
1626 Status = SamrConnect(NULL,
1627 &ServerHandle,
1628 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1629 if (!NT_SUCCESS(Status))
1630 {
1631 TRACE("SamrConnect failed (Status %08lx)\n", Status);
1632 goto done;
1633 }
1634
1635 Status = SamrOpenDomain(ServerHandle,
1636 DOMAIN_LOOKUP,
1637 AccountDomainSid,
1638 &DomainHandle);
1639 if (!NT_SUCCESS(Status))
1640 {
1641 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1642 goto done;
1643 }
1644
1645 for (i = 0; i < Count; i++)
1646 {
1647 /* Ignore names which were already mapped */
1648 if (SidsBuffer[i].Use != SidTypeUnknown)
1649 continue;
1650
1651 /* Ignore isolated account names */
1652 if (DomainNames[i].Length == 0)
1653 continue;
1654
1655 if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &AccountDomainName, TRUE))
1656 continue;
1657
1658 TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1659
1660 Status = SamrLookupNamesInDomain(DomainHandle,
1661 1,
1662 &AccountNames[i],
1663 &RelativeIds,
1664 &Use);
1665 if (NT_SUCCESS(Status))
1666 {
1667 SidsBuffer[i].Use = Use.Element[0];
1668 SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
1669 RelativeIds.Element[0]);
1670 if (SidsBuffer[i].Sid == NULL)
1671 {
1672 Status = STATUS_INSUFFICIENT_RESOURCES;
1673 goto done;
1674 }
1675
1676 SidsBuffer[i].DomainIndex = -1;
1677 SidsBuffer[i].Flags = 0;
1678
1679 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1680 &AccountDomainName,
1681 AccountDomainSid,
1682 &DomainIndex);
1683 if (!NT_SUCCESS(Status))
1684 goto done;
1685
1686 SidsBuffer[i].DomainIndex = DomainIndex;
1687
1688 (*Mapped)++;
1689 }
1690
1691 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1692 SamIFree_SAMPR_ULONG_ARRAY(&Use);
1693 }
1694
1695 done:
1696 if (DomainHandle != NULL)
1697 SamrCloseHandle(&DomainHandle);
1698
1699 if (ServerHandle != NULL)
1700 SamrCloseHandle(&ServerHandle);
1701
1702 return Status;
1703 }
1704
1705
1706 NTSTATUS
1707 LsapLookupNames(DWORD Count,
1708 PRPC_UNICODE_STRING Names,
1709 PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1710 PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
1711 LSAP_LOOKUP_LEVEL LookupLevel,
1712 DWORD *MappedCount,
1713 DWORD LookupOptions,
1714 DWORD ClientRevision)
1715 {
1716 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
1717 PLSAPR_TRANSLATED_SID_EX2 SidsBuffer = NULL;
1718 PRPC_UNICODE_STRING DomainNames = NULL;
1719 PRPC_UNICODE_STRING AccountNames = NULL;
1720 ULONG SidsBufferLength;
1721 ULONG i;
1722 ULONG Mapped = 0;
1723 NTSTATUS Status = STATUS_SUCCESS;
1724
1725 //TRACE("()\n");
1726
1727 TranslatedSids->Entries = 0;
1728 TranslatedSids->Sids = NULL;
1729 *ReferencedDomains = NULL;
1730
1731 SidsBufferLength = Count * sizeof(LSAPR_TRANSLATED_SID_EX2);
1732 SidsBuffer = MIDL_user_allocate(SidsBufferLength);
1733 if (SidsBuffer == NULL)
1734 {
1735 //TRACE("\n");
1736 Status = STATUS_INSUFFICIENT_RESOURCES;
1737 goto done;
1738 }
1739
1740 DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
1741 if (DomainsBuffer == NULL)
1742 {
1743 //TRACE("\n");
1744 Status = STATUS_INSUFFICIENT_RESOURCES;
1745 goto done;
1746 }
1747
1748 DomainsBuffer->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
1749 if (DomainsBuffer->Domains == NULL)
1750 {
1751 //TRACE("\n");
1752 Status = STATUS_INSUFFICIENT_RESOURCES;
1753 goto done;
1754 }
1755 DomainsBuffer->Entries = 0;
1756 DomainsBuffer->MaxEntries = Count;
1757
1758 for (i = 0; i < Count; i++)
1759 {
1760 SidsBuffer[i].Use = SidTypeUnknown;
1761 SidsBuffer[i].Sid = NULL;
1762 SidsBuffer[i].DomainIndex = -1;
1763 SidsBuffer[i].Flags = 0;
1764 }
1765
1766 Status = LsapSplitNames(Count,
1767 Names,
1768 &DomainNames,
1769 &AccountNames);
1770 if (!NT_SUCCESS(Status))
1771 {
1772 TRACE("LsapSplitNames failed! (Status %lx)\n", Status);
1773 goto done;
1774 }
1775
1776
1777 Status = LsapLookupIsolatedNames(Count,
1778 DomainNames,
1779 AccountNames,
1780 DomainsBuffer,
1781 SidsBuffer,
1782 &Mapped);
1783 if (!NT_SUCCESS(Status) &&
1784 Status != STATUS_NONE_MAPPED &&
1785 Status != STATUS_SOME_NOT_MAPPED)
1786 {
1787 TRACE("LsapLookupIsolatedNames failed! (Status %lx)\n", Status);
1788 goto done;
1789 }
1790
1791 if (Mapped == Count)
1792 goto done;
1793
1794
1795 Status = LsapLookupIsolatedBuiltinNames(Count,
1796 DomainNames,
1797 AccountNames,
1798 DomainsBuffer,
1799 SidsBuffer,
1800 &Mapped);
1801 if (!NT_SUCCESS(Status) &&
1802 Status != STATUS_NONE_MAPPED &&
1803 Status != STATUS_SOME_NOT_MAPPED)
1804 {
1805 TRACE("LsapLookupIsolatedBuiltinNames failed! (Status %lx)\n", Status);
1806 goto done;
1807 }
1808
1809 if (Mapped == Count)
1810 goto done;
1811
1812
1813 Status = LsapLookupIsolatedAccountNames(Count,
1814 DomainNames,
1815 AccountNames,
1816 DomainsBuffer,
1817 SidsBuffer,
1818 &Mapped);
1819 if (!NT_SUCCESS(Status) &&
1820 Status != STATUS_NONE_MAPPED &&
1821 Status != STATUS_SOME_NOT_MAPPED)
1822 {
1823 TRACE("LsapLookupIsolatedAccountNames failed! (Status %lx)\n", Status);
1824 goto done;
1825 }
1826
1827 if (Mapped == Count)
1828 goto done;
1829
1830 Status = LsapLookupFullyQualifiedWellKnownNames(Count,
1831 DomainNames,
1832 AccountNames,
1833 DomainsBuffer,
1834 SidsBuffer,
1835 &Mapped);
1836 if (!NT_SUCCESS(Status) &&
1837 Status != STATUS_NONE_MAPPED &&
1838 Status != STATUS_SOME_NOT_MAPPED)
1839 {
1840 TRACE("LsapLookupFullyQualifiedWellKnownNames failed! (Status %lx)\n", Status);
1841 goto done;
1842 }
1843
1844 if (Mapped == Count)
1845 goto done;
1846
1847 Status = LsapLookupBuiltinNames(Count,
1848 DomainNames,
1849 AccountNames,
1850 DomainsBuffer,
1851 SidsBuffer,
1852 &Mapped);
1853 if (!NT_SUCCESS(Status) &&
1854 Status != STATUS_NONE_MAPPED &&
1855 Status != STATUS_SOME_NOT_MAPPED)
1856 {
1857 TRACE("LsapLookupBuiltinNames failed! (Status %lx)\n", Status);
1858 goto done;
1859 }
1860
1861 if (Mapped == Count)
1862 goto done;
1863
1864
1865 Status = LsapLookupAccountNames(Count,
1866 DomainNames,
1867 AccountNames,
1868 DomainsBuffer,
1869 SidsBuffer,
1870 &Mapped);
1871 if (!NT_SUCCESS(Status) &&
1872 Status != STATUS_NONE_MAPPED &&
1873 Status != STATUS_SOME_NOT_MAPPED)
1874 {
1875 TRACE("LsapLookupAccountNames failed! (Status %lx)\n", Status);
1876 goto done;
1877 }
1878
1879 if (Mapped == Count)
1880 goto done;
1881
1882 done:
1883 // TRACE("done: Status %lx\n", Status);
1884
1885 if (DomainNames != NULL)
1886 {
1887 //TRACE("Free DomainNames\n");
1888 for (i = 0; i < Count; i++)
1889 {
1890 if (DomainNames[i].Buffer != NULL)
1891 MIDL_user_free(DomainNames[i].Buffer);
1892 }
1893
1894 MIDL_user_free(DomainNames);
1895 }
1896
1897 if (AccountNames != NULL)
1898 {
1899 //TRACE("Free AccountNames\n");
1900 for (i = 0; i < Count; i++)
1901 {
1902 //TRACE("i: %lu\n", i);
1903 if (AccountNames[i].Buffer != NULL)
1904 {
1905 MIDL_user_free(AccountNames[i].Buffer);
1906 }
1907 }
1908
1909 MIDL_user_free(AccountNames);
1910 }
1911
1912 if (!NT_SUCCESS(Status))
1913 {
1914 //TRACE("Failure!\n");
1915
1916 //TRACE("Free DomainsBuffer\n");
1917 if (DomainsBuffer != NULL)
1918 {
1919 if (DomainsBuffer->Domains != NULL)
1920 MIDL_user_free(DomainsBuffer->Domains);
1921
1922 MIDL_user_free(DomainsBuffer);
1923 }
1924
1925 //TRACE("Free SidsBuffer\n");
1926 if (SidsBuffer != NULL)
1927 MIDL_user_free(SidsBuffer);
1928 }
1929 else
1930 {
1931 //TRACE("Success!\n");
1932
1933 *ReferencedDomains = DomainsBuffer;
1934 TranslatedSids->Entries = Count;
1935 TranslatedSids->Sids = SidsBuffer;
1936 *MappedCount = Mapped;
1937
1938 if (Mapped == 0)
1939 Status = STATUS_NONE_MAPPED;
1940 else if (Mapped < Count)
1941 Status = STATUS_SOME_NOT_MAPPED;
1942 }
1943
1944 // TRACE("done: Status %lx\n", Status);
1945
1946 return Status;
1947 }
1948
1949
1950 static NTSTATUS
1951 LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
1952 PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
1953 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1954 PULONG Mapped)
1955 {
1956 PWELL_KNOWN_SID ptr, ptr2;
1957 LPWSTR SidString = NULL;
1958 ULONG DomainIndex;
1959 ULONG i;
1960 NTSTATUS Status = STATUS_SUCCESS;
1961
1962 for (i = 0; i < SidEnumBuffer->Entries; i++)
1963 {
1964 /* Ignore SIDs which are already mapped */
1965 if (NamesBuffer[i].Use != SidTypeUnknown)
1966 continue;
1967
1968 ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
1969 TRACE("Mapping SID: %S\n", SidString);
1970 LocalFree(SidString);
1971 SidString = NULL;
1972
1973 ptr = LsapLookupWellKnownSid(SidEnumBuffer->SidInfo[i].Sid);
1974 if (ptr != NULL)
1975 {
1976 NamesBuffer[i].Use = ptr->Use;
1977 NamesBuffer[i].Flags = 0;
1978
1979 NamesBuffer[i].Name.Length = ptr->AccountName.Length;
1980 NamesBuffer[i].Name.MaximumLength = ptr->AccountName.MaximumLength;
1981 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->AccountName.MaximumLength);
1982 if (NamesBuffer[i].Name.Buffer == NULL)
1983 {
1984 Status = STATUS_INSUFFICIENT_RESOURCES;
1985 goto done;
1986 }
1987
1988 RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->AccountName.Buffer, ptr->AccountName.MaximumLength);
1989
1990 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
1991 if (ptr2 != NULL)
1992 {
1993 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1994 &ptr2->AccountName,
1995 ptr2->Sid,
1996 &DomainIndex);
1997 if (!NT_SUCCESS(Status))
1998 goto done;
1999
2000 NamesBuffer[i].DomainIndex = DomainIndex;
2001 }
2002
2003 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2004
2005 (*Mapped)++;
2006 }
2007 }
2008
2009 done:
2010 return Status;
2011 }
2012
2013
2014 static NTSTATUS
2015 LsapLookupBuiltinDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2016 PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
2017 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
2018 PULONG Mapped)
2019 {
2020 SAMPR_HANDLE ServerHandle = NULL;
2021 SAMPR_HANDLE DomainHandle = NULL;
2022 SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
2023 SAMPR_ULONG_ARRAY Use = {0, NULL};
2024 LPWSTR SidString = NULL;
2025 ULONG DomainIndex;
2026 ULONG RelativeIds[1];
2027 ULONG i;
2028 NTSTATUS Status = STATUS_SUCCESS;
2029
2030 Status = SamrConnect(NULL,
2031 &ServerHandle,
2032 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
2033 if (!NT_SUCCESS(Status))
2034 {
2035 TRACE("SamrConnect failed (Status %08lx)\n", Status);
2036 goto done;
2037 }
2038
2039 Status = SamrOpenDomain(ServerHandle,
2040 DOMAIN_LOOKUP,
2041 BuiltinDomainSid,
2042 &DomainHandle);
2043 if (!NT_SUCCESS(Status))
2044 {
2045 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
2046 goto done;
2047 }
2048
2049 for (i = 0; i < SidEnumBuffer->Entries; i++)
2050 {
2051 /* Ignore SIDs which are already mapped */
2052 if (NamesBuffer[i].Use != SidTypeUnknown)
2053 continue;
2054
2055 ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
2056 TRACE("Mapping SID: %S\n", SidString);
2057 LocalFree(SidString);
2058 SidString = NULL;
2059
2060 if (RtlEqualSid(BuiltinDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2061 {
2062 TRACE("Found builtin domain!\n");
2063
2064 NamesBuffer[i].Use = SidTypeDomain;
2065 NamesBuffer[i].Flags = 0;
2066
2067 NamesBuffer[i].Name.Length = BuiltinDomainName.Length;
2068 NamesBuffer[i].Name.MaximumLength = BuiltinDomainName.MaximumLength;
2069 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(BuiltinDomainName.MaximumLength);
2070 if (NamesBuffer[i].Name.Buffer == NULL)
2071 {
2072 Status = STATUS_INSUFFICIENT_RESOURCES;
2073 goto done;
2074 }
2075
2076 RtlCopyMemory(NamesBuffer[i].Name.Buffer, BuiltinDomainName.Buffer, BuiltinDomainName.MaximumLength);
2077
2078 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2079 &BuiltinDomainName,
2080 BuiltinDomainSid,
2081 &DomainIndex);
2082 if (!NT_SUCCESS(Status))
2083 goto done;
2084
2085 NamesBuffer[i].DomainIndex = DomainIndex;
2086
2087 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2088
2089 (*Mapped)++;
2090 }
2091 else if (LsapIsPrefixSid(BuiltinDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2092 {
2093 TRACE("Found builtin domain account!\n");
2094
2095 RelativeIds[0] = LsapGetRelativeIdFromSid(SidEnumBuffer->SidInfo[i].Sid);
2096
2097 Status = SamrLookupIdsInDomain(DomainHandle,
2098 1,
2099 RelativeIds,
2100 &Names,
2101 &Use);
2102 if (NT_SUCCESS(Status))
2103 {
2104 NamesBuffer[i].Use = Use.Element[0];
2105 NamesBuffer[i].Flags = 0;
2106
2107 NamesBuffer[i].Name.Length = Names.Element[0].Length;
2108 NamesBuffer[i].Name.MaximumLength = Names.Element[0].MaximumLength;
2109 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(Names.Element[0].MaximumLength);
2110 if (NamesBuffer[i].Name.Buffer == NULL)
2111 {
2112 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2113 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2114
2115 Status = STATUS_INSUFFICIENT_RESOURCES;
2116 goto done;
2117 }
2118
2119 RtlCopyMemory(NamesBuffer[i].Name.Buffer,
2120 Names.Element[0].Buffer,
2121 Names.Element[0].MaximumLength);
2122
2123 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2124 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2125
2126 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2127 &BuiltinDomainName,
2128 BuiltinDomainSid,
2129 &DomainIndex);
2130 if (!NT_SUCCESS(Status))
2131 goto done;
2132
2133 NamesBuffer[i].DomainIndex = DomainIndex;
2134
2135 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2136
2137 (*Mapped)++;
2138 }
2139 }
2140 }
2141
2142 done:
2143 if (DomainHandle != NULL)
2144 SamrCloseHandle(&DomainHandle);
2145
2146 if (ServerHandle != NULL)
2147 SamrCloseHandle(&ServerHandle);
2148
2149 return Status;
2150 }
2151
2152
2153 static NTSTATUS
2154 LsapLookupAccountDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2155 PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
2156 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
2157 PULONG Mapped)
2158 {
2159 SAMPR_HANDLE ServerHandle = NULL;
2160 SAMPR_HANDLE DomainHandle = NULL;
2161 SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
2162 SAMPR_ULONG_ARRAY Use = {0, NULL};
2163 LPWSTR SidString = NULL;
2164 ULONG DomainIndex;
2165 ULONG RelativeIds[1];
2166 ULONG i;
2167 NTSTATUS Status = STATUS_SUCCESS;
2168
2169 Status = SamrConnect(NULL,
2170 &ServerHandle,
2171 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
2172 if (!NT_SUCCESS(Status))
2173 {
2174 TRACE("SamrConnect failed (Status %08lx)\n", Status);
2175 goto done;
2176 }
2177
2178 Status = SamrOpenDomain(ServerHandle,
2179 DOMAIN_LOOKUP,
2180 AccountDomainSid,
2181 &DomainHandle);
2182 if (!NT_SUCCESS(Status))
2183 {
2184 TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
2185 goto done;
2186 }
2187
2188 for (i = 0; i < SidEnumBuffer->Entries; i++)
2189 {
2190 /* Ignore SIDs which are already mapped */
2191 if (NamesBuffer[i].Use != SidTypeUnknown)
2192 continue;
2193
2194 ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
2195 TRACE("Mapping SID: %S\n", SidString);
2196 LocalFree(SidString);
2197 SidString = NULL;
2198
2199 if (RtlEqualSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2200 {
2201 TRACE("Found account domain!\n");
2202
2203 NamesBuffer[i].Use = SidTypeDomain;
2204 NamesBuffer[i].Flags = 0;
2205
2206 NamesBuffer[i].Name.Length = AccountDomainName.Length;
2207 NamesBuffer[i].Name.MaximumLength = AccountDomainName.MaximumLength;
2208 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AccountDomainName.MaximumLength);
2209 if (NamesBuffer[i].Name.Buffer == NULL)
2210 {
2211 Status = STATUS_INSUFFICIENT_RESOURCES;
2212 goto done;
2213 }
2214
2215 RtlCopyMemory(NamesBuffer[i].Name.Buffer, AccountDomainName.Buffer, AccountDomainName.MaximumLength);
2216
2217 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2218 &AccountDomainName,
2219 AccountDomainSid,
2220 &DomainIndex);
2221 if (!NT_SUCCESS(Status))
2222 goto done;
2223
2224 NamesBuffer[i].DomainIndex = DomainIndex;
2225
2226 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2227
2228 (*Mapped)++;
2229 }
2230 else if (LsapIsPrefixSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2231 {
2232 TRACE("Found account domain account!\n");
2233
2234 RelativeIds[0] = LsapGetRelativeIdFromSid(SidEnumBuffer->SidInfo[i].Sid);
2235
2236 Status = SamrLookupIdsInDomain(DomainHandle,
2237 1,
2238 RelativeIds,
2239 &Names,
2240 &Use);
2241 if (NT_SUCCESS(Status))
2242 {
2243 NamesBuffer[i].Use = Use.Element[0];
2244 NamesBuffer[i].Flags = 0;
2245
2246 NamesBuffer[i].Name.Length = Names.Element[0].Length;
2247 NamesBuffer[i].Name.MaximumLength = Names.Element[0].MaximumLength;
2248 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(Names.Element[0].MaximumLength);
2249 if (NamesBuffer[i].Name.Buffer == NULL)
2250 {
2251 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2252 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2253
2254 Status = STATUS_INSUFFICIENT_RESOURCES;
2255 goto done;
2256 }
2257
2258 RtlCopyMemory(NamesBuffer[i].Name.Buffer,
2259 Names.Element[0].Buffer,
2260 Names.Element[0].MaximumLength);
2261
2262 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2263 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2264
2265 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2266 &AccountDomainName,
2267 AccountDomainSid,
2268 &DomainIndex);
2269 if (!NT_SUCCESS(Status))
2270 goto done;
2271
2272 NamesBuffer[i].DomainIndex = DomainIndex;
2273
2274 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2275
2276 (*Mapped)++;
2277 }
2278 }
2279 }
2280
2281 done:
2282 if (DomainHandle != NULL)
2283 SamrCloseHandle(&DomainHandle);
2284
2285 if (ServerHandle != NULL)
2286 SamrCloseHandle(&ServerHandle);
2287
2288 return Status;
2289 }
2290
2291
2292 NTSTATUS
2293 LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2294 PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
2295 PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
2296 LSAP_LOOKUP_LEVEL LookupLevel,
2297 DWORD *MappedCount,
2298 DWORD LookupOptions,
2299 DWORD ClientRevision)
2300 {
2301 PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
2302 PLSAPR_TRANSLATED_NAME_EX NamesBuffer = NULL;
2303 ULONG NamesBufferLength;
2304 ULONG i;
2305 ULONG Mapped = 0;
2306 NTSTATUS Status = STATUS_SUCCESS;
2307
2308 NamesBufferLength = SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME_EX);
2309 NamesBuffer = MIDL_user_allocate(NamesBufferLength);
2310 if (NamesBuffer == NULL)
2311 {
2312 Status = STATUS_INSUFFICIENT_RESOURCES;
2313 goto done;
2314 }
2315
2316 DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
2317 if (DomainsBuffer == NULL)
2318 {
2319 Status = STATUS_INSUFFICIENT_RESOURCES;
2320 goto done;
2321 }
2322
2323 DomainsBuffer->Domains = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSA_TRUST_INFORMATION));
2324 if (DomainsBuffer->Domains == NULL)
2325 {
2326 Status = STATUS_INSUFFICIENT_RESOURCES;
2327 goto done;
2328 }
2329
2330 DomainsBuffer->Entries = 0;
2331 DomainsBuffer->MaxEntries = SidEnumBuffer->Entries;
2332
2333 /* Initialize all name entries */
2334 for (i = 0; i < SidEnumBuffer->Entries; i++)
2335 {
2336 NamesBuffer[i].Use = SidTypeUnknown;
2337 NamesBuffer[i].Name.Length = 0;
2338 NamesBuffer[i].Name.MaximumLength = 0;
2339 NamesBuffer[i].Name.Buffer = NULL;
2340 NamesBuffer[i].DomainIndex = -1;
2341 NamesBuffer[i].Flags = 0;
2342 }
2343
2344 /* Look-up well-known SIDs */
2345 Status = LsapLookupWellKnownSids(SidEnumBuffer,
2346 NamesBuffer,
2347 DomainsBuffer,
2348 &Mapped);
2349 if (!NT_SUCCESS(Status) &&
2350 Status != STATUS_NONE_MAPPED &&
2351 Status != STATUS_SOME_NOT_MAPPED)
2352 goto done;
2353
2354 if (Mapped == SidEnumBuffer->Entries)
2355 goto done;
2356
2357 /* Look-up builtin domain SIDs */
2358 Status = LsapLookupBuiltinDomainSids(SidEnumBuffer,
2359 NamesBuffer,
2360 DomainsBuffer,
2361 &Mapped);
2362 if (!NT_SUCCESS(Status) &&
2363 Status != STATUS_NONE_MAPPED &&
2364 Status != STATUS_SOME_NOT_MAPPED)
2365 goto done;
2366
2367 if (Mapped == SidEnumBuffer->Entries)
2368 goto done;
2369
2370 /* Look-up account domain SIDs */
2371 Status = LsapLookupAccountDomainSids(SidEnumBuffer,
2372 NamesBuffer,
2373 DomainsBuffer,
2374 &Mapped);
2375 if (!NT_SUCCESS(Status) &&
2376 Status != STATUS_NONE_MAPPED &&
2377 Status != STATUS_SOME_NOT_MAPPED)
2378 goto done;
2379
2380 if (Mapped == SidEnumBuffer->Entries)
2381 goto done;
2382
2383 done:
2384 TRACE("done Status: %lx Mapped: %lu\n", Status, Mapped);
2385
2386 if (!NT_SUCCESS(Status))
2387 {
2388 if (DomainsBuffer != NULL)
2389 {
2390 if (DomainsBuffer->Domains != NULL)
2391 MIDL_user_free(DomainsBuffer->Domains);
2392
2393 MIDL_user_free(DomainsBuffer);
2394 }
2395
2396 if (NamesBuffer != NULL)
2397 MIDL_user_free(NamesBuffer);
2398 }
2399 else
2400 {
2401 *ReferencedDomains = DomainsBuffer;
2402 TranslatedNames->Entries = SidEnumBuffer->Entries;
2403 TranslatedNames->Names = NamesBuffer;
2404 *MappedCount = Mapped;
2405
2406 if (Mapped == 0)
2407 Status = STATUS_NONE_MAPPED;
2408 else if (Mapped < SidEnumBuffer->Entries)
2409 Status = STATUS_SOME_NOT_MAPPED;
2410 }
2411
2412 return Status;
2413 }
2414
2415 /* EOF */