xref: /reactos/dll/win32/lsasrv/lookup.c (revision f7cab5a1)
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 NTSTATUS
944 LsapAddAuthorityToDomainsList(
945     PLSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains,
946     PSID Sid,
947     PULONG Index)
948 {
949     SID AuthoritySid;
950     ULONG i;
951 
952     RtlInitializeSid(&AuthoritySid,
953                      RtlIdentifierAuthoritySid(Sid),
954                      0);
955 
956     i = 0;
957     while (i < ReferencedDomains->Entries &&
958            ReferencedDomains->Domains[i].Sid != NULL)
959     {
960         if (RtlEqualSid(&AuthoritySid, ReferencedDomains->Domains[i].Sid))
961         {
962             *Index = i;
963             return STATUS_SUCCESS;
964         }
965 
966         i++;
967     }
968 
969     ReferencedDomains->Domains[i].Sid = MIDL_user_allocate(RtlLengthSid(&AuthoritySid));
970     if (ReferencedDomains->Domains[i].Sid == NULL)
971         return STATUS_INSUFFICIENT_RESOURCES;
972 
973     RtlCopySid(RtlLengthSid(&AuthoritySid), ReferencedDomains->Domains[i].Sid, &AuthoritySid);
974 
975     ReferencedDomains->Domains[i].Name.Length = 0;
976     ReferencedDomains->Domains[i].Name.MaximumLength = sizeof(WCHAR);
977     ReferencedDomains->Domains[i].Name.Buffer = MIDL_user_allocate(sizeof(WCHAR));
978     if (ReferencedDomains->Domains[i].Name.Buffer == NULL)
979     {
980         MIDL_user_free(ReferencedDomains->Domains[i].Sid);
981         ReferencedDomains->Domains[i].Sid = NULL;
982         return STATUS_INSUFFICIENT_RESOURCES;
983     }
984 
985     ReferencedDomains->Domains[i].Name.Buffer[0] = UNICODE_NULL;
986 
987     ReferencedDomains->Entries++;
988     *Index = i;
989 
990     return STATUS_SUCCESS;
991 }
992 
993 
994 static BOOLEAN
995 LsapIsPrefixSid(IN PSID PrefixSid,
996                 IN PSID Sid)
997 {
998     PISID Sid1 = PrefixSid, Sid2 = Sid;
999     ULONG i;
1000 
1001     if (Sid1->Revision != Sid2->Revision)
1002         return FALSE;
1003 
1004     if ((Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0]) ||
1005         (Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1]) ||
1006         (Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2]) ||
1007         (Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3]) ||
1008         (Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4]) ||
1009         (Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5]))
1010         return FALSE;
1011 
1012     if (Sid1->SubAuthorityCount >= Sid2->SubAuthorityCount)
1013         return FALSE;
1014 
1015     if (Sid1->SubAuthorityCount == 0)
1016         return TRUE;
1017 
1018     for (i = 0; i < Sid1->SubAuthorityCount; i++)
1019     {
1020         if (Sid1->SubAuthority[i] != Sid2->SubAuthority[i])
1021             return FALSE;
1022     }
1023 
1024     return TRUE;
1025 }
1026 
1027 
1028 ULONG
1029 LsapGetRelativeIdFromSid(PSID Sid_)
1030 {
1031     PISID Sid = Sid_;
1032 
1033     if (Sid->SubAuthorityCount != 0)
1034         return Sid->SubAuthority[Sid->SubAuthorityCount - 1];
1035 
1036     return 0;
1037 }
1038 
1039 
1040 static PSID
1041 CreateSidFromSidAndRid(PSID SrcSid,
1042                        ULONG RelativeId)
1043 {
1044     UCHAR RidCount;
1045     PSID DstSid;
1046     ULONG i;
1047     ULONG DstSidSize;
1048     PULONG p, q;
1049 
1050     RidCount = *RtlSubAuthorityCountSid(SrcSid);
1051     if (RidCount >= 8)
1052         return NULL;
1053 
1054     DstSidSize = RtlLengthRequiredSid(RidCount + 1);
1055 
1056     DstSid = MIDL_user_allocate(DstSidSize);
1057     if (DstSid == NULL)
1058         return NULL;
1059 
1060     RtlInitializeSid(DstSid,
1061                      RtlIdentifierAuthoritySid(SrcSid),
1062                      RidCount + 1);
1063 
1064     for (i = 0; i < (ULONG)RidCount; i++)
1065     {
1066         p = RtlSubAuthoritySid(SrcSid, i);
1067         q = RtlSubAuthoritySid(DstSid, i);
1068         *q = *p;
1069     }
1070 
1071     q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
1072     *q = RelativeId;
1073 
1074     return DstSid;
1075 }
1076 
1077 
1078 static PSID
1079 CreateDomainSidFromAccountSid(PSID AccountSid)
1080 {
1081     UCHAR RidCount;
1082     PSID DomainSid;
1083     ULONG i;
1084     ULONG DstSidSize;
1085     PULONG p, q;
1086 
1087     RidCount = *RtlSubAuthorityCountSid(AccountSid);
1088     if (RidCount > 0)
1089         RidCount--;
1090 
1091     DstSidSize = RtlLengthRequiredSid(RidCount);
1092 
1093     DomainSid = MIDL_user_allocate(DstSidSize);
1094     if (DomainSid == NULL)
1095         return NULL;
1096 
1097     RtlInitializeSid(DomainSid,
1098                      RtlIdentifierAuthoritySid(AccountSid),
1099                      RidCount);
1100 
1101     for (i = 0; i < (ULONG)RidCount; i++)
1102     {
1103         p = RtlSubAuthoritySid(AccountSid, i);
1104         q = RtlSubAuthoritySid(DomainSid, i);
1105         *q = *p;
1106     }
1107 
1108     return DomainSid;
1109 }
1110 
1111 
1112 static PSID
1113 LsapCopySid(PSID SrcSid)
1114 {
1115     UCHAR RidCount;
1116     PSID DstSid;
1117     ULONG i;
1118     ULONG DstSidSize;
1119     PULONG p, q;
1120 
1121     RidCount = *RtlSubAuthorityCountSid(SrcSid);
1122     DstSidSize = RtlLengthRequiredSid(RidCount);
1123 
1124     DstSid = MIDL_user_allocate(DstSidSize);
1125     if (DstSid == NULL)
1126         return NULL;
1127 
1128     RtlInitializeSid(DstSid,
1129                      RtlIdentifierAuthoritySid(SrcSid),
1130                      RidCount);
1131 
1132     for (i = 0; i < (ULONG)RidCount; i++)
1133     {
1134         p = RtlSubAuthoritySid(SrcSid, i);
1135         q = RtlSubAuthoritySid(DstSid, i);
1136         *q = *p;
1137     }
1138 
1139     return DstSid;
1140 }
1141 
1142 
1143 static
1144 NTSTATUS
1145 LsapLookupIsolatedNames(DWORD Count,
1146                         PRPC_UNICODE_STRING DomainNames,
1147                         PRPC_UNICODE_STRING AccountNames,
1148                         PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1149                         PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1150                         PULONG Mapped)
1151 {
1152     UNICODE_STRING EmptyDomainName = RTL_CONSTANT_STRING(L"");
1153     PWELL_KNOWN_SID ptr, ptr2;
1154     PSID DomainSid;
1155     ULONG DomainIndex;
1156     ULONG i;
1157     NTSTATUS Status = STATUS_SUCCESS;
1158 
1159     for (i = 0; i < Count; i++)
1160     {
1161         /* Ignore names which were already mapped */
1162         if (SidsBuffer[i].Use != SidTypeUnknown)
1163             continue;
1164 
1165         /* Ignore fully qualified account names */
1166         if (DomainNames[i].Length != 0)
1167             continue;
1168 
1169         TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1170 
1171         /* Look-up all well-known names */
1172         ptr = LsapLookupIsolatedWellKnownName((PUNICODE_STRING)&AccountNames[i]);
1173         if (ptr != NULL)
1174         {
1175             SidsBuffer[i].Use = ptr->Use;
1176             SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
1177             if (SidsBuffer[i].Sid == NULL)
1178             {
1179                 Status = STATUS_INSUFFICIENT_RESOURCES;
1180                 goto done;
1181             }
1182 
1183             SidsBuffer[i].DomainIndex = -1;
1184             SidsBuffer[i].Flags = 0;
1185 
1186             if (ptr->Use == SidTypeDomain)
1187             {
1188                 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1189                                                     &ptr->AccountName,
1190                                                     ptr->Sid,
1191                                                     &DomainIndex);
1192                 if (!NT_SUCCESS(Status))
1193                     goto done;
1194 
1195                 SidsBuffer[i].DomainIndex = DomainIndex;
1196             }
1197             else
1198             {
1199                 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
1200                 if (ptr2 != NULL)
1201                 {
1202                     Status = LsapAddDomainToDomainsList(DomainsBuffer,
1203                                                         &ptr2->AccountName,
1204                                                         ptr2->Sid,
1205                                                         &DomainIndex);
1206                     if (!NT_SUCCESS(Status))
1207                         goto done;
1208 
1209                     SidsBuffer[i].DomainIndex = DomainIndex;
1210                 }
1211                 else
1212                 {
1213                     DomainSid = CreateDomainSidFromAccountSid(ptr->Sid);
1214                     if (DomainSid == NULL)
1215                     {
1216                         Status = STATUS_INSUFFICIENT_RESOURCES;
1217                         goto done;
1218                     }
1219 
1220                     Status = LsapAddDomainToDomainsList(DomainsBuffer,
1221                                                         &EmptyDomainName,
1222                                                         DomainSid,
1223                                                         &DomainIndex);
1224 
1225                     if (DomainSid != NULL)
1226                     {
1227                         MIDL_user_free(DomainSid);
1228                         DomainSid = NULL;
1229                     }
1230 
1231                     if (!NT_SUCCESS(Status))
1232                         goto done;
1233 
1234                     SidsBuffer[i].DomainIndex = DomainIndex;
1235                 }
1236             }
1237 
1238             (*Mapped)++;
1239             continue;
1240         }
1241 
1242         /* Look-up the built-in domain */
1243         if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &BuiltinDomainName, TRUE))
1244         {
1245             SidsBuffer[i].Use = SidTypeDomain;
1246             SidsBuffer[i].Sid = LsapCopySid(BuiltinDomainSid);
1247             if (SidsBuffer[i].Sid == NULL)
1248             {
1249                 Status = STATUS_INSUFFICIENT_RESOURCES;
1250                 goto done;
1251             }
1252 
1253             SidsBuffer[i].DomainIndex = -1;
1254             SidsBuffer[i].Flags = 0;
1255 
1256             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1257                                                 &BuiltinDomainName,
1258                                                 BuiltinDomainSid,
1259                                                 &DomainIndex);
1260             if (!NT_SUCCESS(Status))
1261                 goto done;
1262 
1263             SidsBuffer[i].DomainIndex = DomainIndex;
1264 
1265             (*Mapped)++;
1266             continue;
1267         }
1268 
1269         /* Look-up the account domain */
1270         if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &AccountDomainName, TRUE))
1271         {
1272             SidsBuffer[i].Use = SidTypeDomain;
1273             SidsBuffer[i].Sid = LsapCopySid(AccountDomainSid);
1274             if (SidsBuffer[i].Sid == NULL)
1275             {
1276                 Status = STATUS_INSUFFICIENT_RESOURCES;
1277                 goto done;
1278             }
1279             SidsBuffer[i].DomainIndex = -1;
1280             SidsBuffer[i].Flags = 0;
1281 
1282             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1283                                                 &AccountDomainName,
1284                                                 AccountDomainSid,
1285                                                 &DomainIndex);
1286             if (!NT_SUCCESS(Status))
1287                 goto done;
1288 
1289             SidsBuffer[i].DomainIndex = DomainIndex;
1290 
1291             (*Mapped)++;
1292             continue;
1293         }
1294 
1295         /* FIXME: Look-up the primary domain */
1296 
1297         /* FIXME: Look-up the trusted domains */
1298 
1299     }
1300 
1301 done:
1302 
1303     return Status;
1304 }
1305 
1306 
1307 static
1308 NTSTATUS
1309 LsapLookupIsolatedBuiltinNames(DWORD Count,
1310                                PRPC_UNICODE_STRING DomainNames,
1311                                PRPC_UNICODE_STRING AccountNames,
1312                                PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1313                                PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1314                                PULONG Mapped)
1315 {
1316     SAMPR_HANDLE ServerHandle = NULL;
1317     SAMPR_HANDLE DomainHandle = NULL;
1318     SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1319     SAMPR_ULONG_ARRAY Use = {0, NULL};
1320     ULONG DomainIndex;
1321     ULONG i;
1322     NTSTATUS Status = STATUS_SUCCESS;
1323 
1324     Status = SamrConnect(NULL,
1325                          &ServerHandle,
1326                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1327     if (!NT_SUCCESS(Status))
1328     {
1329         TRACE("SamrConnect failed (Status %08lx)\n", Status);
1330         goto done;
1331     }
1332 
1333     Status = SamrOpenDomain(ServerHandle,
1334                             DOMAIN_LOOKUP,
1335                             BuiltinDomainSid,
1336                             &DomainHandle);
1337     if (!NT_SUCCESS(Status))
1338     {
1339         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1340         goto done;
1341     }
1342 
1343     for (i = 0; i < Count; i++)
1344     {
1345         /* Ignore names which were already mapped */
1346         if (SidsBuffer[i].Use != SidTypeUnknown)
1347             continue;
1348 
1349         /* Ignore fully qualified account names */
1350         if (DomainNames[i].Length != 0)
1351             continue;
1352 
1353         TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1354 
1355         Status = SamrLookupNamesInDomain(DomainHandle,
1356                                          1,
1357                                          &AccountNames[i],
1358                                          &RelativeIds,
1359                                          &Use);
1360         if (NT_SUCCESS(Status))
1361         {
1362             TRACE("Found relative ID: %lu\n", RelativeIds.Element[0]);
1363 
1364             SidsBuffer[i].Use = Use.Element[0];
1365             SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
1366                                                        RelativeIds.Element[0]);
1367             if (SidsBuffer[i].Sid == NULL)
1368             {
1369                 Status = STATUS_INSUFFICIENT_RESOURCES;
1370                 goto done;
1371             }
1372 
1373             SidsBuffer[i].DomainIndex = -1;
1374             SidsBuffer[i].Flags = 0;
1375 
1376             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1377                                                 &BuiltinDomainName,
1378                                                 BuiltinDomainSid,
1379                                                 &DomainIndex);
1380             if (!NT_SUCCESS(Status))
1381                 goto done;
1382 
1383             SidsBuffer[i].DomainIndex = DomainIndex;
1384 
1385             (*Mapped)++;
1386         }
1387 
1388         SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1389         SamIFree_SAMPR_ULONG_ARRAY(&Use);
1390     }
1391 
1392 done:
1393     if (DomainHandle != NULL)
1394         SamrCloseHandle(&DomainHandle);
1395 
1396     if (ServerHandle != NULL)
1397         SamrCloseHandle(&ServerHandle);
1398 
1399     return Status;
1400 }
1401 
1402 
1403 static
1404 NTSTATUS
1405 LsapLookupIsolatedAccountNames(DWORD Count,
1406                                PRPC_UNICODE_STRING DomainNames,
1407                                PRPC_UNICODE_STRING AccountNames,
1408                                PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1409                                PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1410                                PULONG Mapped)
1411 {
1412     SAMPR_HANDLE ServerHandle = NULL;
1413     SAMPR_HANDLE DomainHandle = NULL;
1414     SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1415     SAMPR_ULONG_ARRAY Use = {0, NULL};
1416     ULONG DomainIndex;
1417     ULONG i;
1418     NTSTATUS Status = STATUS_SUCCESS;
1419 
1420     TRACE("()\n");
1421 
1422     Status = SamrConnect(NULL,
1423                          &ServerHandle,
1424                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1425     if (!NT_SUCCESS(Status))
1426     {
1427         TRACE("SamrConnect failed (Status %08lx)\n", Status);
1428         goto done;
1429     }
1430 
1431     Status = SamrOpenDomain(ServerHandle,
1432                             DOMAIN_LOOKUP,
1433                             AccountDomainSid,
1434                             &DomainHandle);
1435     if (!NT_SUCCESS(Status))
1436     {
1437         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1438         goto done;
1439     }
1440 
1441     for (i = 0; i < Count; i++)
1442     {
1443         /* Ignore names which were already mapped */
1444         if (SidsBuffer[i].Use != SidTypeUnknown)
1445             continue;
1446 
1447         /* Ignore fully qualified account names */
1448         if (DomainNames[i].Length != 0)
1449             continue;
1450 
1451         TRACE("Mapping name: %wZ\n", &AccountNames[i]);
1452 
1453         Status = SamrLookupNamesInDomain(DomainHandle,
1454                                          1,
1455                                          &AccountNames[i],
1456                                          &RelativeIds,
1457                                          &Use);
1458         if (NT_SUCCESS(Status))
1459         {
1460             TRACE("Found relative ID: %lu\n", RelativeIds.Element[0]);
1461 
1462             SidsBuffer[i].Use = Use.Element[0];
1463             SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
1464                                                        RelativeIds.Element[0]);
1465             if (SidsBuffer[i].Sid == NULL)
1466             {
1467                 Status = STATUS_INSUFFICIENT_RESOURCES;
1468                 goto done;
1469             }
1470 
1471             SidsBuffer[i].DomainIndex = -1;
1472             SidsBuffer[i].Flags = 0;
1473 
1474             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1475                                                 &AccountDomainName,
1476                                                 AccountDomainSid,
1477                                                 &DomainIndex);
1478             if (!NT_SUCCESS(Status))
1479                 goto done;
1480 
1481             SidsBuffer[i].DomainIndex = DomainIndex;
1482 
1483             (*Mapped)++;
1484         }
1485 
1486         SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1487         SamIFree_SAMPR_ULONG_ARRAY(&Use);
1488     }
1489 
1490 done:
1491     if (DomainHandle != NULL)
1492         SamrCloseHandle(&DomainHandle);
1493 
1494     if (ServerHandle != NULL)
1495         SamrCloseHandle(&ServerHandle);
1496 
1497     return Status;
1498 }
1499 
1500 
1501 static
1502 NTSTATUS
1503 LsapLookupFullyQualifiedWellKnownNames(DWORD Count,
1504                                        PRPC_UNICODE_STRING DomainNames,
1505                                        PRPC_UNICODE_STRING AccountNames,
1506                                        PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1507                                        PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1508                                        PULONG Mapped)
1509 {
1510     UNICODE_STRING EmptyDomainName = RTL_CONSTANT_STRING(L"");
1511     PWELL_KNOWN_SID ptr, ptr2;
1512     PSID DomainSid;
1513     ULONG DomainIndex;
1514     ULONG i;
1515     NTSTATUS Status = STATUS_SUCCESS;
1516 
1517     for (i = 0; i < Count; i++)
1518     {
1519         /* Ignore names which were already mapped */
1520         if (SidsBuffer[i].Use != SidTypeUnknown)
1521             continue;
1522 
1523         /* Ignore isolated account names */
1524         if (DomainNames[i].Length == 0)
1525             continue;
1526 
1527         TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1528 
1529         /* Look-up all well-known names */
1530         ptr = LsapLookupFullyQualifiedWellKnownName((PUNICODE_STRING)&AccountNames[i],
1531                                                     (PUNICODE_STRING)&DomainNames[i]);
1532         if (ptr != NULL)
1533         {
1534             TRACE("Found it! (%wZ\\%wZ)\n", &ptr->DomainName, &ptr->AccountName);
1535 
1536             SidsBuffer[i].Use = ptr->Use;
1537             SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
1538             if (SidsBuffer[i].Sid == NULL)
1539             {
1540                 Status = STATUS_INSUFFICIENT_RESOURCES;
1541                 goto done;
1542             }
1543 
1544             SidsBuffer[i].DomainIndex = -1;
1545             SidsBuffer[i].Flags = 0;
1546 
1547             if (ptr->Use == SidTypeDomain)
1548             {
1549                 Status = LsapAddDomainToDomainsList(DomainsBuffer,
1550                                                     &ptr->AccountName,
1551                                                     ptr->Sid,
1552                                                     &DomainIndex);
1553                 if (!NT_SUCCESS(Status))
1554                     goto done;
1555 
1556                 SidsBuffer[i].DomainIndex = DomainIndex;
1557             }
1558             else
1559             {
1560                 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
1561                 if (ptr2 != NULL)
1562                 {
1563                     Status = LsapAddDomainToDomainsList(DomainsBuffer,
1564                                                         &ptr2->AccountName,
1565                                                         ptr2->Sid,
1566                                                         &DomainIndex);
1567                     if (!NT_SUCCESS(Status))
1568                         goto done;
1569 
1570                     SidsBuffer[i].DomainIndex = DomainIndex;
1571                 }
1572                 else
1573                 {
1574                     DomainSid = CreateDomainSidFromAccountSid(ptr->Sid);
1575                     if (DomainSid == NULL)
1576                     {
1577                         Status = STATUS_INSUFFICIENT_RESOURCES;
1578                         goto done;
1579                     }
1580 
1581                     Status = LsapAddDomainToDomainsList(DomainsBuffer,
1582                                                         &EmptyDomainName,
1583                                                         DomainSid,
1584                                                         &DomainIndex);
1585 
1586                     if (DomainSid != NULL)
1587                     {
1588                         MIDL_user_free(DomainSid);
1589                         DomainSid = NULL;
1590                     }
1591 
1592                     if (!NT_SUCCESS(Status))
1593                         goto done;
1594 
1595                     SidsBuffer[i].DomainIndex = DomainIndex;
1596                 }
1597             }
1598 
1599             (*Mapped)++;
1600             continue;
1601         }
1602     }
1603 
1604 done:
1605     return Status;
1606 }
1607 
1608 
1609 static
1610 NTSTATUS
1611 LsapLookupBuiltinNames(DWORD Count,
1612                        PRPC_UNICODE_STRING DomainNames,
1613                        PRPC_UNICODE_STRING AccountNames,
1614                        PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1615                        PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1616                        PULONG Mapped)
1617 {
1618     SAMPR_HANDLE ServerHandle = NULL;
1619     SAMPR_HANDLE DomainHandle = NULL;
1620     SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1621     SAMPR_ULONG_ARRAY Use = {0, NULL};
1622     ULONG DomainIndex;
1623     ULONG i;
1624     NTSTATUS Status = STATUS_SUCCESS;
1625 
1626     Status = SamrConnect(NULL,
1627                          &ServerHandle,
1628                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1629     if (!NT_SUCCESS(Status))
1630     {
1631         TRACE("SamrConnect failed (Status %08lx)\n", Status);
1632         goto done;
1633     }
1634 
1635     Status = SamrOpenDomain(ServerHandle,
1636                             DOMAIN_LOOKUP,
1637                             BuiltinDomainSid,
1638                             &DomainHandle);
1639     if (!NT_SUCCESS(Status))
1640     {
1641         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1642         goto done;
1643     }
1644 
1645     for (i = 0; i < Count; i++)
1646     {
1647         /* Ignore names which were already mapped */
1648         if (SidsBuffer[i].Use != SidTypeUnknown)
1649             continue;
1650 
1651         /* Ignore isolated account names */
1652         if (DomainNames[i].Length == 0)
1653             continue;
1654 
1655         if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &BuiltinDomainName, TRUE))
1656             continue;
1657 
1658         TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1659 
1660         Status = SamrLookupNamesInDomain(DomainHandle,
1661                                          1,
1662                                          &AccountNames[i],
1663                                          &RelativeIds,
1664                                          &Use);
1665         if (NT_SUCCESS(Status))
1666         {
1667             SidsBuffer[i].Use = Use.Element[0];
1668             SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
1669                                                        RelativeIds.Element[0]);
1670             if (SidsBuffer[i].Sid == NULL)
1671             {
1672                 Status = STATUS_INSUFFICIENT_RESOURCES;
1673                 goto done;
1674             }
1675 
1676             SidsBuffer[i].DomainIndex = -1;
1677             SidsBuffer[i].Flags = 0;
1678 
1679             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1680                                                 &BuiltinDomainName,
1681                                                 BuiltinDomainSid,
1682                                                 &DomainIndex);
1683             if (!NT_SUCCESS(Status))
1684                 goto done;
1685 
1686             SidsBuffer[i].DomainIndex = DomainIndex;
1687 
1688             (*Mapped)++;
1689         }
1690 
1691         SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1692         SamIFree_SAMPR_ULONG_ARRAY(&Use);
1693     }
1694 
1695 done:
1696     if (DomainHandle != NULL)
1697         SamrCloseHandle(&DomainHandle);
1698 
1699     if (ServerHandle != NULL)
1700         SamrCloseHandle(&ServerHandle);
1701 
1702     return Status;
1703 }
1704 
1705 
1706 static
1707 NTSTATUS
1708 LsapLookupAccountNames(DWORD Count,
1709                        PRPC_UNICODE_STRING DomainNames,
1710                        PRPC_UNICODE_STRING AccountNames,
1711                        PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
1712                        PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
1713                        PULONG Mapped)
1714 {
1715     SAMPR_HANDLE ServerHandle = NULL;
1716     SAMPR_HANDLE DomainHandle = NULL;
1717     SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
1718     SAMPR_ULONG_ARRAY Use = {0, NULL};
1719     ULONG DomainIndex;
1720     ULONG i;
1721     NTSTATUS Status = STATUS_SUCCESS;
1722 
1723     Status = SamrConnect(NULL,
1724                          &ServerHandle,
1725                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
1726     if (!NT_SUCCESS(Status))
1727     {
1728         TRACE("SamrConnect failed (Status %08lx)\n", Status);
1729         goto done;
1730     }
1731 
1732     Status = SamrOpenDomain(ServerHandle,
1733                             DOMAIN_LOOKUP,
1734                             AccountDomainSid,
1735                             &DomainHandle);
1736     if (!NT_SUCCESS(Status))
1737     {
1738         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
1739         goto done;
1740     }
1741 
1742     for (i = 0; i < Count; i++)
1743     {
1744         /* Ignore names which were already mapped */
1745         if (SidsBuffer[i].Use != SidTypeUnknown)
1746             continue;
1747 
1748         /* Ignore isolated account names */
1749         if (DomainNames[i].Length == 0)
1750             continue;
1751 
1752         if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &AccountDomainName, TRUE))
1753             continue;
1754 
1755         TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
1756 
1757         Status = SamrLookupNamesInDomain(DomainHandle,
1758                                          1,
1759                                          &AccountNames[i],
1760                                          &RelativeIds,
1761                                          &Use);
1762         if (NT_SUCCESS(Status))
1763         {
1764             SidsBuffer[i].Use = Use.Element[0];
1765             SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
1766                                                        RelativeIds.Element[0]);
1767             if (SidsBuffer[i].Sid == NULL)
1768             {
1769                 Status = STATUS_INSUFFICIENT_RESOURCES;
1770                 goto done;
1771             }
1772 
1773             SidsBuffer[i].DomainIndex = -1;
1774             SidsBuffer[i].Flags = 0;
1775 
1776             Status = LsapAddDomainToDomainsList(DomainsBuffer,
1777                                                 &AccountDomainName,
1778                                                 AccountDomainSid,
1779                                                 &DomainIndex);
1780             if (!NT_SUCCESS(Status))
1781                 goto done;
1782 
1783             SidsBuffer[i].DomainIndex = DomainIndex;
1784 
1785             (*Mapped)++;
1786         }
1787 
1788         SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1789         SamIFree_SAMPR_ULONG_ARRAY(&Use);
1790     }
1791 
1792 done:
1793     if (DomainHandle != NULL)
1794         SamrCloseHandle(&DomainHandle);
1795 
1796     if (ServerHandle != NULL)
1797         SamrCloseHandle(&ServerHandle);
1798 
1799     return Status;
1800 }
1801 
1802 
1803 NTSTATUS
1804 LsapLookupNames(DWORD Count,
1805                 PRPC_UNICODE_STRING Names,
1806                 PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1807                 PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
1808                 LSAP_LOOKUP_LEVEL LookupLevel,
1809                 DWORD *MappedCount,
1810                 DWORD LookupOptions,
1811                 DWORD ClientRevision)
1812 {
1813     PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
1814     PLSAPR_TRANSLATED_SID_EX2 SidsBuffer = NULL;
1815     PRPC_UNICODE_STRING DomainNames = NULL;
1816     PRPC_UNICODE_STRING AccountNames = NULL;
1817     ULONG SidsBufferLength;
1818     ULONG i;
1819     ULONG Mapped = 0;
1820     NTSTATUS Status = STATUS_SUCCESS;
1821 
1822 //TRACE("()\n");
1823 
1824     TranslatedSids->Entries = 0;
1825     TranslatedSids->Sids = NULL;
1826     *ReferencedDomains = NULL;
1827 
1828     SidsBufferLength = Count * sizeof(LSAPR_TRANSLATED_SID_EX2);
1829     SidsBuffer = MIDL_user_allocate(SidsBufferLength);
1830     if (SidsBuffer == NULL)
1831     {
1832 //TRACE("\n");
1833         Status = STATUS_INSUFFICIENT_RESOURCES;
1834         goto done;
1835     }
1836 
1837     DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
1838     if (DomainsBuffer == NULL)
1839     {
1840 //TRACE("\n");
1841         Status = STATUS_INSUFFICIENT_RESOURCES;
1842         goto done;
1843     }
1844 
1845     DomainsBuffer->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
1846     if (DomainsBuffer->Domains == NULL)
1847     {
1848 //TRACE("\n");
1849         Status = STATUS_INSUFFICIENT_RESOURCES;
1850         goto done;
1851     }
1852     DomainsBuffer->Entries = 0;
1853     DomainsBuffer->MaxEntries = Count;
1854 
1855     for (i = 0; i < Count; i++)
1856     {
1857         SidsBuffer[i].Use = SidTypeUnknown;
1858         SidsBuffer[i].Sid = NULL;
1859         SidsBuffer[i].DomainIndex = -1;
1860         SidsBuffer[i].Flags = 0;
1861     }
1862 
1863     Status = LsapSplitNames(Count,
1864                             Names,
1865                             &DomainNames,
1866                             &AccountNames);
1867     if (!NT_SUCCESS(Status))
1868     {
1869         TRACE("LsapSplitNames failed! (Status %lx)\n", Status);
1870         goto done;
1871     }
1872 
1873 
1874     Status = LsapLookupIsolatedNames(Count,
1875                                      DomainNames,
1876                                      AccountNames,
1877                                      DomainsBuffer,
1878                                      SidsBuffer,
1879                                      &Mapped);
1880     if (!NT_SUCCESS(Status) &&
1881         Status != STATUS_NONE_MAPPED &&
1882         Status != STATUS_SOME_NOT_MAPPED)
1883     {
1884         TRACE("LsapLookupIsolatedNames failed! (Status %lx)\n", Status);
1885         goto done;
1886     }
1887 
1888     if (Mapped == Count)
1889         goto done;
1890 
1891 
1892     Status = LsapLookupIsolatedBuiltinNames(Count,
1893                                             DomainNames,
1894                                             AccountNames,
1895                                             DomainsBuffer,
1896                                             SidsBuffer,
1897                                             &Mapped);
1898     if (!NT_SUCCESS(Status) &&
1899         Status != STATUS_NONE_MAPPED &&
1900         Status != STATUS_SOME_NOT_MAPPED)
1901     {
1902         TRACE("LsapLookupIsolatedBuiltinNames failed! (Status %lx)\n", Status);
1903         goto done;
1904     }
1905 
1906     if (Mapped == Count)
1907         goto done;
1908 
1909 
1910     Status = LsapLookupIsolatedAccountNames(Count,
1911                                             DomainNames,
1912                                             AccountNames,
1913                                             DomainsBuffer,
1914                                             SidsBuffer,
1915                                             &Mapped);
1916     if (!NT_SUCCESS(Status) &&
1917         Status != STATUS_NONE_MAPPED &&
1918         Status != STATUS_SOME_NOT_MAPPED)
1919     {
1920         TRACE("LsapLookupIsolatedAccountNames failed! (Status %lx)\n", Status);
1921         goto done;
1922     }
1923 
1924     if (Mapped == Count)
1925         goto done;
1926 
1927     Status = LsapLookupFullyQualifiedWellKnownNames(Count,
1928                                                     DomainNames,
1929                                                     AccountNames,
1930                                                     DomainsBuffer,
1931                                                     SidsBuffer,
1932                                                     &Mapped);
1933     if (!NT_SUCCESS(Status) &&
1934         Status != STATUS_NONE_MAPPED &&
1935         Status != STATUS_SOME_NOT_MAPPED)
1936     {
1937         TRACE("LsapLookupFullyQualifiedWellKnownNames failed! (Status %lx)\n", Status);
1938         goto done;
1939     }
1940 
1941     if (Mapped == Count)
1942         goto done;
1943 
1944     Status = LsapLookupBuiltinNames(Count,
1945                                     DomainNames,
1946                                     AccountNames,
1947                                     DomainsBuffer,
1948                                     SidsBuffer,
1949                                     &Mapped);
1950     if (!NT_SUCCESS(Status) &&
1951         Status != STATUS_NONE_MAPPED &&
1952         Status != STATUS_SOME_NOT_MAPPED)
1953     {
1954         TRACE("LsapLookupBuiltinNames failed! (Status %lx)\n", Status);
1955         goto done;
1956     }
1957 
1958     if (Mapped == Count)
1959         goto done;
1960 
1961 
1962     Status = LsapLookupAccountNames(Count,
1963                                     DomainNames,
1964                                     AccountNames,
1965                                     DomainsBuffer,
1966                                     SidsBuffer,
1967                                     &Mapped);
1968     if (!NT_SUCCESS(Status) &&
1969         Status != STATUS_NONE_MAPPED &&
1970         Status != STATUS_SOME_NOT_MAPPED)
1971     {
1972         TRACE("LsapLookupAccountNames failed! (Status %lx)\n", Status);
1973         goto done;
1974     }
1975 
1976     if (Mapped == Count)
1977         goto done;
1978 
1979 done:
1980 //    TRACE("done: Status %lx\n", Status);
1981 
1982     if (DomainNames != NULL)
1983     {
1984 //TRACE("Free DomainNames\n");
1985         for (i = 0; i < Count; i++)
1986         {
1987             if (DomainNames[i].Buffer != NULL)
1988                 MIDL_user_free(DomainNames[i].Buffer);
1989         }
1990 
1991         MIDL_user_free(DomainNames);
1992     }
1993 
1994     if (AccountNames != NULL)
1995     {
1996 //TRACE("Free AccountNames\n");
1997         for (i = 0; i < Count; i++)
1998         {
1999 //TRACE("i: %lu\n", i);
2000             if (AccountNames[i].Buffer != NULL)
2001             {
2002                 MIDL_user_free(AccountNames[i].Buffer);
2003             }
2004         }
2005 
2006         MIDL_user_free(AccountNames);
2007     }
2008 
2009     if (!NT_SUCCESS(Status))
2010     {
2011 //TRACE("Failure!\n");
2012 
2013 //TRACE("Free DomainsBuffer\n");
2014         if (DomainsBuffer != NULL)
2015         {
2016             if (DomainsBuffer->Domains != NULL)
2017                 MIDL_user_free(DomainsBuffer->Domains);
2018 
2019             MIDL_user_free(DomainsBuffer);
2020         }
2021 
2022 //TRACE("Free SidsBuffer\n");
2023         if (SidsBuffer != NULL)
2024             MIDL_user_free(SidsBuffer);
2025     }
2026     else
2027     {
2028 //TRACE("Success!\n");
2029 
2030         *ReferencedDomains = DomainsBuffer;
2031         TranslatedSids->Entries = Count;
2032         TranslatedSids->Sids = SidsBuffer;
2033         *MappedCount = Mapped;
2034 
2035         if (Mapped == 0)
2036             Status = STATUS_NONE_MAPPED;
2037         else if (Mapped < Count)
2038             Status = STATUS_SOME_NOT_MAPPED;
2039     }
2040 
2041 //    TRACE("done: Status %lx\n", Status);
2042 
2043     return Status;
2044 }
2045 
2046 
2047 static NTSTATUS
2048 LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2049                         PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
2050                         PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
2051                         PULONG Mapped)
2052 {
2053     PWELL_KNOWN_SID ptr, ptr2;
2054     LPWSTR SidString = NULL;
2055     ULONG DomainIndex;
2056     ULONG i;
2057     NTSTATUS Status = STATUS_SUCCESS;
2058 
2059     for (i = 0; i < SidEnumBuffer->Entries; i++)
2060     {
2061         /* Ignore SIDs which are already mapped */
2062         if (NamesBuffer[i].Use != SidTypeUnknown)
2063             continue;
2064 
2065         ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
2066         TRACE("Mapping SID: %S\n", SidString);
2067         LocalFree(SidString);
2068         SidString = NULL;
2069 
2070         ptr = LsapLookupWellKnownSid(SidEnumBuffer->SidInfo[i].Sid);
2071         if (ptr != NULL)
2072         {
2073             NamesBuffer[i].Use = ptr->Use;
2074             NamesBuffer[i].Flags = 0;
2075 
2076             NamesBuffer[i].Name.Length = ptr->AccountName.Length;
2077             NamesBuffer[i].Name.MaximumLength = ptr->AccountName.MaximumLength;
2078             NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->AccountName.MaximumLength);
2079             if (NamesBuffer[i].Name.Buffer == NULL)
2080             {
2081                 Status = STATUS_INSUFFICIENT_RESOURCES;
2082                 goto done;
2083             }
2084 
2085             RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->AccountName.Buffer, ptr->AccountName.MaximumLength);
2086 
2087             if (ptr->DomainName.Length == 0)
2088             {
2089                 Status = LsapAddAuthorityToDomainsList(DomainsBuffer,
2090                                                        SidEnumBuffer->SidInfo[i].Sid,
2091                                                        &DomainIndex);
2092                 if (!NT_SUCCESS(Status))
2093                     goto done;
2094 
2095                 NamesBuffer[i].DomainIndex = DomainIndex;
2096             }
2097             else
2098             {
2099                 ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
2100                 if (ptr2 != NULL)
2101                 {
2102                     Status = LsapAddDomainToDomainsList(DomainsBuffer,
2103                                                         &ptr2->AccountName,
2104                                                         ptr2->Sid,
2105                                                         &DomainIndex);
2106                     if (!NT_SUCCESS(Status))
2107                         goto done;
2108 
2109                     NamesBuffer[i].DomainIndex = DomainIndex;
2110                 }
2111             }
2112 
2113             TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2114 
2115             (*Mapped)++;
2116         }
2117     }
2118 
2119 done:
2120     return Status;
2121 }
2122 
2123 
2124 static NTSTATUS
2125 LsapLookupBuiltinDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2126                             PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
2127                             PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
2128                             PULONG Mapped)
2129 {
2130     SAMPR_HANDLE ServerHandle = NULL;
2131     SAMPR_HANDLE DomainHandle = NULL;
2132     SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
2133     SAMPR_ULONG_ARRAY Use = {0, NULL};
2134     LPWSTR SidString = NULL;
2135     ULONG DomainIndex;
2136     ULONG RelativeIds[1];
2137     ULONG i;
2138     NTSTATUS Status = STATUS_SUCCESS;
2139 
2140     Status = SamrConnect(NULL,
2141                          &ServerHandle,
2142                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
2143     if (!NT_SUCCESS(Status))
2144     {
2145         TRACE("SamrConnect failed (Status %08lx)\n", Status);
2146         goto done;
2147     }
2148 
2149     Status = SamrOpenDomain(ServerHandle,
2150                             DOMAIN_LOOKUP,
2151                             BuiltinDomainSid,
2152                             &DomainHandle);
2153     if (!NT_SUCCESS(Status))
2154     {
2155         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
2156         goto done;
2157     }
2158 
2159     for (i = 0; i < SidEnumBuffer->Entries; i++)
2160     {
2161         /* Ignore SIDs which are already mapped */
2162         if (NamesBuffer[i].Use != SidTypeUnknown)
2163             continue;
2164 
2165         ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
2166         TRACE("Mapping SID: %S\n", SidString);
2167         LocalFree(SidString);
2168         SidString = NULL;
2169 
2170         if (RtlEqualSid(BuiltinDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2171         {
2172             TRACE("Found builtin domain!\n");
2173 
2174             NamesBuffer[i].Use = SidTypeDomain;
2175             NamesBuffer[i].Flags = 0;
2176 
2177             NamesBuffer[i].Name.Length = BuiltinDomainName.Length;
2178             NamesBuffer[i].Name.MaximumLength = BuiltinDomainName.MaximumLength;
2179             NamesBuffer[i].Name.Buffer = MIDL_user_allocate(BuiltinDomainName.MaximumLength);
2180             if (NamesBuffer[i].Name.Buffer == NULL)
2181             {
2182                 Status = STATUS_INSUFFICIENT_RESOURCES;
2183                 goto done;
2184             }
2185 
2186             RtlCopyMemory(NamesBuffer[i].Name.Buffer, BuiltinDomainName.Buffer, BuiltinDomainName.MaximumLength);
2187 
2188             Status = LsapAddDomainToDomainsList(DomainsBuffer,
2189                                                 &BuiltinDomainName,
2190                                                 BuiltinDomainSid,
2191                                                 &DomainIndex);
2192             if (!NT_SUCCESS(Status))
2193                 goto done;
2194 
2195             NamesBuffer[i].DomainIndex = DomainIndex;
2196 
2197             TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2198 
2199             (*Mapped)++;
2200         }
2201         else if (LsapIsPrefixSid(BuiltinDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2202         {
2203             TRACE("Found builtin domain account!\n");
2204 
2205             RelativeIds[0] = LsapGetRelativeIdFromSid(SidEnumBuffer->SidInfo[i].Sid);
2206 
2207             Status = SamrLookupIdsInDomain(DomainHandle,
2208                                            1,
2209                                            RelativeIds,
2210                                            &Names,
2211                                            &Use);
2212             if (NT_SUCCESS(Status))
2213             {
2214                 NamesBuffer[i].Use = Use.Element[0];
2215                 NamesBuffer[i].Flags = 0;
2216 
2217                 NamesBuffer[i].Name.Length = Names.Element[0].Length;
2218                 NamesBuffer[i].Name.MaximumLength = Names.Element[0].MaximumLength;
2219                 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(Names.Element[0].MaximumLength);
2220                 if (NamesBuffer[i].Name.Buffer == NULL)
2221                 {
2222                     SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2223                     SamIFree_SAMPR_ULONG_ARRAY(&Use);
2224 
2225                     Status = STATUS_INSUFFICIENT_RESOURCES;
2226                     goto done;
2227                 }
2228 
2229                 RtlCopyMemory(NamesBuffer[i].Name.Buffer,
2230                               Names.Element[0].Buffer,
2231                               Names.Element[0].MaximumLength);
2232 
2233                 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2234                 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2235 
2236                 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2237                                                     &BuiltinDomainName,
2238                                                     BuiltinDomainSid,
2239                                                     &DomainIndex);
2240                 if (!NT_SUCCESS(Status))
2241                     goto done;
2242 
2243                 NamesBuffer[i].DomainIndex = DomainIndex;
2244 
2245                 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2246 
2247                 (*Mapped)++;
2248             }
2249         }
2250     }
2251 
2252 done:
2253     if (DomainHandle != NULL)
2254         SamrCloseHandle(&DomainHandle);
2255 
2256     if (ServerHandle != NULL)
2257         SamrCloseHandle(&ServerHandle);
2258 
2259     return Status;
2260 }
2261 
2262 
2263 static NTSTATUS
2264 LsapLookupAccountDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2265                             PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
2266                             PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
2267                             PULONG Mapped)
2268 {
2269     SAMPR_HANDLE ServerHandle = NULL;
2270     SAMPR_HANDLE DomainHandle = NULL;
2271     SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
2272     SAMPR_ULONG_ARRAY Use = {0, NULL};
2273     LPWSTR SidString = NULL;
2274     ULONG DomainIndex;
2275     ULONG RelativeIds[1];
2276     ULONG i;
2277     NTSTATUS Status = STATUS_SUCCESS;
2278 
2279     Status = SamrConnect(NULL,
2280                          &ServerHandle,
2281                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
2282     if (!NT_SUCCESS(Status))
2283     {
2284         TRACE("SamrConnect failed (Status %08lx)\n", Status);
2285         goto done;
2286     }
2287 
2288     Status = SamrOpenDomain(ServerHandle,
2289                             DOMAIN_LOOKUP,
2290                             AccountDomainSid,
2291                             &DomainHandle);
2292     if (!NT_SUCCESS(Status))
2293     {
2294         TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
2295         goto done;
2296     }
2297 
2298     for (i = 0; i < SidEnumBuffer->Entries; i++)
2299     {
2300         /* Ignore SIDs which are already mapped */
2301         if (NamesBuffer[i].Use != SidTypeUnknown)
2302             continue;
2303 
2304         ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
2305         TRACE("Mapping SID: %S\n", SidString);
2306         LocalFree(SidString);
2307         SidString = NULL;
2308 
2309         if (RtlEqualSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2310         {
2311             TRACE("Found account domain!\n");
2312 
2313             NamesBuffer[i].Use = SidTypeDomain;
2314             NamesBuffer[i].Flags = 0;
2315 
2316             NamesBuffer[i].Name.Length = AccountDomainName.Length;
2317             NamesBuffer[i].Name.MaximumLength = AccountDomainName.MaximumLength;
2318             NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AccountDomainName.MaximumLength);
2319             if (NamesBuffer[i].Name.Buffer == NULL)
2320             {
2321                 Status = STATUS_INSUFFICIENT_RESOURCES;
2322                 goto done;
2323             }
2324 
2325             RtlCopyMemory(NamesBuffer[i].Name.Buffer, AccountDomainName.Buffer, AccountDomainName.MaximumLength);
2326 
2327             Status = LsapAddDomainToDomainsList(DomainsBuffer,
2328                                                 &AccountDomainName,
2329                                                 AccountDomainSid,
2330                                                 &DomainIndex);
2331             if (!NT_SUCCESS(Status))
2332                 goto done;
2333 
2334             NamesBuffer[i].DomainIndex = DomainIndex;
2335 
2336             TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2337 
2338             (*Mapped)++;
2339         }
2340         else if (LsapIsPrefixSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
2341         {
2342             TRACE("Found account domain account!\n");
2343 
2344             RelativeIds[0] = LsapGetRelativeIdFromSid(SidEnumBuffer->SidInfo[i].Sid);
2345 
2346             Status = SamrLookupIdsInDomain(DomainHandle,
2347                                            1,
2348                                            RelativeIds,
2349                                            &Names,
2350                                            &Use);
2351             if (NT_SUCCESS(Status))
2352             {
2353                 NamesBuffer[i].Use = Use.Element[0];
2354                 NamesBuffer[i].Flags = 0;
2355 
2356                 NamesBuffer[i].Name.Length = Names.Element[0].Length;
2357                 NamesBuffer[i].Name.MaximumLength = Names.Element[0].MaximumLength;
2358                 NamesBuffer[i].Name.Buffer = MIDL_user_allocate(Names.Element[0].MaximumLength);
2359                 if (NamesBuffer[i].Name.Buffer == NULL)
2360                 {
2361                     SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2362                     SamIFree_SAMPR_ULONG_ARRAY(&Use);
2363 
2364                     Status = STATUS_INSUFFICIENT_RESOURCES;
2365                     goto done;
2366                 }
2367 
2368                 RtlCopyMemory(NamesBuffer[i].Name.Buffer,
2369                               Names.Element[0].Buffer,
2370                               Names.Element[0].MaximumLength);
2371 
2372                 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
2373                 SamIFree_SAMPR_ULONG_ARRAY(&Use);
2374 
2375                 Status = LsapAddDomainToDomainsList(DomainsBuffer,
2376                                                     &AccountDomainName,
2377                                                     AccountDomainSid,
2378                                                     &DomainIndex);
2379                 if (!NT_SUCCESS(Status))
2380                     goto done;
2381 
2382                 NamesBuffer[i].DomainIndex = DomainIndex;
2383 
2384                 TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
2385 
2386                 (*Mapped)++;
2387             }
2388         }
2389     }
2390 
2391 done:
2392     if (DomainHandle != NULL)
2393         SamrCloseHandle(&DomainHandle);
2394 
2395     if (ServerHandle != NULL)
2396         SamrCloseHandle(&ServerHandle);
2397 
2398     return Status;
2399 }
2400 
2401 
2402 NTSTATUS
2403 LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
2404                PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
2405                PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
2406                LSAP_LOOKUP_LEVEL LookupLevel,
2407                DWORD *MappedCount,
2408                DWORD LookupOptions,
2409                DWORD ClientRevision)
2410 {
2411     PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
2412     PLSAPR_TRANSLATED_NAME_EX NamesBuffer = NULL;
2413     ULONG NamesBufferLength;
2414     ULONG i;
2415     ULONG Mapped = 0;
2416     NTSTATUS Status = STATUS_SUCCESS;
2417 
2418     NamesBufferLength = SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME_EX);
2419     NamesBuffer = MIDL_user_allocate(NamesBufferLength);
2420     if (NamesBuffer == NULL)
2421     {
2422         Status = STATUS_INSUFFICIENT_RESOURCES;
2423         goto done;
2424     }
2425 
2426     DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
2427     if (DomainsBuffer == NULL)
2428     {
2429         Status = STATUS_INSUFFICIENT_RESOURCES;
2430         goto done;
2431     }
2432 
2433     DomainsBuffer->Domains = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSA_TRUST_INFORMATION));
2434     if (DomainsBuffer->Domains == NULL)
2435     {
2436         Status = STATUS_INSUFFICIENT_RESOURCES;
2437         goto done;
2438     }
2439 
2440     DomainsBuffer->Entries = 0;
2441     DomainsBuffer->MaxEntries = SidEnumBuffer->Entries;
2442 
2443     /* Initialize all name entries */
2444     for (i = 0; i < SidEnumBuffer->Entries; i++)
2445     {
2446         NamesBuffer[i].Use = SidTypeUnknown;
2447         NamesBuffer[i].Name.Length = 0;
2448         NamesBuffer[i].Name.MaximumLength = 0;
2449         NamesBuffer[i].Name.Buffer = NULL;
2450         NamesBuffer[i].DomainIndex = -1;
2451         NamesBuffer[i].Flags = 0;
2452     }
2453 
2454     /* Look-up well-known SIDs */
2455     Status = LsapLookupWellKnownSids(SidEnumBuffer,
2456                                      NamesBuffer,
2457                                      DomainsBuffer,
2458                                      &Mapped);
2459     if (!NT_SUCCESS(Status) &&
2460         Status != STATUS_NONE_MAPPED &&
2461         Status != STATUS_SOME_NOT_MAPPED)
2462         goto done;
2463 
2464     if (Mapped == SidEnumBuffer->Entries)
2465         goto done;
2466 
2467     /* Look-up builtin domain SIDs */
2468     Status = LsapLookupBuiltinDomainSids(SidEnumBuffer,
2469                                          NamesBuffer,
2470                                          DomainsBuffer,
2471                                          &Mapped);
2472     if (!NT_SUCCESS(Status) &&
2473         Status != STATUS_NONE_MAPPED &&
2474         Status != STATUS_SOME_NOT_MAPPED)
2475         goto done;
2476 
2477     if (Mapped == SidEnumBuffer->Entries)
2478         goto done;
2479 
2480     /* Look-up account domain SIDs */
2481     Status = LsapLookupAccountDomainSids(SidEnumBuffer,
2482                                          NamesBuffer,
2483                                          DomainsBuffer,
2484                                          &Mapped);
2485     if (!NT_SUCCESS(Status) &&
2486         Status != STATUS_NONE_MAPPED &&
2487         Status != STATUS_SOME_NOT_MAPPED)
2488         goto done;
2489 
2490     if (Mapped == SidEnumBuffer->Entries)
2491         goto done;
2492 
2493 done:
2494     TRACE("done Status: %lx  Mapped: %lu\n", Status, Mapped);
2495 
2496     if (!NT_SUCCESS(Status))
2497     {
2498         if (DomainsBuffer != NULL)
2499         {
2500             if (DomainsBuffer->Domains != NULL)
2501                 MIDL_user_free(DomainsBuffer->Domains);
2502 
2503             MIDL_user_free(DomainsBuffer);
2504         }
2505 
2506         if (NamesBuffer != NULL)
2507             MIDL_user_free(NamesBuffer);
2508     }
2509     else
2510     {
2511         *ReferencedDomains = DomainsBuffer;
2512         TranslatedNames->Entries = SidEnumBuffer->Entries;
2513         TranslatedNames->Names = NamesBuffer;
2514         *MappedCount = Mapped;
2515 
2516         if (Mapped == 0)
2517             Status = STATUS_NONE_MAPPED;
2518         else if (Mapped < SidEnumBuffer->Entries)
2519             Status = STATUS_SOME_NOT_MAPPED;
2520     }
2521 
2522     return Status;
2523 }
2524 
2525 /* EOF */
2526