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