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