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