xref: /reactos/dll/win32/lsasrv/lsarpc.c (revision d5399189)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         Local Security Authority (LSA) Server
4  * FILE:            reactos/dll/win32/lsasrv/lsarpc.h
5  * PURPOSE:         RPC interface functions
6  *
7  * PROGRAMMERS:     Eric Kohl
8  */
9 
10 #include "lsasrv.h"
11 
12 /* GLOBALS *****************************************************************/
13 
14 static RTL_CRITICAL_SECTION PolicyHandleTableLock;
15 
16 static
17 GENERIC_MAPPING
18 LsapPolicyMapping = {POLICY_READ,
19                      POLICY_WRITE,
20                      POLICY_EXECUTE,
21                      POLICY_ALL_ACCESS};
22 
23 static
24 GENERIC_MAPPING
25 LsapAccountMapping = {ACCOUNT_READ,
26                       ACCOUNT_WRITE,
27                       ACCOUNT_EXECUTE,
28                       ACCOUNT_ALL_ACCESS};
29 
30 static
31 GENERIC_MAPPING
32 LsapSecretMapping = {SECRET_READ,
33                      SECRET_WRITE,
34                      SECRET_EXECUTE,
35                      SECRET_ALL_ACCESS};
36 
37 /* FUNCTIONS ***************************************************************/
38 
39 NTSTATUS
40 LsarStartRpcServer(VOID)
41 {
42     RPC_STATUS Status;
43     DWORD dwError;
44     HANDLE hEvent;
45 
46     RtlInitializeCriticalSection(&PolicyHandleTableLock);
47 
48     TRACE("LsarStartRpcServer() called\n");
49 
50     Status = RpcServerUseProtseqEpW(L"ncacn_np",
51                                     RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
52                                     L"\\pipe\\lsarpc",
53                                     NULL);
54     if (Status != RPC_S_OK)
55     {
56         WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
57         return I_RpcMapWin32Status(Status);
58     }
59 
60     Status = RpcServerRegisterIf(lsarpc_v0_0_s_ifspec,
61                                  NULL,
62                                  NULL);
63     if (Status != RPC_S_OK)
64     {
65         WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status);
66         return I_RpcMapWin32Status(Status);
67     }
68 
69     DsSetupInit();
70 
71     Status = RpcServerListen(1, 20, TRUE);
72     if (Status != RPC_S_OK)
73     {
74         WARN("RpcServerListen() failed (Status %lx)\n", Status);
75         return I_RpcMapWin32Status(Status);
76     }
77 
78     /* Notify the service manager */
79     TRACE("Creating notification event!\n");
80     hEvent = CreateEventW(NULL,
81                           TRUE,
82                           FALSE,
83                           L"LSA_RPC_SERVER_ACTIVE");
84     if (hEvent == NULL)
85     {
86         dwError = GetLastError();
87         TRACE("Failed to create or open the notification event (Error %lu)\n", dwError);
88 #if 0
89         if (dwError == ERROR_ALREADY_EXISTS)
90         {
91             hEvent = OpenEventW(GENERIC_WRITE,
92                                 FALSE,
93                                 L"LSA_RPC_SERVER_ACTIVE");
94             if (hEvent == NULL)
95             {
96                ERR("Could not open the notification event (Error %lu)\n", GetLastError());
97                return STATUS_UNSUCCESSFUL;
98             }
99         }
100 #endif
101         return STATUS_UNSUCCESSFUL;
102     }
103 
104     TRACE("Set notification event!\n");
105     SetEvent(hEvent);
106 
107     /* NOTE: Do not close the event handle, as it must remain alive! */
108 
109     TRACE("LsarStartRpcServer() done\n");
110     return STATUS_SUCCESS;
111 }
112 
113 
114 void __RPC_USER LSAPR_HANDLE_rundown(LSAPR_HANDLE hHandle)
115 {
116 
117 }
118 
119 
120 /* Function 0 */
121 NTSTATUS WINAPI LsarClose(
122     LSAPR_HANDLE *ObjectHandle)
123 {
124     PLSA_DB_OBJECT DbObject;
125     NTSTATUS Status = STATUS_SUCCESS;
126 
127     TRACE("LsarClose(%p)\n", ObjectHandle);
128 
129 //    RtlEnterCriticalSection(&PolicyHandleTableLock);
130 
131     Status = LsapValidateDbObject(*ObjectHandle,
132                                   LsaDbIgnoreObject,
133                                   0,
134                                   &DbObject);
135     if (Status == STATUS_SUCCESS)
136     {
137         Status = LsapCloseDbObject(DbObject);
138         *ObjectHandle = NULL;
139     }
140 
141 //    RtlLeaveCriticalSection(&PolicyHandleTableLock);
142 
143     return Status;
144 }
145 
146 
147 /* Function 1 */
148 NTSTATUS WINAPI LsarDelete(
149     LSAPR_HANDLE ObjectHandle)
150 {
151     TRACE("LsarDelete(%p)\n", ObjectHandle);
152 
153     return LsarDeleteObject(&ObjectHandle);
154 }
155 
156 
157 /* Function 2 */
158 NTSTATUS WINAPI LsarEnumeratePrivileges(
159     LSAPR_HANDLE PolicyHandle,
160     DWORD *EnumerationContext,
161     PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
162     DWORD PreferedMaximumLength)
163 {
164     PLSA_DB_OBJECT PolicyObject;
165     NTSTATUS Status;
166 
167     TRACE("LsarEnumeratePrivileges(%p %p %p %lu)\n",
168           PolicyHandle, EnumerationContext, EnumerationBuffer,
169           PreferedMaximumLength);
170 
171     Status = LsapValidateDbObject(PolicyHandle,
172                                   LsaDbPolicyObject,
173                                   POLICY_VIEW_LOCAL_INFORMATION,
174                                   &PolicyObject);
175     if (!NT_SUCCESS(Status))
176         return Status;
177 
178     if (EnumerationContext == NULL)
179         return STATUS_INVALID_PARAMETER;
180 
181     return LsarpEnumeratePrivileges(EnumerationContext,
182                                     EnumerationBuffer,
183                                     PreferedMaximumLength);
184 }
185 
186 
187 /* Function 3 */
188 NTSTATUS WINAPI LsarQuerySecurityObject(
189     LSAPR_HANDLE ObjectHandle,
190     SECURITY_INFORMATION SecurityInformation,
191     PLSAPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor)
192 {
193     PLSA_DB_OBJECT DbObject = NULL;
194     PSECURITY_DESCRIPTOR RelativeSd = NULL;
195     PSECURITY_DESCRIPTOR ResultSd = NULL;
196     PLSAPR_SR_SECURITY_DESCRIPTOR SdData = NULL;
197     ACCESS_MASK DesiredAccess = 0;
198     ULONG RelativeSdSize = 0;
199     ULONG ResultSdSize = 0;
200     NTSTATUS Status;
201 
202     TRACE("LsarQuerySecurityObject(%p %lx %p)\n",
203           ObjectHandle, SecurityInformation, SecurityDescriptor);
204 
205     if (SecurityDescriptor == NULL)
206         return STATUS_INVALID_PARAMETER;
207 
208     *SecurityDescriptor = NULL;
209 
210     if ((SecurityInformation & OWNER_SECURITY_INFORMATION) ||
211         (SecurityInformation & GROUP_SECURITY_INFORMATION) ||
212         (SecurityInformation & DACL_SECURITY_INFORMATION))
213         DesiredAccess |= READ_CONTROL;
214 
215     if (SecurityInformation & SACL_SECURITY_INFORMATION)
216         DesiredAccess |= ACCESS_SYSTEM_SECURITY;
217 
218     /* Validate the ObjectHandle */
219     Status = LsapValidateDbObject(ObjectHandle,
220                                   LsaDbIgnoreObject,
221                                   DesiredAccess,
222                                   &DbObject);
223     if (!NT_SUCCESS(Status))
224         return Status;
225 
226     /* Get the size of the SD */
227     Status = LsapGetObjectAttribute(DbObject,
228                                     L"SecDesc",
229                                     NULL,
230                                     &RelativeSdSize);
231     if (!NT_SUCCESS(Status))
232         return Status;
233 
234     /* Allocate a buffer for the SD */
235     RelativeSd = MIDL_user_allocate(RelativeSdSize);
236     if (RelativeSd == NULL)
237         return STATUS_INSUFFICIENT_RESOURCES;
238 
239     /* Get the SD */
240     Status = LsapGetObjectAttribute(DbObject,
241                                     L"SecDesc",
242                                     RelativeSd,
243                                     &RelativeSdSize);
244     if (!NT_SUCCESS(Status))
245         goto done;
246 
247     /* Invalidate the SD information that was not requested */
248     if (!(SecurityInformation & OWNER_SECURITY_INFORMATION))
249         ((PISECURITY_DESCRIPTOR)RelativeSd)->Owner = NULL;
250 
251     if (!(SecurityInformation & GROUP_SECURITY_INFORMATION))
252         ((PISECURITY_DESCRIPTOR)RelativeSd)->Group = NULL;
253 
254     if (!(SecurityInformation & DACL_SECURITY_INFORMATION))
255         ((PISECURITY_DESCRIPTOR)RelativeSd)->Control &= ~SE_DACL_PRESENT;
256 
257     if (!(SecurityInformation & SACL_SECURITY_INFORMATION))
258         ((PISECURITY_DESCRIPTOR)RelativeSd)->Control &= ~SE_SACL_PRESENT;
259 
260     /* Calculate the required SD size */
261     Status = RtlMakeSelfRelativeSD(RelativeSd,
262                                    NULL,
263                                    &ResultSdSize);
264     if (Status != STATUS_BUFFER_TOO_SMALL)
265         goto done;
266 
267     /* Allocate a buffer for the new SD */
268     ResultSd = MIDL_user_allocate(ResultSdSize);
269     if (ResultSd == NULL)
270     {
271         Status = STATUS_INSUFFICIENT_RESOURCES;
272         goto done;
273     }
274 
275     /* Build the new SD */
276     Status = RtlMakeSelfRelativeSD(RelativeSd,
277                                    ResultSd,
278                                    &ResultSdSize);
279     if (!NT_SUCCESS(Status))
280         goto done;
281 
282     /* Allocate the SD data buffer */
283     SdData = MIDL_user_allocate(sizeof(LSAPR_SR_SECURITY_DESCRIPTOR));
284     if (SdData == NULL)
285     {
286         Status = STATUS_INSUFFICIENT_RESOURCES;
287         goto done;
288     }
289 
290     /* Fill the SD data buffer and return it to the caller */
291     SdData->Length = RelativeSdSize;
292     SdData->SecurityDescriptor = (PBYTE)ResultSd;
293 
294     *SecurityDescriptor = SdData;
295 
296 done:
297     if (!NT_SUCCESS(Status))
298     {
299         if (ResultSd != NULL)
300             MIDL_user_free(ResultSd);
301     }
302 
303     if (RelativeSd != NULL)
304         MIDL_user_free(RelativeSd);
305 
306     return Status;
307 }
308 
309 
310 /* Function 4 */
311 NTSTATUS WINAPI LsarSetSecurityObject(
312     LSAPR_HANDLE ObjectHandle,
313     SECURITY_INFORMATION SecurityInformation,
314     PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor)
315 {
316     PLSA_DB_OBJECT DbObject = NULL;
317     ACCESS_MASK DesiredAccess = 0;
318     PSECURITY_DESCRIPTOR RelativeSd = NULL;
319     ULONG RelativeSdSize = 0;
320     HANDLE TokenHandle = NULL;
321     PGENERIC_MAPPING Mapping;
322     NTSTATUS Status;
323 
324     TRACE("LsarSetSecurityObject(%p %lx %p)\n",
325           ObjectHandle, SecurityInformation, SecurityDescriptor);
326 
327     if ((SecurityDescriptor == NULL) ||
328         (SecurityDescriptor->SecurityDescriptor == NULL) ||
329         !RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR)SecurityDescriptor->SecurityDescriptor))
330         return ERROR_INVALID_PARAMETER;
331 
332     if (SecurityInformation == 0 ||
333         SecurityInformation & ~(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
334         | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION))
335         return ERROR_INVALID_PARAMETER;
336 
337     if (SecurityInformation & SACL_SECURITY_INFORMATION)
338         DesiredAccess |= ACCESS_SYSTEM_SECURITY;
339 
340     if (SecurityInformation & DACL_SECURITY_INFORMATION)
341         DesiredAccess |= WRITE_DAC;
342 
343     if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
344         DesiredAccess |= WRITE_OWNER;
345 
346     if ((SecurityInformation & OWNER_SECURITY_INFORMATION) &&
347         (((PISECURITY_DESCRIPTOR)SecurityDescriptor)->Owner == NULL))
348         return ERROR_INVALID_PARAMETER;
349 
350     if ((SecurityInformation & GROUP_SECURITY_INFORMATION) &&
351         (((PISECURITY_DESCRIPTOR)SecurityDescriptor)->Group == NULL))
352         return ERROR_INVALID_PARAMETER;
353 
354     /* Validate the ObjectHandle */
355     Status = LsapValidateDbObject(ObjectHandle,
356                                   LsaDbIgnoreObject,
357                                   DesiredAccess,
358                                   &DbObject);
359     if (!NT_SUCCESS(Status))
360     {
361         ERR("LsapValidateDbObject failed (Status 0x%08lx)\n", Status);
362         return Status;
363     }
364 
365     /* Get the mapping for the object type */
366     switch (DbObject->ObjectType)
367     {
368         case LsaDbPolicyObject:
369             Mapping = &LsapPolicyMapping;
370             break;
371 
372         case LsaDbAccountObject:
373             Mapping = &LsapAccountMapping;
374             break;
375 
376 //        case LsaDbDomainObject:
377 //            Mapping = &LsapDomainMapping;
378 //            break;
379 
380         case LsaDbSecretObject:
381             Mapping = &LsapSecretMapping;
382             break;
383 
384         default:
385             return STATUS_INVALID_HANDLE;
386     }
387 
388     /* Get the size of the SD */
389     Status = LsapGetObjectAttribute(DbObject,
390                                     L"SecDesc",
391                                     NULL,
392                                     &RelativeSdSize);
393     if (!NT_SUCCESS(Status))
394         return Status;
395 
396     /* Allocate a buffer for the SD */
397     RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(), 0, RelativeSdSize);
398     if (RelativeSd == NULL)
399         return STATUS_INSUFFICIENT_RESOURCES;
400 
401     /* Get the SD */
402     Status = LsapGetObjectAttribute(DbObject,
403                                     L"SecDesc",
404                                     RelativeSd,
405                                     &RelativeSdSize);
406     if (!NT_SUCCESS(Status))
407         goto done;
408 
409     /* Get the clients token if we try to set the owner */
410     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
411     {
412         Status = I_RpcMapWin32Status(RpcImpersonateClient(NULL));
413         if (!NT_SUCCESS(Status))
414         {
415             ERR("RpcImpersonateClient returns 0x%08lx\n", Status);
416             goto done;
417         }
418 
419         Status = NtOpenThreadToken(NtCurrentThread(),
420                                    TOKEN_QUERY,
421                                    TRUE,
422                                    &TokenHandle);
423         RpcRevertToSelf();
424         if (!NT_SUCCESS(Status))
425         {
426             ERR("NtOpenThreadToken returns 0x%08lx\n", Status);
427             goto done;
428         }
429     }
430 
431     /* Build the new security descriptor */
432     Status = RtlSetSecurityObject(SecurityInformation,
433                                   (PSECURITY_DESCRIPTOR)SecurityDescriptor->SecurityDescriptor,
434                                   &RelativeSd,
435                                   Mapping,
436                                   TokenHandle);
437     if (!NT_SUCCESS(Status))
438     {
439         ERR("RtlSetSecurityObject failed (Status 0x%08lx)\n", Status);
440         goto done;
441     }
442 
443     /* Set the modified SD */
444     Status = LsapSetObjectAttribute(DbObject,
445                                     L"SecDesc",
446                                     RelativeSd,
447                                     RtlLengthSecurityDescriptor(RelativeSd));
448     if (!NT_SUCCESS(Status))
449     {
450         ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
451     }
452 
453 done:
454     if (TokenHandle != NULL)
455         NtClose(TokenHandle);
456 
457     if (RelativeSd != NULL)
458         RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
459 
460     return Status;
461 }
462 
463 
464 /* Function 5 */
465 NTSTATUS WINAPI LsarChangePassword(
466     handle_t IDL_handle,
467     PRPC_UNICODE_STRING String1,
468     PRPC_UNICODE_STRING String2,
469     PRPC_UNICODE_STRING String3,
470     PRPC_UNICODE_STRING String4,
471     PRPC_UNICODE_STRING String5)
472 {
473     /* Deprecated */
474     return STATUS_NOT_IMPLEMENTED;
475 }
476 
477 
478 /* Function 6 */
479 NTSTATUS WINAPI LsarOpenPolicy(
480     LPWSTR SystemName,
481     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
482     ACCESS_MASK DesiredAccess,
483     LSAPR_HANDLE *PolicyHandle)
484 {
485     PLSA_DB_OBJECT PolicyObject;
486     NTSTATUS Status;
487 
488     TRACE("LsarOpenPolicy(%S %p %lx %p)\n",
489           SystemName, ObjectAttributes, DesiredAccess, PolicyHandle);
490 
491     RtlEnterCriticalSection(&PolicyHandleTableLock);
492 
493     Status = LsapOpenDbObject(NULL,
494                               NULL,
495                               L"Policy",
496                               LsaDbPolicyObject,
497                               DesiredAccess,
498                               FALSE,
499                               &PolicyObject);
500 
501     RtlLeaveCriticalSection(&PolicyHandleTableLock);
502 
503     if (NT_SUCCESS(Status))
504         *PolicyHandle = (LSAPR_HANDLE)PolicyObject;
505 
506     TRACE("LsarOpenPolicy done!\n");
507 
508     return Status;
509 }
510 
511 
512 /* Function 7 */
513 NTSTATUS WINAPI LsarQueryInformationPolicy(
514     LSAPR_HANDLE PolicyHandle,
515     POLICY_INFORMATION_CLASS InformationClass,
516     PLSAPR_POLICY_INFORMATION *PolicyInformation)
517 {
518     PLSA_DB_OBJECT PolicyObject;
519     ACCESS_MASK DesiredAccess = 0;
520     NTSTATUS Status;
521 
522     TRACE("LsarQueryInformationPolicy(%p,0x%08x,%p)\n",
523           PolicyHandle, InformationClass, PolicyInformation);
524 
525     if (PolicyInformation)
526     {
527         TRACE("*PolicyInformation %p\n", *PolicyInformation);
528     }
529 
530     switch (InformationClass)
531     {
532         case PolicyAuditLogInformation:
533         case PolicyAuditEventsInformation:
534         case PolicyAuditFullQueryInformation:
535             DesiredAccess = POLICY_VIEW_AUDIT_INFORMATION;
536             break;
537 
538         case PolicyPrimaryDomainInformation:
539         case PolicyAccountDomainInformation:
540         case PolicyLsaServerRoleInformation:
541         case PolicyReplicaSourceInformation:
542         case PolicyDefaultQuotaInformation:
543         case PolicyModificationInformation:
544         case PolicyDnsDomainInformation:
545         case PolicyDnsDomainInformationInt:
546         case PolicyLocalAccountDomainInformation:
547             DesiredAccess = POLICY_VIEW_LOCAL_INFORMATION;
548             break;
549 
550         case PolicyPdAccountInformation:
551             DesiredAccess = POLICY_GET_PRIVATE_INFORMATION;
552             break;
553 
554         default:
555             ERR("Invalid InformationClass!\n");
556             return STATUS_INVALID_PARAMETER;
557     }
558 
559     Status = LsapValidateDbObject(PolicyHandle,
560                                   LsaDbPolicyObject,
561                                   DesiredAccess,
562                                   &PolicyObject);
563     if (!NT_SUCCESS(Status))
564         return Status;
565 
566     switch (InformationClass)
567     {
568         case PolicyAuditLogInformation:      /* 1 */
569             Status = LsarQueryAuditLog(PolicyObject,
570                                        PolicyInformation);
571             break;
572 
573         case PolicyAuditEventsInformation:   /* 2 */
574             Status = LsarQueryAuditEvents(PolicyObject,
575                                           PolicyInformation);
576             break;
577 
578         case PolicyPrimaryDomainInformation: /* 3 */
579             Status = LsarQueryPrimaryDomain(PolicyObject,
580                                             PolicyInformation);
581             break;
582 
583         case PolicyPdAccountInformation:     /* 4 */
584             Status = LsarQueryPdAccount(PolicyObject,
585                                         PolicyInformation);
586             break;
587 
588         case PolicyAccountDomainInformation: /* 5 */
589             Status = LsarQueryAccountDomain(PolicyObject,
590                                             PolicyInformation);
591             break;
592 
593         case PolicyLsaServerRoleInformation: /* 6 */
594             Status = LsarQueryServerRole(PolicyObject,
595                                          PolicyInformation);
596             break;
597 
598         case PolicyReplicaSourceInformation: /* 7 */
599             Status = LsarQueryReplicaSource(PolicyObject,
600                                             PolicyInformation);
601             break;
602 
603         case PolicyDefaultQuotaInformation:  /* 8 */
604             Status = LsarQueryDefaultQuota(PolicyObject,
605                                            PolicyInformation);
606             break;
607 
608         case PolicyModificationInformation:  /* 9 */
609             Status = LsarQueryModification(PolicyObject,
610                                            PolicyInformation);
611             break;
612 
613         case PolicyAuditFullQueryInformation: /* 11 (0xB) */
614             Status = LsarQueryAuditFull(PolicyObject,
615                                         PolicyInformation);
616             break;
617 
618         case PolicyDnsDomainInformation:      /* 12 (0xC) */
619             Status = LsarQueryDnsDomain(PolicyObject,
620                                         PolicyInformation);
621             break;
622 
623         case PolicyDnsDomainInformationInt:   /* 13 (0xD) */
624             Status = LsarQueryDnsDomainInt(PolicyObject,
625                                            PolicyInformation);
626             break;
627 
628         case PolicyLocalAccountDomainInformation: /* 14 (0xE) */
629             Status = LsarQueryLocalAccountDomain(PolicyObject,
630                                                  PolicyInformation);
631             break;
632 
633         default:
634             ERR("Invalid InformationClass!\n");
635             Status = STATUS_INVALID_PARAMETER;
636     }
637 
638     return Status;
639 }
640 
641 
642 /* Function 8 */
643 NTSTATUS WINAPI LsarSetInformationPolicy(
644     LSAPR_HANDLE PolicyHandle,
645     POLICY_INFORMATION_CLASS InformationClass,
646     PLSAPR_POLICY_INFORMATION PolicyInformation)
647 {
648     PLSA_DB_OBJECT PolicyObject;
649     ACCESS_MASK DesiredAccess = 0;
650     NTSTATUS Status;
651 
652     TRACE("LsarSetInformationPolicy(%p,0x%08x,%p)\n",
653           PolicyHandle, InformationClass, PolicyInformation);
654 
655     if (PolicyInformation)
656     {
657         TRACE("*PolicyInformation %p\n", *PolicyInformation);
658     }
659 
660     switch (InformationClass)
661     {
662         case PolicyAuditLogInformation:
663         case PolicyAuditFullSetInformation:
664             DesiredAccess = POLICY_AUDIT_LOG_ADMIN;
665             break;
666 
667         case PolicyAuditEventsInformation:
668             DesiredAccess = POLICY_SET_AUDIT_REQUIREMENTS;
669             break;
670 
671         case PolicyPrimaryDomainInformation:
672         case PolicyAccountDomainInformation:
673         case PolicyDnsDomainInformation:
674         case PolicyDnsDomainInformationInt:
675         case PolicyLocalAccountDomainInformation:
676             DesiredAccess = POLICY_TRUST_ADMIN;
677             break;
678 
679         case PolicyLsaServerRoleInformation:
680         case PolicyReplicaSourceInformation:
681             DesiredAccess = POLICY_SERVER_ADMIN;
682             break;
683 
684         case PolicyDefaultQuotaInformation:
685             DesiredAccess = POLICY_SET_DEFAULT_QUOTA_LIMITS;
686             break;
687 
688         default:
689             ERR("Invalid InformationClass!\n");
690             return STATUS_INVALID_PARAMETER;
691     }
692 
693     Status = LsapValidateDbObject(PolicyHandle,
694                                   LsaDbPolicyObject,
695                                   DesiredAccess,
696                                   &PolicyObject);
697     if (!NT_SUCCESS(Status))
698         return Status;
699 
700     switch (InformationClass)
701     {
702         case PolicyAuditLogInformation:      /* 1 */
703             Status = LsarSetAuditLog(PolicyObject,
704                                      (PPOLICY_AUDIT_LOG_INFO)PolicyInformation);
705             break;
706 
707         case PolicyAuditEventsInformation:   /* 2 */
708             Status = LsarSetAuditEvents(PolicyObject,
709                                         (PLSAPR_POLICY_AUDIT_EVENTS_INFO)PolicyInformation);
710             if (NT_SUCCESS(Status))
711                 LsapNotifyPolicyChange(PolicyNotifyAuditEventsInformation);
712             break;
713 
714         case PolicyPrimaryDomainInformation: /* 3 */
715             Status = LsarSetPrimaryDomain(PolicyObject,
716                                           (PLSAPR_POLICY_PRIMARY_DOM_INFO)PolicyInformation);
717             if (NT_SUCCESS(Status))
718                 LsapNotifyPolicyChange(PolicyNotifyDnsDomainInformation);
719             break;
720 
721         case PolicyAccountDomainInformation: /* 5 */
722             Status = LsarSetAccountDomain(PolicyObject,
723                                           (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation);
724             if (NT_SUCCESS(Status))
725                 LsapNotifyPolicyChange(PolicyNotifyAccountDomainInformation);
726             break;
727 
728         case PolicyLsaServerRoleInformation: /* 6 */
729             Status = LsarSetServerRole(PolicyObject,
730                                        (PPOLICY_LSA_SERVER_ROLE_INFO)PolicyInformation);
731             if (NT_SUCCESS(Status))
732                 LsapNotifyPolicyChange(PolicyNotifyServerRoleInformation);
733             break;
734 
735         case PolicyReplicaSourceInformation: /* 7 */
736             Status = LsarSetReplicaSource(PolicyObject,
737                                           (PPOLICY_LSA_REPLICA_SRCE_INFO)PolicyInformation);
738             break;
739 
740         case PolicyDefaultQuotaInformation:  /* 8 */
741             Status = LsarSetDefaultQuota(PolicyObject,
742                                          (PPOLICY_DEFAULT_QUOTA_INFO)PolicyInformation);
743             break;
744 
745         case PolicyModificationInformation:  /* 9 */
746             Status = LsarSetModification(PolicyObject,
747                                          (PPOLICY_MODIFICATION_INFO)PolicyInformation);
748             break;
749 
750         case PolicyAuditFullSetInformation:  /* 10 (0xA) */
751             Status = LsarSetAuditFull(PolicyObject,
752                                       (PPOLICY_AUDIT_FULL_QUERY_INFO)PolicyInformation);
753             break;
754 
755         case PolicyDnsDomainInformation:      /* 12 (0xC) */
756             Status = LsarSetDnsDomain(PolicyObject,
757                                       (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation);
758             if (NT_SUCCESS(Status))
759                 LsapNotifyPolicyChange(PolicyNotifyDnsDomainInformation);
760             break;
761 
762         case PolicyDnsDomainInformationInt:   /* 13 (0xD) */
763             Status = LsarSetDnsDomainInt(PolicyObject,
764                                          (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation);
765             break;
766 
767         case PolicyLocalAccountDomainInformation: /* 14 (0xE) */
768             Status = LsarSetLocalAccountDomain(PolicyObject,
769                                                (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation);
770             break;
771 
772         default:
773             Status = STATUS_INVALID_PARAMETER;
774             break;
775     }
776 
777     return Status;
778 }
779 
780 
781 /* Function 9 */
782 NTSTATUS WINAPI LsarClearAuditLog(
783     LSAPR_HANDLE ObjectHandle)
784 {
785     /* Deprecated */
786     return STATUS_NOT_IMPLEMENTED;
787 }
788 
789 
790 NTSTATUS
791 LsarpCreateAccount(
792     PLSA_DB_OBJECT PolicyObject,
793     PRPC_SID AccountSid,
794     ACCESS_MASK DesiredAccess,
795     PLSA_DB_OBJECT *AccountObject)
796 {
797     LPWSTR SidString = NULL;
798     PSECURITY_DESCRIPTOR AccountSd = NULL;
799     ULONG AccountSdSize;
800     NTSTATUS Status = STATUS_SUCCESS;
801 
802     /* Create SID string */
803     if (!ConvertSidToStringSid((PSID)AccountSid,
804                                &SidString))
805     {
806         ERR("ConvertSidToStringSid failed\n");
807         return STATUS_INVALID_PARAMETER;
808     }
809 
810     /* Create a security descriptor for the account */
811     Status = LsapCreateAccountSd(&AccountSd,
812                                  &AccountSdSize);
813     if (!NT_SUCCESS(Status))
814     {
815         ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
816         goto done;
817     }
818 
819     /* Create the Account object */
820     Status = LsapCreateDbObject(PolicyObject,
821                                 L"Accounts",
822                                 SidString,
823                                 LsaDbAccountObject,
824                                 DesiredAccess,
825                                 PolicyObject->Trusted,
826                                 AccountObject);
827     if (!NT_SUCCESS(Status))
828     {
829         ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
830         goto done;
831     }
832 
833     /* Set the Sid attribute */
834     Status = LsapSetObjectAttribute(*AccountObject,
835                                     L"Sid",
836                                     (PVOID)AccountSid,
837                                     GetLengthSid(AccountSid));
838     if (!NT_SUCCESS(Status))
839         goto done;
840 
841     /* Set the SecDesc attribute */
842     Status = LsapSetObjectAttribute(*AccountObject,
843                                     L"SecDesc",
844                                     AccountSd,
845                                     AccountSdSize);
846 
847 done:
848     if (SidString != NULL)
849         LocalFree(SidString);
850 
851     if (AccountSd != NULL)
852         RtlFreeHeap(RtlGetProcessHeap(), 0, AccountSd);
853 
854     return Status;
855 }
856 
857 
858 /* Function 10 */
859 NTSTATUS WINAPI LsarCreateAccount(
860     LSAPR_HANDLE PolicyHandle,
861     PRPC_SID AccountSid,
862     ACCESS_MASK DesiredAccess,
863     LSAPR_HANDLE *AccountHandle)
864 {
865     PLSA_DB_OBJECT PolicyObject;
866     PLSA_DB_OBJECT AccountObject = NULL;
867     NTSTATUS Status = STATUS_SUCCESS;
868 
869     TRACE("LsarCreateAccount(%p %p %lx %p)\n",
870           PolicyHandle, AccountSid, DesiredAccess, AccountHandle);
871 
872     /* Validate the AccountSid */
873     if (!RtlValidSid(AccountSid))
874         return STATUS_INVALID_PARAMETER;
875 
876     /* Validate the PolicyHandle */
877     Status = LsapValidateDbObject(PolicyHandle,
878                                   LsaDbPolicyObject,
879                                   POLICY_CREATE_ACCOUNT,
880                                   &PolicyObject);
881     if (!NT_SUCCESS(Status))
882     {
883         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
884         return Status;
885     }
886 
887 
888     Status = LsarpCreateAccount(PolicyObject,
889                                 AccountSid,
890                                 DesiredAccess,
891                                 &AccountObject);
892     if (NT_SUCCESS(Status))
893     {
894         *AccountHandle = (LSAPR_HANDLE)AccountObject;
895     }
896 
897     return Status;
898 }
899 
900 
901 /* Function 11 */
902 NTSTATUS WINAPI LsarEnumerateAccounts(
903     LSAPR_HANDLE PolicyHandle,
904     DWORD *EnumerationContext,
905     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer,
906     DWORD PreferedMaximumLength)
907 {
908     LSAPR_ACCOUNT_ENUM_BUFFER EnumBuffer = {0, NULL};
909     PLSA_DB_OBJECT PolicyObject = NULL;
910     PWSTR AccountKeyBuffer = NULL;
911     HANDLE AccountsKeyHandle = NULL;
912     HANDLE AccountKeyHandle;
913     HANDLE SidKeyHandle;
914     ULONG AccountKeyBufferSize;
915     ULONG EnumIndex;
916     ULONG EnumCount;
917     ULONG RequiredLength;
918     ULONG DataLength;
919     ULONG i;
920     NTSTATUS Status = STATUS_SUCCESS;
921 
922     TRACE("LsarEnumerateAccount(%p %p %p %lu)\n",
923           PolicyHandle, EnumerationContext, EnumerationBuffer, PreferedMaximumLength);
924 
925     if (EnumerationContext == NULL ||
926         EnumerationBuffer == NULL)
927         return STATUS_INVALID_PARAMETER;
928 
929     EnumerationBuffer->EntriesRead = 0;
930     EnumerationBuffer->Information = NULL;
931 
932     /* Validate the PolicyHandle */
933     Status = LsapValidateDbObject(PolicyHandle,
934                                   LsaDbPolicyObject,
935                                   POLICY_VIEW_LOCAL_INFORMATION,
936                                   &PolicyObject);
937     if (!NT_SUCCESS(Status))
938     {
939         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
940         return Status;
941     }
942 
943     Status = LsapRegOpenKey(PolicyObject->KeyHandle,
944                             L"Accounts",
945                             KEY_READ,
946                             &AccountsKeyHandle);
947     if (!NT_SUCCESS(Status))
948         return Status;
949 
950     Status = LsapRegQueryKeyInfo(AccountsKeyHandle,
951                                  NULL,
952                                  &AccountKeyBufferSize,
953                                  NULL);
954     if (!NT_SUCCESS(Status))
955     {
956         ERR("LsapRegQueryKeyInfo returned 0x%08lx\n", Status);
957         return Status;
958     }
959 
960     AccountKeyBufferSize += sizeof(WCHAR);
961     AccountKeyBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AccountKeyBufferSize);
962     if (AccountKeyBuffer == NULL)
963     {
964         return STATUS_NO_MEMORY;
965     }
966 
967     EnumIndex = *EnumerationContext;
968     EnumCount = 0;
969     RequiredLength = 0;
970 
971     while (TRUE)
972     {
973         Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
974                                         EnumIndex,
975                                         AccountKeyBufferSize,
976                                         AccountKeyBuffer);
977         if (!NT_SUCCESS(Status))
978             break;
979 
980         TRACE("EnumIndex: %lu\n", EnumIndex);
981         TRACE("Account key name: %S\n", AccountKeyBuffer);
982 
983         Status = LsapRegOpenKey(AccountsKeyHandle,
984                                 AccountKeyBuffer,
985                                 KEY_READ,
986                                 &AccountKeyHandle);
987         TRACE("LsapRegOpenKey returned %08lX\n", Status);
988         if (NT_SUCCESS(Status))
989         {
990             Status = LsapRegOpenKey(AccountKeyHandle,
991                                     L"Sid",
992                                     KEY_READ,
993                                     &SidKeyHandle);
994             TRACE("LsapRegOpenKey returned %08lX\n", Status);
995             if (NT_SUCCESS(Status))
996             {
997                 DataLength = 0;
998                 Status = LsapRegQueryValue(SidKeyHandle,
999                                            NULL,
1000                                            NULL,
1001                                            NULL,
1002                                            &DataLength);
1003                 TRACE("LsapRegQueryValue returned %08lX\n", Status);
1004                 if (NT_SUCCESS(Status))
1005                 {
1006                     TRACE("Data length: %lu\n", DataLength);
1007 
1008                     if ((RequiredLength + DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION)) > PreferedMaximumLength)
1009                         break;
1010 
1011                     RequiredLength += (DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION));
1012                     EnumCount++;
1013                 }
1014 
1015                 LsapRegCloseKey(SidKeyHandle);
1016             }
1017 
1018             LsapRegCloseKey(AccountKeyHandle);
1019         }
1020 
1021         EnumIndex++;
1022     }
1023 
1024     TRACE("EnumCount: %lu\n", EnumCount);
1025     TRACE("RequiredLength: %lu\n", RequiredLength);
1026 
1027     EnumBuffer.EntriesRead = EnumCount;
1028     EnumBuffer.Information = midl_user_allocate(EnumCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
1029     if (EnumBuffer.Information == NULL)
1030     {
1031         Status = STATUS_INSUFFICIENT_RESOURCES;
1032         goto done;
1033     }
1034 
1035     EnumIndex = *EnumerationContext;
1036     for (i = 0; i < EnumCount; i++, EnumIndex++)
1037     {
1038         Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
1039                                         EnumIndex,
1040                                         AccountKeyBufferSize,
1041                                         AccountKeyBuffer);
1042         if (!NT_SUCCESS(Status))
1043             break;
1044 
1045         TRACE("EnumIndex: %lu\n", EnumIndex);
1046         TRACE("Account key name: %S\n", AccountKeyBuffer);
1047 
1048         Status = LsapRegOpenKey(AccountsKeyHandle,
1049                                 AccountKeyBuffer,
1050                                 KEY_READ,
1051                                 &AccountKeyHandle);
1052         TRACE("LsapRegOpenKey returned %08lX\n", Status);
1053         if (NT_SUCCESS(Status))
1054         {
1055             Status = LsapRegOpenKey(AccountKeyHandle,
1056                                     L"Sid",
1057                                     KEY_READ,
1058                                     &SidKeyHandle);
1059             TRACE("LsapRegOpenKey returned %08lX\n", Status);
1060             if (NT_SUCCESS(Status))
1061             {
1062                 DataLength = 0;
1063                 Status = LsapRegQueryValue(SidKeyHandle,
1064                                            NULL,
1065                                            NULL,
1066                                            NULL,
1067                                            &DataLength);
1068                 TRACE("LsapRegQueryValue returned %08lX\n", Status);
1069                 if (NT_SUCCESS(Status))
1070                 {
1071                     EnumBuffer.Information[i].Sid = midl_user_allocate(DataLength);
1072                     if (EnumBuffer.Information[i].Sid == NULL)
1073                     {
1074                         LsapRegCloseKey(AccountKeyHandle);
1075                         Status = STATUS_INSUFFICIENT_RESOURCES;
1076                         goto done;
1077                     }
1078 
1079                     Status = LsapRegQueryValue(SidKeyHandle,
1080                                                NULL,
1081                                                NULL,
1082                                                EnumBuffer.Information[i].Sid,
1083                                                &DataLength);
1084                     TRACE("SampRegQueryValue returned %08lX\n", Status);
1085                 }
1086 
1087                 LsapRegCloseKey(SidKeyHandle);
1088             }
1089 
1090             LsapRegCloseKey(AccountKeyHandle);
1091 
1092             if (!NT_SUCCESS(Status))
1093                 goto done;
1094         }
1095     }
1096 
1097     if (NT_SUCCESS(Status))
1098     {
1099         *EnumerationContext += EnumCount;
1100         EnumerationBuffer->EntriesRead = EnumBuffer.EntriesRead;
1101         EnumerationBuffer->Information = EnumBuffer.Information;
1102     }
1103 
1104 done:
1105     if (!NT_SUCCESS(Status))
1106     {
1107         if (EnumBuffer.Information)
1108         {
1109             for (i = 0; i < EnumBuffer.EntriesRead; i++)
1110             {
1111                 if (EnumBuffer.Information[i].Sid != NULL)
1112                     midl_user_free(EnumBuffer.Information[i].Sid);
1113             }
1114 
1115             midl_user_free(EnumBuffer.Information);
1116         }
1117     }
1118 
1119     if (AccountKeyBuffer != NULL)
1120         RtlFreeHeap(RtlGetProcessHeap(), 0, AccountKeyBuffer);
1121 
1122     if (AccountsKeyHandle != NULL)
1123         LsapRegCloseKey(AccountsKeyHandle);
1124 
1125     return Status;
1126 }
1127 
1128 
1129 /* Function 12 */
1130 NTSTATUS WINAPI LsarCreateTrustedDomain(
1131     LSAPR_HANDLE PolicyHandle,
1132     PLSAPR_TRUST_INFORMATION TrustedDomainInformation,
1133     ACCESS_MASK DesiredAccess,
1134     LSAPR_HANDLE *TrustedDomainHandle)
1135 {
1136     /* FIXME: We are not running an AD yet */
1137     return STATUS_DIRECTORY_SERVICE_REQUIRED;
1138 }
1139 
1140 
1141 /* Function 13 */
1142 NTSTATUS WINAPI LsarEnumerateTrustedDomains(
1143     LSAPR_HANDLE PolicyHandle,
1144     DWORD *EnumerationContext,
1145     PLSAPR_TRUSTED_ENUM_BUFFER EnumerationBuffer,
1146     DWORD PreferedMaximumLength)
1147 {
1148     /* FIXME: We are not running an AD yet */
1149     EnumerationBuffer->EntriesRead = 0;
1150     EnumerationBuffer->Information = NULL;
1151     return STATUS_NO_MORE_ENTRIES;
1152 }
1153 
1154 
1155 /* Function 14 */
1156 NTSTATUS WINAPI LsarLookupNames(
1157     LSAPR_HANDLE PolicyHandle,
1158     DWORD Count,
1159     PRPC_UNICODE_STRING Names,
1160     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1161     PLSAPR_TRANSLATED_SIDS TranslatedSids,
1162     LSAP_LOOKUP_LEVEL LookupLevel,
1163     DWORD *MappedCount)
1164 {
1165     LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2;
1166     ULONG i;
1167     NTSTATUS Status;
1168 
1169     TRACE("LsarLookupNames(%p %lu %p %p %p %d %p)\n",
1170           PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
1171           LookupLevel, MappedCount);
1172 
1173     TranslatedSids->Entries = 0;
1174     TranslatedSids->Sids = NULL;
1175     *ReferencedDomains = NULL;
1176 
1177     if (Count == 0)
1178         return STATUS_NONE_MAPPED;
1179 
1180     TranslatedSidsEx2.Entries = 0;
1181     TranslatedSidsEx2.Sids = NULL;
1182 
1183     Status = LsapLookupNames(Count,
1184                              Names,
1185                              ReferencedDomains,
1186                              &TranslatedSidsEx2,
1187                              LookupLevel,
1188                              MappedCount,
1189                              0,
1190                              0);
1191     if (!NT_SUCCESS(Status))
1192         return Status;
1193 
1194     TranslatedSids->Entries = TranslatedSidsEx2.Entries;
1195     TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID));
1196     if (TranslatedSids->Sids == NULL)
1197     {
1198         MIDL_user_free(TranslatedSidsEx2.Sids);
1199         MIDL_user_free(*ReferencedDomains);
1200         *ReferencedDomains = NULL;
1201         return STATUS_INSUFFICIENT_RESOURCES;
1202     }
1203 
1204     for (i = 0; i < TranslatedSidsEx2.Entries; i++)
1205     {
1206         TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use;
1207         TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid);
1208         TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex;
1209     }
1210 
1211     MIDL_user_free(TranslatedSidsEx2.Sids);
1212 
1213     return STATUS_SUCCESS;
1214 }
1215 
1216 
1217 /* Function 15 */
1218 NTSTATUS WINAPI LsarLookupSids(
1219     LSAPR_HANDLE PolicyHandle,
1220     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
1221     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1222     PLSAPR_TRANSLATED_NAMES TranslatedNames,
1223     LSAP_LOOKUP_LEVEL LookupLevel,
1224     DWORD *MappedCount)
1225 {
1226     LSAPR_TRANSLATED_NAMES_EX TranslatedNamesEx;
1227     ULONG i;
1228     NTSTATUS Status;
1229 
1230     TRACE("LsarLookupSids(%p %p %p %p %d %p)\n",
1231           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
1232           LookupLevel, MappedCount);
1233 
1234     /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
1235 
1236     TranslatedNames->Entries = SidEnumBuffer->Entries;
1237     TranslatedNames->Names = NULL;
1238     *ReferencedDomains = NULL;
1239 
1240     TranslatedNamesEx.Entries = SidEnumBuffer->Entries;
1241     TranslatedNamesEx.Names = NULL;
1242 
1243     Status = LsapLookupSids(SidEnumBuffer,
1244                             ReferencedDomains,
1245                             &TranslatedNamesEx,
1246                             LookupLevel,
1247                             MappedCount,
1248                             0,
1249                             0);
1250     if (!NT_SUCCESS(Status))
1251         return Status;
1252 
1253     TranslatedNames->Entries = SidEnumBuffer->Entries;
1254     TranslatedNames->Names = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME));
1255     if (TranslatedNames->Names == NULL)
1256     {
1257         MIDL_user_free(TranslatedNamesEx.Names);
1258         MIDL_user_free(*ReferencedDomains);
1259         *ReferencedDomains = NULL;
1260         return STATUS_INSUFFICIENT_RESOURCES;
1261     }
1262 
1263     for (i = 0; i < TranslatedNamesEx.Entries; i++)
1264     {
1265         TranslatedNames->Names[i].Use = TranslatedNamesEx.Names[i].Use;
1266         TranslatedNames->Names[i].Name.Length = TranslatedNamesEx.Names[i].Name.Length;
1267         TranslatedNames->Names[i].Name.MaximumLength = TranslatedNamesEx.Names[i].Name.MaximumLength;
1268         TranslatedNames->Names[i].Name.Buffer = TranslatedNamesEx.Names[i].Name.Buffer;
1269         TranslatedNames->Names[i].DomainIndex = TranslatedNamesEx.Names[i].DomainIndex;
1270     }
1271 
1272     MIDL_user_free(TranslatedNamesEx.Names);
1273 
1274     return Status;
1275 }
1276 
1277 
1278 /* Function 16 */
1279 NTSTATUS WINAPI LsarCreateSecret(
1280     LSAPR_HANDLE PolicyHandle,
1281     PRPC_UNICODE_STRING SecretName,
1282     ACCESS_MASK DesiredAccess,
1283     LSAPR_HANDLE *SecretHandle)
1284 {
1285     PLSA_DB_OBJECT PolicyObject;
1286     PLSA_DB_OBJECT SecretObject = NULL;
1287     LARGE_INTEGER Time;
1288     PSECURITY_DESCRIPTOR SecretSd = NULL;
1289     ULONG SecretSdSize;
1290     NTSTATUS Status = STATUS_SUCCESS;
1291 
1292     TRACE("LsarCreateSecret(%p %wZ %lx %p)\n",
1293           PolicyHandle, SecretName, DesiredAccess, SecretHandle);
1294 
1295     /* Validate the PolicyHandle */
1296     Status = LsapValidateDbObject(PolicyHandle,
1297                                   LsaDbPolicyObject,
1298                                   POLICY_CREATE_SECRET,
1299                                   &PolicyObject);
1300     if (!NT_SUCCESS(Status))
1301     {
1302         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
1303         return Status;
1304     }
1305 
1306     /* Get the current time */
1307     Status = NtQuerySystemTime(&Time);
1308     if (!NT_SUCCESS(Status))
1309     {
1310         ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
1311         goto done;
1312     }
1313 
1314     /* Create a security descriptor for the secret */
1315     Status = LsapCreateSecretSd(&SecretSd,
1316                                 &SecretSdSize);
1317     if (!NT_SUCCESS(Status))
1318     {
1319         ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
1320         return Status;
1321     }
1322 
1323     /* Create the Secret object */
1324     Status = LsapCreateDbObject(PolicyObject,
1325                                 L"Secrets",
1326                                 SecretName->Buffer,
1327                                 LsaDbSecretObject,
1328                                 DesiredAccess,
1329                                 PolicyObject->Trusted,
1330                                 &SecretObject);
1331     if (!NT_SUCCESS(Status))
1332     {
1333         ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
1334         goto done;
1335     }
1336 
1337     /* Set the CurrentTime attribute */
1338     Status = LsapSetObjectAttribute(SecretObject,
1339                                     L"CurrentTime",
1340                                     (PVOID)&Time,
1341                                     sizeof(LARGE_INTEGER));
1342     if (!NT_SUCCESS(Status))
1343     {
1344         ERR("LsapSetObjectAttribute (CurrentTime) failed (Status 0x%08lx)\n", Status);
1345         goto done;
1346     }
1347 
1348     /* Set the OldTime attribute */
1349     Status = LsapSetObjectAttribute(SecretObject,
1350                                     L"OldTime",
1351                                     (PVOID)&Time,
1352                                     sizeof(LARGE_INTEGER));
1353     if (!NT_SUCCESS(Status))
1354     {
1355         ERR("LsapSetObjectAttribute (OldTime) failed (Status 0x%08lx)\n", Status);
1356         goto done;
1357     }
1358 
1359     /* Set the SecDesc attribute */
1360     Status = LsapSetObjectAttribute(SecretObject,
1361                                     L"SecDesc",
1362                                     SecretSd,
1363                                     SecretSdSize);
1364 
1365 done:
1366     if (SecretSd != NULL)
1367         RtlFreeHeap(RtlGetProcessHeap(), 0, SecretSd);
1368 
1369     if (!NT_SUCCESS(Status))
1370     {
1371         if (SecretObject != NULL)
1372             LsapCloseDbObject(SecretObject);
1373     }
1374     else
1375     {
1376         *SecretHandle = (LSAPR_HANDLE)SecretObject;
1377     }
1378 
1379     return STATUS_SUCCESS;
1380 }
1381 
1382 
1383 static
1384 NTSTATUS
1385 LsarpOpenAccount(
1386     IN PLSA_DB_OBJECT PolicyObject,
1387     IN PRPC_SID AccountSid,
1388     IN ACCESS_MASK DesiredAccess,
1389     OUT PLSA_DB_OBJECT *AccountObject)
1390 {
1391     LPWSTR SidString = NULL;
1392     NTSTATUS Status = STATUS_SUCCESS;
1393 
1394     /* Create SID string */
1395     if (!ConvertSidToStringSid((PSID)AccountSid,
1396                                &SidString))
1397     {
1398         ERR("ConvertSidToStringSid failed\n");
1399         return STATUS_INVALID_PARAMETER;
1400     }
1401 
1402     /* Create the Account object */
1403     Status = LsapOpenDbObject(PolicyObject,
1404                               L"Accounts",
1405                               SidString,
1406                               LsaDbAccountObject,
1407                               DesiredAccess,
1408                               PolicyObject->Trusted,
1409                               AccountObject);
1410     if (!NT_SUCCESS(Status))
1411     {
1412         ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
1413     }
1414 
1415     if (SidString != NULL)
1416         LocalFree(SidString);
1417 
1418     return Status;
1419 }
1420 
1421 
1422 /* Function 17 */
1423 NTSTATUS WINAPI LsarOpenAccount(
1424     LSAPR_HANDLE PolicyHandle,
1425     PRPC_SID AccountSid,
1426     ACCESS_MASK DesiredAccess,
1427     LSAPR_HANDLE *AccountHandle)
1428 {
1429     PLSA_DB_OBJECT PolicyObject;
1430     NTSTATUS Status;
1431 
1432     TRACE("LsarOpenAccount(%p %p %lx %p)\n",
1433           PolicyHandle, AccountSid, DesiredAccess, AccountHandle);
1434 
1435     /* Validate the AccountSid */
1436     if (!RtlValidSid(AccountSid))
1437         return STATUS_INVALID_PARAMETER;
1438 
1439     /* Validate the PolicyHandle */
1440     Status = LsapValidateDbObject(PolicyHandle,
1441                                   LsaDbPolicyObject,
1442                                   0,
1443                                   &PolicyObject);
1444     if (!NT_SUCCESS(Status))
1445     {
1446         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
1447         return Status;
1448     }
1449 
1450 
1451     /* Open the Account object */
1452     return LsarpOpenAccount(PolicyObject,
1453                             AccountSid,
1454                             DesiredAccess,
1455                             (PLSA_DB_OBJECT *)AccountHandle);
1456 }
1457 
1458 
1459 /* Function 18 */
1460 NTSTATUS WINAPI LsarEnumeratePrivilegesAccount(
1461     LSAPR_HANDLE AccountHandle,
1462     PLSAPR_PRIVILEGE_SET *Privileges)
1463 {
1464     PLSA_DB_OBJECT AccountObject;
1465     ULONG PrivilegeSetSize = 0;
1466     PLSAPR_PRIVILEGE_SET PrivilegeSet = NULL;
1467     NTSTATUS Status;
1468 
1469     TRACE("LsarEnumeratePrivilegesAccount(%p %p)\n",
1470           AccountHandle, Privileges);
1471 
1472     *Privileges = NULL;
1473 
1474     /* Validate the AccountHandle */
1475     Status = LsapValidateDbObject(AccountHandle,
1476                                   LsaDbAccountObject,
1477                                   ACCOUNT_VIEW,
1478                                   &AccountObject);
1479     if (!NT_SUCCESS(Status))
1480     {
1481         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
1482         return Status;
1483     }
1484 
1485     /* Get the size of the privilege set */
1486     Status = LsapGetObjectAttribute(AccountObject,
1487                                     L"Privilgs",
1488                                     NULL,
1489                                     &PrivilegeSetSize);
1490     if (!NT_SUCCESS(Status))
1491         return Status;
1492 
1493     /* Allocate a buffer for the privilege set */
1494     PrivilegeSet = MIDL_user_allocate(PrivilegeSetSize);
1495     if (PrivilegeSet == NULL)
1496         return STATUS_NO_MEMORY;
1497 
1498     /* Get the privilege set */
1499     Status = LsapGetObjectAttribute(AccountObject,
1500                                     L"Privilgs",
1501                                     PrivilegeSet,
1502                                     &PrivilegeSetSize);
1503     if (!NT_SUCCESS(Status))
1504     {
1505         MIDL_user_free(PrivilegeSet);
1506         return Status;
1507     }
1508 
1509     /* Return a pointer to the privilege set */
1510     *Privileges = PrivilegeSet;
1511 
1512     return STATUS_SUCCESS;
1513 }
1514 
1515 
1516 /* Function 19 */
1517 NTSTATUS WINAPI LsarAddPrivilegesToAccount(
1518     LSAPR_HANDLE AccountHandle,
1519     PLSAPR_PRIVILEGE_SET Privileges)
1520 {
1521     PLSA_DB_OBJECT AccountObject;
1522     PPRIVILEGE_SET CurrentPrivileges = NULL;
1523     PPRIVILEGE_SET NewPrivileges = NULL;
1524     ULONG PrivilegeSetSize = 0;
1525     ULONG PrivilegeCount;
1526     ULONG i, j;
1527     BOOL bFound;
1528     NTSTATUS Status;
1529 
1530     TRACE("LsarAddPrivilegesToAccount(%p %p)\n",
1531           AccountHandle, Privileges);
1532 
1533     /* Validate the AccountHandle */
1534     Status = LsapValidateDbObject(AccountHandle,
1535                                   LsaDbAccountObject,
1536                                   ACCOUNT_ADJUST_PRIVILEGES,
1537                                   &AccountObject);
1538     if (!NT_SUCCESS(Status))
1539     {
1540         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
1541         return Status;
1542     }
1543 
1544     /* Get the size of the Privilgs attribute */
1545     Status = LsapGetObjectAttribute(AccountObject,
1546                                     L"Privilgs",
1547                                     NULL,
1548                                     &PrivilegeSetSize);
1549     if (!NT_SUCCESS(Status) || PrivilegeSetSize == 0)
1550     {
1551         /* The Privilgs attribute does not exist */
1552 
1553         PrivilegeSetSize = sizeof(PRIVILEGE_SET) +
1554                            (Privileges->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
1555         Status = LsapSetObjectAttribute(AccountObject,
1556                                         L"Privilgs",
1557                                         Privileges,
1558                                         PrivilegeSetSize);
1559     }
1560     else
1561     {
1562         /* The Privilgs attribute exists */
1563 
1564         /* Allocate memory for the stored privilege set */
1565         CurrentPrivileges = MIDL_user_allocate(PrivilegeSetSize);
1566         if (CurrentPrivileges == NULL)
1567             return STATUS_NO_MEMORY;
1568 
1569         /* Get the current privilege set */
1570         Status = LsapGetObjectAttribute(AccountObject,
1571                                         L"Privilgs",
1572                                         CurrentPrivileges,
1573                                         &PrivilegeSetSize);
1574         if (!NT_SUCCESS(Status))
1575         {
1576             TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
1577             goto done;
1578         }
1579 
1580         PrivilegeCount = CurrentPrivileges->PrivilegeCount;
1581         TRACE("Current privilege count: %lu\n", PrivilegeCount);
1582 
1583         /* Calculate the number of privileges in the combined privilege set */
1584         for (i = 0; i < Privileges->PrivilegeCount; i++)
1585         {
1586             bFound = FALSE;
1587             for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++)
1588             {
1589                 if (RtlEqualLuid(&(Privileges->Privilege[i].Luid),
1590                                  &(CurrentPrivileges->Privilege[i].Luid)))
1591                 {
1592                     bFound = TRUE;
1593                     break;
1594                 }
1595             }
1596 
1597             if (bFound == FALSE)
1598             {
1599                 TRACE("Found new privilege\n");
1600                 PrivilegeCount++;
1601             }
1602         }
1603         TRACE("New privilege count: %lu\n", PrivilegeCount);
1604 
1605         /* Calculate the size of the new privilege set and allocate it */
1606         PrivilegeSetSize = sizeof(PRIVILEGE_SET) +
1607                            (PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
1608         NewPrivileges = MIDL_user_allocate(PrivilegeSetSize);
1609         if (NewPrivileges == NULL)
1610         {
1611             Status = STATUS_NO_MEMORY;
1612             goto done;
1613         }
1614 
1615         /* Initialize the new privilege set */
1616         NewPrivileges->PrivilegeCount = PrivilegeCount;
1617         NewPrivileges->Control = 0;
1618 
1619         /* Copy all privileges from the current privilege set */
1620         RtlCopyLuidAndAttributesArray(CurrentPrivileges->PrivilegeCount,
1621                                       &(CurrentPrivileges->Privilege[0]),
1622                                       &(NewPrivileges->Privilege[0]));
1623 
1624         /* Add new privileges to the new privilege set */
1625         PrivilegeCount = CurrentPrivileges->PrivilegeCount;
1626         for (i = 0; i < Privileges->PrivilegeCount; i++)
1627         {
1628             bFound = FALSE;
1629             for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++)
1630             {
1631                 if (RtlEqualLuid(&(Privileges->Privilege[i].Luid),
1632                                  &(CurrentPrivileges->Privilege[i].Luid)))
1633                 {
1634                     /* Overwrite attributes if a matching privilege was found */
1635                     NewPrivileges->Privilege[j].Attributes = Privileges->Privilege[i].Attributes;
1636 
1637                     bFound = TRUE;
1638                     break;
1639                 }
1640             }
1641 
1642             if (bFound == FALSE)
1643             {
1644                 /* Copy the new privilege */
1645                 RtlCopyLuidAndAttributesArray(1,
1646                                               (PLUID_AND_ATTRIBUTES)&(Privileges->Privilege[i]),
1647                                               &(NewPrivileges->Privilege[PrivilegeCount]));
1648                 PrivilegeCount++;
1649             }
1650         }
1651 
1652         /* Set the new privilege set */
1653         Status = LsapSetObjectAttribute(AccountObject,
1654                                         L"Privilgs",
1655                                         NewPrivileges,
1656                                         PrivilegeSetSize);
1657     }
1658 
1659 done:
1660     if (CurrentPrivileges != NULL)
1661         MIDL_user_free(CurrentPrivileges);
1662 
1663     if (NewPrivileges != NULL)
1664         MIDL_user_free(NewPrivileges);
1665 
1666     return Status;
1667 }
1668 
1669 
1670 /* Function 20 */
1671 NTSTATUS WINAPI LsarRemovePrivilegesFromAccount(
1672     LSAPR_HANDLE AccountHandle,
1673     BOOLEAN AllPrivileges,
1674     PLSAPR_PRIVILEGE_SET Privileges)
1675 {
1676     PLSA_DB_OBJECT AccountObject;
1677     PPRIVILEGE_SET CurrentPrivileges = NULL;
1678     PPRIVILEGE_SET NewPrivileges = NULL;
1679     ULONG PrivilegeSetSize = 0;
1680     ULONG PrivilegeCount;
1681     ULONG i, j, k;
1682     BOOL bFound;
1683     NTSTATUS Status;
1684 
1685     TRACE("LsarRemovePrivilegesFromAccount(%p %u %p)\n",
1686           AccountHandle, AllPrivileges, Privileges);
1687 
1688     /* */
1689     if (((AllPrivileges == FALSE) && (Privileges == NULL)) ||
1690         ((AllPrivileges != FALSE) && (Privileges != NULL)))
1691             return STATUS_INVALID_PARAMETER;
1692 
1693     /* Validate the AccountHandle */
1694     Status = LsapValidateDbObject(AccountHandle,
1695                                   LsaDbAccountObject,
1696                                   ACCOUNT_ADJUST_PRIVILEGES,
1697                                   &AccountObject);
1698     if (!NT_SUCCESS(Status))
1699     {
1700         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
1701         return Status;
1702     }
1703 
1704     if (AllPrivileges != FALSE)
1705     {
1706         /* Delete the Privilgs attribute */
1707         Status = LsapDeleteObjectAttribute(AccountObject,
1708                                            L"Privilgs");
1709         if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
1710             Status = STATUS_SUCCESS;
1711     }
1712     else
1713     {
1714         /* Get the size of the Privilgs attribute */
1715         Status = LsapGetObjectAttribute(AccountObject,
1716                                         L"Privilgs",
1717                                         NULL,
1718                                         &PrivilegeSetSize);
1719         if (!NT_SUCCESS(Status))
1720             goto done;
1721 
1722         /* Succeed, if there is no privilege set to remove privileges from */
1723         if (PrivilegeSetSize == 0)
1724         {
1725             Status = STATUS_SUCCESS;
1726             goto done;
1727         }
1728 
1729         /* Allocate memory for the stored privilege set */
1730         CurrentPrivileges = MIDL_user_allocate(PrivilegeSetSize);
1731         if (CurrentPrivileges == NULL)
1732             return STATUS_NO_MEMORY;
1733 
1734         /* Get the current privilege set */
1735         Status = LsapGetObjectAttribute(AccountObject,
1736                                         L"Privilgs",
1737                                         CurrentPrivileges,
1738                                         &PrivilegeSetSize);
1739         if (!NT_SUCCESS(Status))
1740         {
1741             TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
1742             goto done;
1743         }
1744 
1745         PrivilegeCount = CurrentPrivileges->PrivilegeCount;
1746         TRACE("Current privilege count: %lu\n", PrivilegeCount);
1747 
1748         /* Calculate the number of privileges in the new privilege set */
1749         for (i = 0; i < CurrentPrivileges->PrivilegeCount; i++)
1750         {
1751             for (j = 0; j < Privileges->PrivilegeCount; j++)
1752             {
1753                 if (RtlEqualLuid(&(CurrentPrivileges->Privilege[i].Luid),
1754                                  &(Privileges->Privilege[j].Luid)))
1755                 {
1756                     if (PrivilegeCount > 0)
1757                         PrivilegeCount--;
1758                 }
1759             }
1760         }
1761         TRACE("New privilege count: %lu\n", PrivilegeCount);
1762 
1763         if (PrivilegeCount == 0)
1764         {
1765             /* Delete the Privilgs attribute */
1766             Status = LsapDeleteObjectAttribute(AccountObject,
1767                                                L"Privilgs");
1768             if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
1769                 Status = STATUS_SUCCESS;
1770         }
1771         else
1772         {
1773             /* Calculate the size of the new privilege set and allocate it */
1774             PrivilegeSetSize = sizeof(PRIVILEGE_SET) +
1775                                (PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
1776             NewPrivileges = MIDL_user_allocate(PrivilegeSetSize);
1777             if (NewPrivileges == NULL)
1778             {
1779                 Status = STATUS_NO_MEMORY;
1780                 goto done;
1781             }
1782 
1783             /* Initialize the new privilege set */
1784             NewPrivileges->PrivilegeCount = PrivilegeCount;
1785             NewPrivileges->Control = 0;
1786 
1787             /* Copy the privileges which are not to be removed */
1788             for (i = 0, k = 0; i < CurrentPrivileges->PrivilegeCount; i++)
1789             {
1790                 bFound = FALSE;
1791                 for (j = 0; j < Privileges->PrivilegeCount; j++)
1792                 {
1793                     if (RtlEqualLuid(&(CurrentPrivileges->Privilege[i].Luid),
1794                                      &(Privileges->Privilege[j].Luid)))
1795                         bFound = TRUE;
1796                 }
1797 
1798                 if (bFound == FALSE)
1799                 {
1800                     /* Copy the privilege */
1801                     RtlCopyLuidAndAttributesArray(1,
1802                                                   &(CurrentPrivileges->Privilege[i]),
1803                                                   &(NewPrivileges->Privilege[k]));
1804                     k++;
1805                 }
1806             }
1807 
1808             /* Set the new privilege set */
1809             Status = LsapSetObjectAttribute(AccountObject,
1810                                             L"Privilgs",
1811                                             NewPrivileges,
1812                                             PrivilegeSetSize);
1813         }
1814     }
1815 
1816 done:
1817     if (CurrentPrivileges != NULL)
1818         MIDL_user_free(CurrentPrivileges);
1819 
1820     if (NewPrivileges != NULL)
1821         MIDL_user_free(NewPrivileges);
1822 
1823     return Status;
1824 }
1825 
1826 
1827 /* Function 21 */
1828 NTSTATUS WINAPI LsarGetQuotasForAccount(
1829     LSAPR_HANDLE AccountHandle,
1830     PQUOTA_LIMITS QuotaLimits)
1831 {
1832     PLSA_DB_OBJECT AccountObject;
1833     ULONG Size;
1834     NTSTATUS Status;
1835 
1836     TRACE("LsarGetQuotasForAccount(%p %p)\n",
1837           AccountHandle, QuotaLimits);
1838 
1839     /* Validate the account handle */
1840     Status = LsapValidateDbObject(AccountHandle,
1841                                   LsaDbAccountObject,
1842                                   ACCOUNT_VIEW,
1843                                   &AccountObject);
1844     if (!NT_SUCCESS(Status))
1845     {
1846         ERR("Invalid handle (Status %lx)\n", Status);
1847         return Status;
1848     }
1849 
1850     /* Get the quota attribute */
1851     Status = LsapGetObjectAttribute(AccountObject,
1852                                     L"DefQuota",
1853                                     QuotaLimits,
1854                                     &Size);
1855 
1856     return Status;
1857 }
1858 
1859 
1860 /* Function 22 */
1861 NTSTATUS WINAPI LsarSetQuotasForAccount(
1862     LSAPR_HANDLE AccountHandle,
1863     PQUOTA_LIMITS QuotaLimits)
1864 {
1865     PLSA_DB_OBJECT AccountObject;
1866     QUOTA_LIMITS InternalQuotaLimits;
1867     ULONG Size;
1868     NTSTATUS Status;
1869 
1870     TRACE("LsarSetQuotasForAccount(%p %p)\n",
1871           AccountHandle, QuotaLimits);
1872 
1873     /* Validate the account handle */
1874     Status = LsapValidateDbObject(AccountHandle,
1875                                   LsaDbAccountObject,
1876                                   ACCOUNT_ADJUST_QUOTAS,
1877                                   &AccountObject);
1878     if (!NT_SUCCESS(Status))
1879     {
1880         ERR("Invalid handle (Status %lx)\n", Status);
1881         return Status;
1882     }
1883 
1884     /* Get the quota limits attribute */
1885     Size = sizeof(QUOTA_LIMITS);
1886     Status = LsapGetObjectAttribute(AccountObject,
1887                                     L"DefQuota",
1888                                     &InternalQuotaLimits,
1889                                     &Size);
1890     if (!NT_SUCCESS(Status))
1891     {
1892         TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
1893         return Status;
1894     }
1895 
1896     /* Update the quota limits */
1897     if (QuotaLimits->PagedPoolLimit != 0)
1898         InternalQuotaLimits.PagedPoolLimit = QuotaLimits->PagedPoolLimit;
1899 
1900     if (QuotaLimits->NonPagedPoolLimit != 0)
1901         InternalQuotaLimits.NonPagedPoolLimit = QuotaLimits->NonPagedPoolLimit;
1902 
1903     if (QuotaLimits->MinimumWorkingSetSize != 0)
1904         InternalQuotaLimits.MinimumWorkingSetSize = QuotaLimits->MinimumWorkingSetSize;
1905 
1906     if (QuotaLimits->MaximumWorkingSetSize != 0)
1907         InternalQuotaLimits.MaximumWorkingSetSize = QuotaLimits->MaximumWorkingSetSize;
1908 
1909     if (QuotaLimits->PagefileLimit != 0)
1910         InternalQuotaLimits.PagefileLimit = QuotaLimits->PagefileLimit;
1911 
1912     /* Set the quota limits attribute */
1913     Status = LsapSetObjectAttribute(AccountObject,
1914                                     L"DefQuota",
1915                                     &InternalQuotaLimits,
1916                                     sizeof(QUOTA_LIMITS));
1917 
1918     return Status;
1919 }
1920 
1921 
1922 /* Function 23 */
1923 NTSTATUS WINAPI LsarGetSystemAccessAccount(
1924     LSAPR_HANDLE AccountHandle,
1925     ACCESS_MASK *SystemAccess)
1926 {
1927     PLSA_DB_OBJECT AccountObject;
1928     ULONG Size = sizeof(ACCESS_MASK);
1929     NTSTATUS Status;
1930 
1931     TRACE("LsarGetSystemAccessAccount(%p %p)\n",
1932           AccountHandle, SystemAccess);
1933 
1934     /* Validate the account handle */
1935     Status = LsapValidateDbObject(AccountHandle,
1936                                   LsaDbAccountObject,
1937                                   ACCOUNT_VIEW,
1938                                   &AccountObject);
1939     if (!NT_SUCCESS(Status))
1940     {
1941         ERR("Invalid handle (Status %lx)\n", Status);
1942         return Status;
1943     }
1944 
1945     /* Get the system access flags */
1946     Status = LsapGetObjectAttribute(AccountObject,
1947                                     L"ActSysAc",
1948                                     SystemAccess,
1949                                     &Size);
1950 
1951     return Status;
1952 }
1953 
1954 
1955 /* Function 24 */
1956 NTSTATUS WINAPI LsarSetSystemAccessAccount(
1957     LSAPR_HANDLE AccountHandle,
1958     ACCESS_MASK SystemAccess)
1959 {
1960     PLSA_DB_OBJECT AccountObject;
1961     NTSTATUS Status;
1962 
1963     TRACE("LsarSetSystemAccessAccount(%p %lx)\n",
1964           AccountHandle, SystemAccess);
1965 
1966     /* Validate the account handle */
1967     Status = LsapValidateDbObject(AccountHandle,
1968                                   LsaDbAccountObject,
1969                                   ACCOUNT_ADJUST_SYSTEM_ACCESS,
1970                                   &AccountObject);
1971     if (!NT_SUCCESS(Status))
1972     {
1973         ERR("Invalid handle (Status %lx)\n", Status);
1974         return Status;
1975     }
1976 
1977     /* Set the system access flags */
1978     Status = LsapSetObjectAttribute(AccountObject,
1979                                     L"ActSysAc",
1980                                     &SystemAccess,
1981                                     sizeof(ACCESS_MASK));
1982 
1983     return Status;
1984 }
1985 
1986 
1987 /* Function 25 */
1988 NTSTATUS WINAPI LsarOpenTrustedDomain(
1989     LSAPR_HANDLE PolicyHandle,
1990     PRPC_SID TrustedDomainSid,
1991     ACCESS_MASK DesiredAccess,
1992     LSAPR_HANDLE *TrustedDomainHandle)
1993 {
1994     UNIMPLEMENTED;
1995     return STATUS_NOT_IMPLEMENTED;
1996 }
1997 
1998 
1999 /* Function 26 */
2000 NTSTATUS WINAPI LsarQueryInfoTrustedDomain(
2001     LSAPR_HANDLE TrustedDomainHandle,
2002     TRUSTED_INFORMATION_CLASS InformationClass,
2003     PLSAPR_TRUSTED_DOMAIN_INFO *TrustedDomainInformation)
2004 {
2005     UNIMPLEMENTED;
2006     return STATUS_NOT_IMPLEMENTED;
2007 }
2008 
2009 
2010 /* Function 27 */
2011 NTSTATUS WINAPI LsarSetInformationTrustedDomain(
2012     LSAPR_HANDLE TrustedDomainHandle,
2013     TRUSTED_INFORMATION_CLASS InformationClass,
2014     PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainInformation)
2015 {
2016     UNIMPLEMENTED;
2017     return STATUS_NOT_IMPLEMENTED;
2018 }
2019 
2020 
2021 /* Function 28 */
2022 NTSTATUS WINAPI LsarOpenSecret(
2023     LSAPR_HANDLE PolicyHandle,
2024     PRPC_UNICODE_STRING SecretName,
2025     ACCESS_MASK DesiredAccess,
2026     LSAPR_HANDLE *SecretHandle)
2027 {
2028     PLSA_DB_OBJECT PolicyObject;
2029     PLSA_DB_OBJECT SecretObject = NULL;
2030     NTSTATUS Status = STATUS_SUCCESS;
2031 
2032     TRACE("LsarOpenSecret(%p %wZ %lx %p)\n",
2033           PolicyHandle, SecretName, DesiredAccess, SecretHandle);
2034 
2035     /* Validate the PolicyHandle */
2036     Status = LsapValidateDbObject(PolicyHandle,
2037                                   LsaDbPolicyObject,
2038                                   0,
2039                                   &PolicyObject);
2040     if (!NT_SUCCESS(Status))
2041     {
2042         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
2043         return Status;
2044     }
2045 
2046     /* Create the secret object */
2047     Status = LsapOpenDbObject(PolicyObject,
2048                               L"Secrets",
2049                               SecretName->Buffer,
2050                               LsaDbSecretObject,
2051                               DesiredAccess,
2052                               PolicyObject->Trusted,
2053                               &SecretObject);
2054     if (!NT_SUCCESS(Status))
2055     {
2056         ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
2057         goto done;
2058     }
2059 
2060 done:
2061     if (!NT_SUCCESS(Status))
2062     {
2063         if (SecretObject != NULL)
2064             LsapCloseDbObject(SecretObject);
2065     }
2066     else
2067     {
2068         *SecretHandle = (LSAPR_HANDLE)SecretObject;
2069     }
2070 
2071     return Status;
2072 }
2073 
2074 
2075 /* Function 29 */
2076 NTSTATUS WINAPI LsarSetSecret(
2077     LSAPR_HANDLE SecretHandle,
2078     PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue,
2079     PLSAPR_CR_CIPHER_VALUE EncryptedOldValue)
2080 {
2081     PLSA_DB_OBJECT SecretObject;
2082     PBYTE CurrentValue = NULL;
2083     PBYTE OldValue = NULL;
2084     ULONG CurrentValueLength = 0;
2085     ULONG OldValueLength = 0;
2086     LARGE_INTEGER Time;
2087     NTSTATUS Status;
2088 
2089     TRACE("LsarSetSecret(%p %p %p)\n", SecretHandle,
2090           EncryptedCurrentValue, EncryptedOldValue);
2091 
2092     /* Validate the SecretHandle */
2093     Status = LsapValidateDbObject(SecretHandle,
2094                                   LsaDbSecretObject,
2095                                   SECRET_SET_VALUE,
2096                                   &SecretObject);
2097     if (!NT_SUCCESS(Status))
2098     {
2099         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
2100         return Status;
2101     }
2102 
2103     if (EncryptedCurrentValue != NULL)
2104     {
2105         /* FIXME: Decrypt the current value */
2106         CurrentValue = EncryptedCurrentValue->Buffer;
2107         CurrentValueLength = EncryptedCurrentValue->MaximumLength;
2108     }
2109 
2110     /* Set the current value */
2111     Status = LsapSetObjectAttribute(SecretObject,
2112                                     L"CurrentValue",
2113                                     CurrentValue,
2114                                     CurrentValueLength);
2115     if (!NT_SUCCESS(Status))
2116     {
2117         ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
2118         goto done;
2119     }
2120 
2121     /* Get the current time */
2122     Status = NtQuerySystemTime(&Time);
2123     if (!NT_SUCCESS(Status))
2124     {
2125         ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
2126         goto done;
2127     }
2128 
2129     /* Set the current time */
2130     Status = LsapSetObjectAttribute(SecretObject,
2131                                     L"CurrentTime",
2132                                     &Time,
2133                                     sizeof(LARGE_INTEGER));
2134     if (!NT_SUCCESS(Status))
2135     {
2136         ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
2137         goto done;
2138     }
2139 
2140     if (EncryptedOldValue != NULL)
2141     {
2142         /* FIXME: Decrypt the old value */
2143         OldValue = EncryptedOldValue->Buffer;
2144         OldValueLength = EncryptedOldValue->MaximumLength;
2145     }
2146 
2147     /* Set the old value */
2148     Status = LsapSetObjectAttribute(SecretObject,
2149                                     L"OldValue",
2150                                     OldValue,
2151                                     OldValueLength);
2152     if (!NT_SUCCESS(Status))
2153     {
2154         ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
2155         goto done;
2156     }
2157 
2158     /* Set the old time */
2159     Status = LsapSetObjectAttribute(SecretObject,
2160                                     L"OldTime",
2161                                     &Time,
2162                                     sizeof(LARGE_INTEGER));
2163     if (!NT_SUCCESS(Status))
2164     {
2165         ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
2166     }
2167 
2168 done:
2169     return Status;
2170 }
2171 
2172 
2173 /* Function 30 */
2174 NTSTATUS WINAPI LsarQuerySecret(
2175     LSAPR_HANDLE SecretHandle,
2176     PLSAPR_CR_CIPHER_VALUE *EncryptedCurrentValue,
2177     PLARGE_INTEGER CurrentValueSetTime,
2178     PLSAPR_CR_CIPHER_VALUE *EncryptedOldValue,
2179     PLARGE_INTEGER OldValueSetTime)
2180 {
2181     PLSA_DB_OBJECT SecretObject;
2182     PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL;
2183     PLSAPR_CR_CIPHER_VALUE EncOldValue = NULL;
2184     PBYTE CurrentValue = NULL;
2185     PBYTE OldValue = NULL;
2186     ULONG CurrentValueLength = 0;
2187     ULONG OldValueLength = 0;
2188     ULONG BufferSize;
2189     NTSTATUS Status;
2190 
2191     TRACE("LsarQuerySecret(%p %p %p %p %p)\n", SecretHandle,
2192           EncryptedCurrentValue, CurrentValueSetTime,
2193           EncryptedOldValue, OldValueSetTime);
2194 
2195     /* Validate the SecretHandle */
2196     Status = LsapValidateDbObject(SecretHandle,
2197                                   LsaDbSecretObject,
2198                                   SECRET_QUERY_VALUE,
2199                                   &SecretObject);
2200     if (!NT_SUCCESS(Status))
2201     {
2202         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
2203         return Status;
2204     }
2205 
2206     if (EncryptedCurrentValue != NULL)
2207     {
2208         CurrentValueLength = 0;
2209 
2210         /* Get the size of the current value */
2211         Status = LsapGetObjectAttribute(SecretObject,
2212                                         L"CurrentValue",
2213                                         NULL,
2214                                         &CurrentValueLength);
2215         if (!NT_SUCCESS(Status))
2216             goto done;
2217 
2218         /* Allocate a buffer for the current value */
2219         CurrentValue = midl_user_allocate(CurrentValueLength);
2220         if (CurrentValue == NULL)
2221         {
2222             Status = STATUS_INSUFFICIENT_RESOURCES;
2223             goto done;
2224         }
2225 
2226         /* Get the current value */
2227         Status = LsapGetObjectAttribute(SecretObject,
2228                                         L"CurrentValue",
2229                                         CurrentValue,
2230                                         &CurrentValueLength);
2231         if (!NT_SUCCESS(Status))
2232             goto done;
2233 
2234         /* Allocate a buffer for the encrypted current value */
2235         EncCurrentValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE));
2236         if (EncCurrentValue == NULL)
2237         {
2238             Status = STATUS_INSUFFICIENT_RESOURCES;
2239             goto done;
2240         }
2241 
2242         /* FIXME: Encrypt the current value */
2243         EncCurrentValue->Length = (USHORT)(CurrentValueLength - sizeof(WCHAR));
2244         EncCurrentValue->MaximumLength = (USHORT)CurrentValueLength;
2245         EncCurrentValue->Buffer = (PBYTE)CurrentValue;
2246     }
2247 
2248     if (CurrentValueSetTime != NULL)
2249     {
2250         BufferSize = sizeof(LARGE_INTEGER);
2251 
2252         /* Get the current value time */
2253         Status = LsapGetObjectAttribute(SecretObject,
2254                                         L"CurrentTime",
2255                                         (PBYTE)CurrentValueSetTime,
2256                                         &BufferSize);
2257         if (!NT_SUCCESS(Status))
2258             goto done;
2259     }
2260 
2261     if (EncryptedOldValue != NULL)
2262     {
2263         OldValueLength = 0;
2264 
2265         /* Get the size of the old value */
2266         Status = LsapGetObjectAttribute(SecretObject,
2267                                         L"OldValue",
2268                                         NULL,
2269                                         &OldValueLength);
2270         if (!NT_SUCCESS(Status))
2271             goto done;
2272 
2273         /* Allocate a buffer for the old value */
2274         OldValue = midl_user_allocate(OldValueLength);
2275         if (OldValue == NULL)
2276         {
2277             Status = STATUS_INSUFFICIENT_RESOURCES;
2278             goto done;
2279         }
2280 
2281         /* Get the old value */
2282         Status = LsapGetObjectAttribute(SecretObject,
2283                                         L"OldValue",
2284                                         OldValue,
2285                                         &OldValueLength);
2286         if (!NT_SUCCESS(Status))
2287             goto done;
2288 
2289         /* Allocate a buffer for the encrypted old value */
2290         EncOldValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE) + OldValueLength);
2291         if (EncOldValue == NULL)
2292         {
2293             Status = STATUS_INSUFFICIENT_RESOURCES;
2294             goto done;
2295         }
2296 
2297         /* FIXME: Encrypt the old value */
2298         EncOldValue->Length = (USHORT)(OldValueLength - sizeof(WCHAR));
2299         EncOldValue->MaximumLength = (USHORT)OldValueLength;
2300         EncOldValue->Buffer = (PBYTE)OldValue;
2301     }
2302 
2303     if (OldValueSetTime != NULL)
2304     {
2305         BufferSize = sizeof(LARGE_INTEGER);
2306 
2307         /* Get the old value time */
2308         Status = LsapGetObjectAttribute(SecretObject,
2309                                         L"OldTime",
2310                                         (PBYTE)OldValueSetTime,
2311                                         &BufferSize);
2312         if (!NT_SUCCESS(Status))
2313             goto done;
2314     }
2315 
2316 
2317 done:
2318     if (NT_SUCCESS(Status))
2319     {
2320         if (EncryptedCurrentValue != NULL)
2321             *EncryptedCurrentValue = EncCurrentValue;
2322 
2323         if (EncryptedOldValue != NULL)
2324             *EncryptedOldValue = EncOldValue;
2325     }
2326     else
2327     {
2328         if (EncryptedCurrentValue != NULL)
2329             *EncryptedCurrentValue = NULL;
2330 
2331         if (EncryptedOldValue != NULL)
2332             *EncryptedOldValue = NULL;
2333 
2334         if (EncCurrentValue != NULL)
2335             midl_user_free(EncCurrentValue);
2336 
2337         if (EncOldValue != NULL)
2338             midl_user_free(EncOldValue);
2339 
2340         if (CurrentValue != NULL)
2341             midl_user_free(CurrentValue);
2342 
2343         if (OldValue != NULL)
2344             midl_user_free(OldValue);
2345     }
2346 
2347     TRACE("LsarQuerySecret done (Status 0x%08lx)\n", Status);
2348 
2349     return Status;
2350 }
2351 
2352 
2353 /* Function 31 */
2354 NTSTATUS WINAPI LsarLookupPrivilegeValue(
2355     LSAPR_HANDLE PolicyHandle,
2356     PRPC_UNICODE_STRING Name,
2357     PLUID Value)
2358 {
2359     PLUID pValue;
2360     NTSTATUS Status;
2361 
2362     TRACE("LsarLookupPrivilegeValue(%p, %wZ, %p)\n",
2363           PolicyHandle, Name, Value);
2364 
2365     Status = LsapValidateDbObject(PolicyHandle,
2366                                   LsaDbPolicyObject,
2367                                   POLICY_LOOKUP_NAMES,
2368                                   NULL);
2369     if (!NT_SUCCESS(Status))
2370     {
2371         ERR("Invalid handle (Status %lx)\n", Status);
2372         return Status;
2373     }
2374 
2375     TRACE("Privilege: %wZ\n", Name);
2376 
2377     pValue = LsarpLookupPrivilegeValue(Name);
2378     if (pValue == NULL)
2379         return STATUS_NO_SUCH_PRIVILEGE;
2380 
2381     RtlCopyLuid(Value, pValue);
2382 
2383     return STATUS_SUCCESS;
2384 }
2385 
2386 
2387 /* Function 32 */
2388 NTSTATUS WINAPI LsarLookupPrivilegeName(
2389     LSAPR_HANDLE PolicyHandle,
2390     PLUID Value,
2391     PRPC_UNICODE_STRING *Name)
2392 {
2393     NTSTATUS Status;
2394 
2395     TRACE("LsarLookupPrivilegeName(%p, %p, %p)\n",
2396           PolicyHandle, Value, Name);
2397 
2398     Status = LsapValidateDbObject(PolicyHandle,
2399                                   LsaDbPolicyObject,
2400                                   POLICY_LOOKUP_NAMES,
2401                                   NULL);
2402     if (!NT_SUCCESS(Status))
2403     {
2404         ERR("Invalid handle\n");
2405         return Status;
2406     }
2407 
2408     Status = LsarpLookupPrivilegeName(Value,
2409                                       Name);
2410 
2411     return Status;
2412 }
2413 
2414 
2415 /* Function 33 */
2416 NTSTATUS WINAPI LsarLookupPrivilegeDisplayName(
2417     LSAPR_HANDLE PolicyHandle,
2418     PRPC_UNICODE_STRING Name,
2419     USHORT ClientLanguage,
2420     USHORT ClientSystemDefaultLanguage,
2421     PRPC_UNICODE_STRING *DisplayName,
2422     USHORT *LanguageReturned)
2423 {
2424     NTSTATUS Status;
2425 
2426     TRACE("LsarLookupPrivilegeDisplayName(%p, %p, %u, %u, %p, %p)\n",
2427           PolicyHandle, Name, ClientLanguage, ClientSystemDefaultLanguage, DisplayName, LanguageReturned);
2428 
2429     Status = LsapValidateDbObject(PolicyHandle,
2430                                   LsaDbPolicyObject,
2431                                   POLICY_LOOKUP_NAMES,
2432                                   NULL);
2433     if (!NT_SUCCESS(Status))
2434     {
2435         ERR("Invalid handle\n");
2436         return Status;
2437     }
2438 
2439     Status = LsarpLookupPrivilegeDisplayName(Name,
2440                                              ClientLanguage,
2441                                              ClientSystemDefaultLanguage,
2442                                              DisplayName,
2443                                              LanguageReturned);
2444 
2445     return Status;
2446 }
2447 
2448 
2449 /* Function 34 */
2450 NTSTATUS WINAPI LsarDeleteObject(
2451     LSAPR_HANDLE *ObjectHandle)
2452 {
2453     PLSA_DB_OBJECT DbObject;
2454     NTSTATUS Status;
2455 
2456     TRACE("LsarDeleteObject(%p)\n", ObjectHandle);
2457 
2458     if (ObjectHandle == NULL)
2459         return STATUS_INVALID_PARAMETER;
2460 
2461     /* Validate the ObjectHandle */
2462     Status = LsapValidateDbObject(*ObjectHandle,
2463                                   LsaDbIgnoreObject,
2464                                   DELETE,
2465                                   &DbObject);
2466     if (!NT_SUCCESS(Status))
2467     {
2468         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
2469         return Status;
2470     }
2471 
2472     /* You cannot delete the policy object */
2473     if (DbObject->ObjectType == LsaDbPolicyObject)
2474         return STATUS_INVALID_PARAMETER;
2475 
2476     /* Delete the database object */
2477     Status = LsapDeleteDbObject(DbObject);
2478     if (!NT_SUCCESS(Status))
2479     {
2480         ERR("LsapDeleteDbObject returned 0x%08lx\n", Status);
2481         return Status;
2482     }
2483 
2484     /* Invalidate the object handle */
2485     *ObjectHandle = NULL;
2486 
2487     return STATUS_SUCCESS;
2488 }
2489 
2490 
2491 /* Function 35 */
2492 NTSTATUS WINAPI LsarEnumerateAccountsWithUserRight(
2493     LSAPR_HANDLE PolicyHandle,
2494     PRPC_UNICODE_STRING UserRight,
2495     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer)
2496 {
2497     PLSA_DB_OBJECT PolicyObject;
2498     ACCESS_MASK AccountRight = 0;
2499     PLUID Luid = NULL;
2500     ULONG AccountKeyBufferSize;
2501     PWSTR AccountKeyBuffer = NULL;
2502     HKEY AccountsKeyHandle = NULL;
2503     HKEY AccountKeyHandle = NULL;
2504     HKEY AttributeKeyHandle;
2505     ACCESS_MASK SystemAccess;
2506     PPRIVILEGE_SET PrivilegeSet;
2507     PLSAPR_ACCOUNT_INFORMATION EnumBuffer = NULL, ReturnBuffer;
2508     ULONG SubKeyCount = 0;
2509     ULONG EnumIndex, EnumCount;
2510     ULONG Size, i;
2511     BOOL Found;
2512     NTSTATUS Status;
2513 
2514     TRACE("LsarEnumerateAccountsWithUserRights(%p %wZ %p)\n",
2515           PolicyHandle, UserRight, EnumerationBuffer);
2516 
2517     /* Validate the privilege and account right names */
2518     if (UserRight != NULL)
2519     {
2520         Luid = LsarpLookupPrivilegeValue(UserRight);
2521         if (Luid == NULL)
2522         {
2523             AccountRight = LsapLookupAccountRightValue(UserRight);
2524             if (AccountRight == 0)
2525                 return STATUS_NO_SUCH_PRIVILEGE;
2526         }
2527     }
2528 
2529     if (EnumerationBuffer == NULL)
2530         return STATUS_INVALID_PARAMETER;
2531 
2532     EnumerationBuffer->EntriesRead = 0;
2533     EnumerationBuffer->Information = NULL;
2534 
2535     /* Validate the PolicyHandle */
2536     Status = LsapValidateDbObject(PolicyHandle,
2537                                   LsaDbPolicyObject,
2538                                   POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
2539                                   &PolicyObject);
2540     if (!NT_SUCCESS(Status))
2541     {
2542         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
2543         return Status;
2544     }
2545 
2546     Status = LsapRegOpenKey(PolicyObject->KeyHandle,
2547                             L"Accounts",
2548                             KEY_READ,
2549                             &AccountsKeyHandle);
2550     if (!NT_SUCCESS(Status))
2551     {
2552         ERR("LsapRegOpenKey returned 0x%08lx\n", Status);
2553         return Status;
2554     }
2555 
2556     Status = LsapRegQueryKeyInfo(AccountsKeyHandle,
2557                                  &SubKeyCount,
2558                                  &AccountKeyBufferSize,
2559                                  NULL);
2560     if (!NT_SUCCESS(Status))
2561     {
2562         ERR("LsapRegOpenKey returned 0x%08lx\n", Status);
2563         return Status;
2564     }
2565 
2566     AccountKeyBufferSize += sizeof(WCHAR);
2567     AccountKeyBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AccountKeyBufferSize);
2568     if (AccountKeyBuffer == NULL)
2569     {
2570         return STATUS_INSUFFICIENT_RESOURCES;
2571     }
2572 
2573     EnumBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2574                                  HEAP_ZERO_MEMORY,
2575                                  SubKeyCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
2576     if (EnumBuffer == NULL)
2577     {
2578         Status = STATUS_INSUFFICIENT_RESOURCES;
2579         goto done;
2580     }
2581 
2582     EnumCount = 0;
2583     EnumIndex = 0;
2584     while (TRUE)
2585     {
2586         Found = FALSE;
2587 
2588         Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
2589                                         EnumIndex,
2590                                         AccountKeyBufferSize,
2591                                         AccountKeyBuffer);
2592         if (!NT_SUCCESS(Status))
2593         {
2594             if (Status == STATUS_NO_MORE_ENTRIES)
2595                 Status = STATUS_SUCCESS;
2596             break;
2597         }
2598 
2599         TRACE("EnumIndex: %lu\n", EnumIndex);
2600         TRACE("Account key name: %S\n", AccountKeyBuffer);
2601 
2602         Status = LsapRegOpenKey(AccountsKeyHandle,
2603                                 AccountKeyBuffer,
2604                                 KEY_READ,
2605                                 &AccountKeyHandle);
2606         if (NT_SUCCESS(Status))
2607         {
2608             if (Luid != NULL || AccountRight != 0)
2609             {
2610                 Status = LsapRegOpenKey(AccountKeyHandle,
2611                                         (Luid != NULL) ? L"Privilgs" : L"ActSysAc",
2612                                         KEY_READ,
2613                                         &AttributeKeyHandle);
2614                 if (NT_SUCCESS(Status))
2615                 {
2616                     if (Luid != NULL)
2617                     {
2618                         Size = 0;
2619                         LsapRegQueryValue(AttributeKeyHandle,
2620                                           NULL,
2621                                           NULL,
2622                                           NULL,
2623                                           &Size);
2624                         if (Size != 0)
2625                         {
2626                             PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
2627                             if (PrivilegeSet)
2628                             {
2629                                 if (LsapRegQueryValue(AttributeKeyHandle,
2630                                                       NULL,
2631                                                       NULL,
2632                                                       PrivilegeSet,
2633                                                       &Size) == STATUS_SUCCESS)
2634                                 {
2635                                     for (i = 0; i < PrivilegeSet->PrivilegeCount; i++)
2636                                     {
2637                                         if (RtlEqualLuid(&(PrivilegeSet->Privilege[i].Luid), Luid))
2638                                         {
2639                                             TRACE("%S got the privilege!\n", AccountKeyBuffer);
2640                                             Found = TRUE;
2641                                             break;
2642                                         }
2643                                     }
2644                                 }
2645 
2646                                 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
2647                             }
2648                         }
2649                     }
2650                     else if (AccountRight != 0)
2651                     {
2652                         SystemAccess = 0;
2653                         Size = sizeof(ACCESS_MASK);
2654                         LsapRegQueryValue(AttributeKeyHandle,
2655                                           NULL,
2656                                           NULL,
2657                                           &SystemAccess,
2658                                           &Size);
2659                         if (SystemAccess & AccountRight)
2660                         {
2661                             TRACE("%S got the account right!\n", AccountKeyBuffer);
2662                             Found = TRUE;
2663                         }
2664                     }
2665 
2666                     LsapRegCloseKey(AttributeKeyHandle);
2667                 }
2668             }
2669             else
2670             {
2671                 /* enumerate all accounts */
2672                 Found = TRUE;
2673             }
2674 
2675             if (Found == TRUE)
2676             {
2677                 TRACE("Add account: %S\n", AccountKeyBuffer);
2678 
2679                 Status = LsapRegOpenKey(AccountKeyHandle,
2680                                         L"Sid",
2681                                         KEY_READ,
2682                                         &AttributeKeyHandle);
2683                 if (NT_SUCCESS(Status))
2684                 {
2685                     Size = 0;
2686                     LsapRegQueryValue(AttributeKeyHandle,
2687                                       NULL,
2688                                       NULL,
2689                                       NULL,
2690                                       &Size);
2691                     if (Size != 0)
2692                     {
2693                         EnumBuffer[EnumCount].Sid = midl_user_allocate(Size);
2694                         if (EnumBuffer[EnumCount].Sid != NULL)
2695                         {
2696                             Status = LsapRegQueryValue(AttributeKeyHandle,
2697                                                        NULL,
2698                                                        NULL,
2699                                                        EnumBuffer[EnumCount].Sid,
2700                                                        &Size);
2701                             if (NT_SUCCESS(Status))
2702                             {
2703                                 EnumCount++;
2704                             }
2705                             else
2706                             {
2707                                 TRACE("SampRegQueryValue returned %08lX\n", Status);
2708                                 midl_user_free(EnumBuffer[EnumCount].Sid);
2709                                 EnumBuffer[EnumCount].Sid = NULL;
2710                             }
2711                         }
2712                     }
2713 
2714                     LsapRegCloseKey(AttributeKeyHandle);
2715                 }
2716             }
2717 
2718             LsapRegCloseKey(AccountKeyHandle);
2719         }
2720 
2721         EnumIndex++;
2722     }
2723 
2724     TRACE("EnumCount: %lu\n", EnumCount);
2725 
2726     if (NT_SUCCESS(Status) && EnumCount != 0)
2727     {
2728         ReturnBuffer = midl_user_allocate(EnumCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
2729         if (ReturnBuffer == NULL)
2730         {
2731             Status = STATUS_INSUFFICIENT_RESOURCES;
2732             goto done;
2733         }
2734 
2735         RtlCopyMemory(ReturnBuffer,
2736                       EnumBuffer,
2737                       EnumCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
2738 
2739         EnumerationBuffer->EntriesRead = EnumCount;
2740         EnumerationBuffer->Information = ReturnBuffer;
2741     }
2742 
2743 done:
2744     if (EnumBuffer != NULL)
2745     {
2746         if (Status != STATUS_SUCCESS)
2747         {
2748             for (i = 0; i < EnumCount; i++)
2749             {
2750                 if (EnumBuffer[i].Sid != NULL)
2751                     midl_user_free(EnumBuffer[i].Sid);
2752             }
2753         }
2754 
2755         RtlFreeHeap(RtlGetProcessHeap(), 0, EnumBuffer);
2756     }
2757 
2758     if (AccountKeyBuffer != NULL)
2759         RtlFreeHeap(RtlGetProcessHeap(), 0, AccountKeyBuffer);
2760 
2761     if (Status == STATUS_SUCCESS && EnumCount == 0)
2762         Status = STATUS_NO_MORE_ENTRIES;
2763 
2764     return Status;
2765 }
2766 
2767 
2768 /* Function 36 */
2769 NTSTATUS WINAPI LsarEnumerateAccountRights(
2770     LSAPR_HANDLE PolicyHandle,
2771     PRPC_SID AccountSid,
2772     PLSAPR_USER_RIGHT_SET UserRights)
2773 {
2774     LSAPR_HANDLE AccountHandle;
2775     PLSAPR_PRIVILEGE_SET PrivilegeSet = NULL;
2776     PRPC_UNICODE_STRING RightsBuffer = NULL;
2777     PRPC_UNICODE_STRING PrivilegeString;
2778     ACCESS_MASK SystemAccess = 0;
2779     ULONG RightsCount = 0;
2780     ULONG Index;
2781     ULONG i;
2782     NTSTATUS Status;
2783 
2784     TRACE("LsarEnumerateAccountRights(%p %p %p)\n",
2785           PolicyHandle, AccountSid, UserRights);
2786 
2787     /* Open the account */
2788     Status = LsarOpenAccount(PolicyHandle,
2789                              AccountSid,
2790                              ACCOUNT_VIEW,
2791                              &AccountHandle);
2792     if (!NT_SUCCESS(Status))
2793     {
2794         WARN("LsarOpenAccount returned 0x%08lx\n", Status);
2795         return Status;
2796     }
2797 
2798     /* Enumerate the privileges */
2799     Status = LsarEnumeratePrivilegesAccount(AccountHandle,
2800                                             &PrivilegeSet);
2801     if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
2802     {
2803         WARN("LsarEnumeratePrivilegesAccount returned 0x%08lx\n", Status);
2804         goto done;
2805     }
2806 
2807     /* Get account rights */
2808     Status = LsarGetSystemAccessAccount(AccountHandle,
2809                                         &SystemAccess);
2810     if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
2811     {
2812         WARN("LsarGetSystemAccessAccount returned 0x%08lx\n", Status);
2813         goto done;
2814     }
2815 
2816     RightsCount = PrivilegeSet->PrivilegeCount;
2817 
2818     /* Count account rights */
2819     for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
2820     {
2821         if (SystemAccess & (1 << i))
2822             RightsCount++;
2823     }
2824 
2825     /* We are done if there are no rights to be enumerated */
2826     if (RightsCount == 0)
2827     {
2828         UserRights->Entries = 0;
2829         UserRights->UserRights = NULL;
2830         Status = STATUS_SUCCESS;
2831         goto done;
2832     }
2833 
2834     /* Allocate a buffer for the account rights */
2835     RightsBuffer = MIDL_user_allocate(RightsCount * sizeof(RPC_UNICODE_STRING));
2836     if (RightsBuffer == NULL)
2837     {
2838         Status = STATUS_INSUFFICIENT_RESOURCES;
2839         goto done;
2840     }
2841 
2842     /* Copy the privileges into the buffer */
2843     Index = 0;
2844     if (PrivilegeSet)
2845     {
2846         for (i = 0; i < PrivilegeSet->PrivilegeCount; i++)
2847         {
2848             PrivilegeString = NULL;
2849             Status = LsarLookupPrivilegeName(PolicyHandle,
2850                                              (PLUID)&PrivilegeSet->Privilege[i].Luid,
2851                                              &PrivilegeString);
2852             if (!NT_SUCCESS(Status))
2853             {
2854                 WARN("LsarLookupPrivilegeName returned 0x%08lx\n", Status);
2855                 goto done;
2856             }
2857 
2858             RightsBuffer[Index].Length = PrivilegeString->Length;
2859             RightsBuffer[Index].MaximumLength = PrivilegeString->MaximumLength;
2860             RightsBuffer[Index].Buffer = PrivilegeString->Buffer;
2861 
2862             MIDL_user_free(PrivilegeString);
2863             Index++;
2864         }
2865     }
2866 
2867     /* Copy account rights into the buffer */
2868     for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
2869     {
2870         if (SystemAccess & (1 << i))
2871         {
2872             Status = LsapLookupAccountRightName(1 << i,
2873                                                 &PrivilegeString);
2874             if (!NT_SUCCESS(Status))
2875             {
2876                 WARN("LsarLookupAccountRightName returned 0x%08lx\n", Status);
2877                 goto done;
2878             }
2879 
2880             RightsBuffer[Index].Length = PrivilegeString->Length;
2881             RightsBuffer[Index].MaximumLength = PrivilegeString->MaximumLength;
2882             RightsBuffer[Index].Buffer = PrivilegeString->Buffer;
2883 
2884             MIDL_user_free(PrivilegeString);
2885             Index++;
2886         }
2887     }
2888 
2889     UserRights->Entries = RightsCount;
2890     UserRights->UserRights = (PRPC_UNICODE_STRING)RightsBuffer;
2891 
2892 done:
2893     if (!NT_SUCCESS(Status))
2894     {
2895         if (RightsBuffer != NULL)
2896         {
2897             for (Index = 0; Index < RightsCount; Index++)
2898             {
2899                 if (RightsBuffer[Index].Buffer != NULL)
2900                     MIDL_user_free(RightsBuffer[Index].Buffer);
2901             }
2902 
2903             MIDL_user_free(RightsBuffer);
2904         }
2905     }
2906 
2907     if (PrivilegeSet != NULL)
2908         MIDL_user_free(PrivilegeSet);
2909 
2910     LsarClose(&AccountHandle);
2911 
2912     return Status;
2913 }
2914 
2915 
2916 /* Function 37 */
2917 NTSTATUS WINAPI LsarAddAccountRights(
2918     LSAPR_HANDLE PolicyHandle,
2919     PRPC_SID AccountSid,
2920     PLSAPR_USER_RIGHT_SET UserRights)
2921 {
2922     PLSA_DB_OBJECT PolicyObject;
2923     PLSA_DB_OBJECT AccountObject = NULL;
2924     ULONG ulNewPrivileges = 0, ulNewRights = 0;
2925     ACCESS_MASK SystemAccess = 0;
2926     ULONG Size, Value, i, j;
2927     PPRIVILEGE_SET PrivilegeSet = NULL;
2928     ULONG PrivilegeSetBufferSize = 0;
2929     ULONG PrivilegeCount;
2930     BOOLEAN bFound;
2931     PLUID pLuid;
2932     NTSTATUS Status;
2933 
2934     TRACE("LsarAddAccountRights(%p %p %p)\n",
2935           PolicyHandle, AccountSid, UserRights);
2936 
2937     /* Validate the AccountSid */
2938     if (!RtlValidSid(AccountSid))
2939         return STATUS_INVALID_PARAMETER;
2940 
2941     /* Validate the UserRights */
2942     if (UserRights == NULL)
2943         return STATUS_INVALID_PARAMETER;
2944 
2945     /* Validate the privilege and account right names */
2946     for (i = 0; i < UserRights->Entries; i++)
2947     {
2948         if (LsarpLookupPrivilegeValue(&UserRights->UserRights[i]) != NULL)
2949         {
2950             ulNewPrivileges++;
2951         }
2952         else
2953         {
2954             if (LsapLookupAccountRightValue(&UserRights->UserRights[i]) == 0)
2955                 return STATUS_NO_SUCH_PRIVILEGE;
2956 
2957             ulNewRights++;
2958         }
2959     }
2960 
2961     TRACE("ulNewPrivileges: %lu\n", ulNewPrivileges);
2962     TRACE("ulNewRights: %lu\n", ulNewRights);
2963 
2964     /* Validate the PolicyHandle */
2965     Status = LsapValidateDbObject(PolicyHandle,
2966                                   LsaDbPolicyObject,
2967                                   POLICY_LOOKUP_NAMES,
2968                                   &PolicyObject);
2969     if (!NT_SUCCESS(Status))
2970     {
2971         WARN("LsapValidateDbObject returned 0x%08lx\n", Status);
2972         return Status;
2973     }
2974 
2975     /* Open the account */
2976     Status = LsarpOpenAccount(PolicyObject,
2977                               AccountSid,
2978                               0,
2979                               &AccountObject);
2980     if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
2981     {
2982         WARN("LsarpOpenAccount returned 0x%08lx\n", Status);
2983         goto done;
2984     }
2985     else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
2986     {
2987         /* Create a new account if it does not yet exist */
2988         Status = LsarpCreateAccount(PolicyObject,
2989                                     AccountSid,
2990                                     0,
2991                                     &AccountObject);
2992         if (!NT_SUCCESS(Status))
2993         {
2994             WARN("LsarpCreateAccount returned 0x%08lx\n", Status);
2995             goto done;
2996         }
2997     }
2998 
2999     if (ulNewPrivileges > 0)
3000     {
3001         Size = 0;
3002 
3003         /* Get the size of the Privilgs attribute */
3004         Status = LsapGetObjectAttribute(AccountObject,
3005                                         L"Privilgs",
3006                                         NULL,
3007                                         &Size);
3008         if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
3009             goto done;
3010 
3011         /* Calculate the required privilege set buffer size */
3012         if (Size == 0)
3013             PrivilegeSetBufferSize = sizeof(PRIVILEGE_SET) +
3014                                      (ulNewPrivileges - 1) * sizeof(LUID_AND_ATTRIBUTES);
3015         else
3016             PrivilegeSetBufferSize = Size +
3017                                      ulNewPrivileges * sizeof(LUID_AND_ATTRIBUTES);
3018 
3019         /* Allocate the privilege set buffer */
3020         PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(),
3021                                        HEAP_ZERO_MEMORY,
3022                                        PrivilegeSetBufferSize);
3023         if (PrivilegeSet == NULL)
3024             return STATUS_NO_MEMORY;
3025 
3026         /* Get the privilege set */
3027         if (Size != 0)
3028         {
3029             Status = LsapGetObjectAttribute(AccountObject,
3030                                             L"Privilgs",
3031                                             PrivilegeSet,
3032                                             &Size);
3033             if (!NT_SUCCESS(Status))
3034             {
3035                 WARN("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
3036                 goto done;
3037             }
3038         }
3039 
3040         PrivilegeCount = PrivilegeSet->PrivilegeCount;
3041         TRACE("Privilege count: %lu\n", PrivilegeCount);
3042 
3043         for (i = 0; i < UserRights->Entries; i++)
3044         {
3045             pLuid = LsarpLookupPrivilegeValue(&UserRights->UserRights[i]);
3046             if (pLuid == NULL)
3047                 continue;
3048 
3049             bFound = FALSE;
3050             for (j = 0; j < PrivilegeSet->PrivilegeCount; j++)
3051             {
3052                 if (RtlEqualLuid(&(PrivilegeSet->Privilege[j].Luid), pLuid))
3053                 {
3054                     bFound = TRUE;
3055                     break;
3056                 }
3057             }
3058 
3059             if (bFound == FALSE)
3060             {
3061                 /* Copy the new privilege */
3062                 RtlCopyMemory(&(PrivilegeSet->Privilege[PrivilegeSet->PrivilegeCount]),
3063                               pLuid,
3064                               sizeof(LUID));
3065                 PrivilegeSet->PrivilegeCount++;
3066             }
3067         }
3068 
3069         /* Store the extended privilege set */
3070         if (PrivilegeCount != PrivilegeSet->PrivilegeCount)
3071         {
3072             Size = sizeof(PRIVILEGE_SET) +
3073                    (PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
3074 
3075             Status = LsapSetObjectAttribute(AccountObject,
3076                                             L"Privilgs",
3077                                             PrivilegeSet,
3078                                             Size);
3079             if (!NT_SUCCESS(Status))
3080             {
3081                 WARN("LsapSetObjectAttribute() failed (Status 0x%08lx)\n", Status);
3082                 goto done;
3083             }
3084         }
3085     }
3086 
3087     if (ulNewRights > 0)
3088     {
3089         Size = sizeof(ACCESS_MASK);
3090 
3091         /* Get the system access flags, if the attribute exists */
3092         Status = LsapGetObjectAttribute(AccountObject,
3093                                         L"ActSysAc",
3094                                         &SystemAccess,
3095                                         &Size);
3096         if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
3097             goto done;
3098 
3099         /* Set the new access rights */
3100         for (i = 0; i < UserRights->Entries; i++)
3101         {
3102             Value = LsapLookupAccountRightValue(&UserRights->UserRights[i]);
3103             if (Value != 0)
3104                 SystemAccess |= Value;
3105         }
3106 
3107         /* Set the system access flags */
3108         Status = LsapSetObjectAttribute(AccountObject,
3109                                         L"ActSysAc",
3110                                         &SystemAccess,
3111                                         sizeof(ACCESS_MASK));
3112     }
3113 
3114 done:
3115     if (PrivilegeSet != NULL)
3116         RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
3117 
3118     if (AccountObject != NULL)
3119         LsapCloseDbObject(AccountObject);
3120 
3121     return Status;
3122 }
3123 
3124 
3125 /* Function 38 */
3126 NTSTATUS WINAPI LsarRemoveAccountRights(
3127     LSAPR_HANDLE PolicyHandle,
3128     PRPC_SID AccountSid,
3129     BOOLEAN AllRights,
3130     PLSAPR_USER_RIGHT_SET UserRights)
3131 {
3132     PLSA_DB_OBJECT PolicyObject;
3133     PLSA_DB_OBJECT AccountObject = NULL;
3134     ULONG PrivilegesToRemove = 0, RightsToRemove = 0;
3135     ACCESS_MASK SystemAccess = 0;
3136     ULONG Size, Value, i, j, Index;
3137     PPRIVILEGE_SET PrivilegeSet = NULL;
3138     ULONG PrivilegeCount;
3139     PLUID pLuid;
3140     NTSTATUS Status;
3141 
3142     TRACE("LsarRemoveAccountRights(%p %p %lu %p)\n",
3143           PolicyHandle, AccountSid, AllRights, UserRights);
3144 
3145     /* Validate the AccountSid */
3146     if (!RtlValidSid(AccountSid))
3147         return STATUS_INVALID_PARAMETER;
3148 
3149     /* Validate the UserRights */
3150     if (UserRights == NULL)
3151         return STATUS_INVALID_PARAMETER;
3152 
3153     /* Validate the privilege and account right names */
3154     for (i = 0; i < UserRights->Entries; i++)
3155     {
3156         if (LsarpLookupPrivilegeValue(&UserRights->UserRights[i]) != NULL)
3157         {
3158             PrivilegesToRemove++;
3159         }
3160         else
3161         {
3162             if (LsapLookupAccountRightValue(&UserRights->UserRights[i]) == 0)
3163                 return STATUS_NO_SUCH_PRIVILEGE;
3164 
3165             RightsToRemove++;
3166         }
3167     }
3168 
3169     /* Validate the PolicyHandle */
3170     Status = LsapValidateDbObject(PolicyHandle,
3171                                   LsaDbPolicyObject,
3172                                   POLICY_LOOKUP_NAMES,
3173                                   &PolicyObject);
3174     if (!NT_SUCCESS(Status))
3175     {
3176         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
3177         return Status;
3178     }
3179 
3180     /* Open the account */
3181     Status = LsarpOpenAccount(PolicyObject,
3182                               AccountSid,
3183                               0,
3184                               &AccountObject);
3185     if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
3186     {
3187         ERR("LsarpOpenAccount returned 0x%08lx\n", Status);
3188         goto done;
3189     }
3190 
3191     if (AllRights == FALSE)
3192     {
3193         /* Get the size of the Privilgs attribute */
3194         Size = 0;
3195         Status = LsapGetObjectAttribute(AccountObject,
3196                                         L"Privilgs",
3197                                         NULL,
3198                                         &Size);
3199         if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
3200             goto done;
3201 
3202         if ((Size != 0) && (PrivilegesToRemove != 0))
3203         {
3204             /* Allocate the privilege set buffer */
3205             PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(),
3206                                            HEAP_ZERO_MEMORY,
3207                                            Size);
3208             if (PrivilegeSet == NULL)
3209                 return STATUS_NO_MEMORY;
3210 
3211             /* Get the privilege set */
3212             Status = LsapGetObjectAttribute(AccountObject,
3213                                             L"Privilgs",
3214                                             PrivilegeSet,
3215                                             &Size);
3216             if (!NT_SUCCESS(Status))
3217             {
3218                 ERR("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
3219                 goto done;
3220             }
3221 
3222             PrivilegeCount = PrivilegeSet->PrivilegeCount;
3223 
3224             for (i = 0; i < UserRights->Entries; i++)
3225             {
3226                 pLuid = LsarpLookupPrivilegeValue(&UserRights->UserRights[i]);
3227                 if (pLuid == NULL)
3228                     continue;
3229 
3230                 Index = -1;
3231                 for (j = 0; j < PrivilegeSet->PrivilegeCount; j++)
3232                 {
3233                     if (RtlEqualLuid(&(PrivilegeSet->Privilege[j].Luid), pLuid))
3234                     {
3235                         Index = j;
3236                         break;
3237                     }
3238                 }
3239 
3240                 if (Index != -1)
3241                 {
3242                     /* Remove the privilege */
3243                     if ((PrivilegeSet->PrivilegeCount > 1) &&
3244                         (Index < PrivilegeSet->PrivilegeCount - 1))
3245                         RtlMoveMemory(&(PrivilegeSet->Privilege[Index]),
3246                                       &(PrivilegeSet->Privilege[Index + 1]),
3247                                       (Index - PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID));
3248 
3249                     /* Wipe the last entry */
3250                     RtlZeroMemory(&(PrivilegeSet->Privilege[PrivilegeSet->PrivilegeCount - 1]),
3251                                   sizeof(LUID));
3252 
3253                     PrivilegeSet->PrivilegeCount--;
3254                 }
3255             }
3256 
3257             /* Store the extended privilege set */
3258             if (PrivilegeCount != PrivilegeSet->PrivilegeCount)
3259             {
3260                 Size = sizeof(PRIVILEGE_SET) +
3261                        (PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
3262 
3263                 Status = LsapSetObjectAttribute(AccountObject,
3264                                                 L"Privilgs",
3265                                                 PrivilegeSet,
3266                                                 Size);
3267                 if (!NT_SUCCESS(Status))
3268                 {
3269                     ERR("LsapSetObjectAttribute() failed (Status 0x%08lx)\n", Status);
3270                     goto done;
3271                 }
3272             }
3273         }
3274 
3275         /* Get the system access flags, if the attribute exists */
3276         Size = 0;
3277         Status = LsapGetObjectAttribute(AccountObject,
3278                                         L"ActSysAc",
3279                                         &SystemAccess,
3280                                         &Size);
3281         if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
3282             goto done;
3283 
3284         if ((Size != 0) && (RightsToRemove != 0))
3285         {
3286             ERR("Rights: 0x%lx\n", SystemAccess);
3287 
3288             /* Set the new access rights */
3289             for (i = 0; i < UserRights->Entries; i++)
3290             {
3291                 Value = LsapLookupAccountRightValue(&UserRights->UserRights[i]);
3292                 if (Value != 0)
3293                     SystemAccess &= ~Value;
3294             }
3295             ERR("New Rights: 0x%lx\n", SystemAccess);
3296 
3297             /* Set the system access flags */
3298             Status = LsapSetObjectAttribute(AccountObject,
3299                                             L"ActSysAc",
3300                                             &SystemAccess,
3301                                             sizeof(ACCESS_MASK));
3302         }
3303     }
3304     else
3305     {
3306     }
3307 
3308 done:
3309     if (PrivilegeSet != NULL)
3310         RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
3311 
3312     if (AccountObject != NULL)
3313         LsapCloseDbObject(AccountObject);
3314 
3315     return Status;
3316 }
3317 
3318 
3319 /* Function 39 */
3320 NTSTATUS WINAPI LsarQueryTrustedDomainInfo(
3321     LSAPR_HANDLE PolicyHandle,
3322     PRPC_SID TrustedDomainSid,
3323     TRUSTED_INFORMATION_CLASS InformationClass,
3324     PLSAPR_TRUSTED_DOMAIN_INFO *TrustedDomainInformation)
3325 {
3326     /* FIXME: We are not running an AD yet */
3327     return STATUS_DIRECTORY_SERVICE_REQUIRED;
3328 }
3329 
3330 
3331 /* Function 40 */
3332 NTSTATUS WINAPI LsarSetTrustedDomainInfo(
3333     LSAPR_HANDLE PolicyHandle,
3334     PRPC_SID TrustedDomainSid,
3335     TRUSTED_INFORMATION_CLASS InformationClass,
3336     PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainInformation)
3337 {
3338     /* FIXME: We are not running an AD yet */
3339     return STATUS_DIRECTORY_SERVICE_REQUIRED;
3340 }
3341 
3342 
3343 /* Function 41 */
3344 NTSTATUS WINAPI LsarDeleteTrustedDomain(
3345     LSAPR_HANDLE PolicyHandle,
3346     PRPC_SID TrustedDomainSid)
3347 {
3348     /* FIXME: We are not running an AD yet */
3349     return STATUS_DIRECTORY_SERVICE_REQUIRED;
3350 }
3351 
3352 
3353 /* Function 42 */
3354 NTSTATUS WINAPI LsarStorePrivateData(
3355     LSAPR_HANDLE PolicyHandle,
3356     PRPC_UNICODE_STRING KeyName,
3357     PLSAPR_CR_CIPHER_VALUE EncryptedData)
3358 {
3359     PLSA_DB_OBJECT PolicyObject = NULL;
3360     PLSA_DB_OBJECT SecretsObject = NULL;
3361     PLSA_DB_OBJECT SecretObject = NULL;
3362     LARGE_INTEGER Time;
3363     PBYTE Value = NULL;
3364     ULONG ValueLength = 0;
3365     NTSTATUS Status;
3366 
3367     TRACE("LsarStorePrivateData(%p %p %p)\n",
3368           PolicyHandle, KeyName, EncryptedData);
3369 
3370     /* Validate the SecretHandle */
3371     Status = LsapValidateDbObject(PolicyHandle,
3372                                   LsaDbPolicyObject,
3373                                   POLICY_CREATE_SECRET,
3374                                   &PolicyObject);
3375     if (!NT_SUCCESS(Status))
3376     {
3377         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
3378         return Status;
3379     }
3380 
3381     /* Open the 'Secrets' object */
3382     Status = LsapOpenDbObject(PolicyObject,
3383                               NULL,
3384                               L"Secrets",
3385                               LsaDbIgnoreObject,
3386                               0,
3387                               PolicyObject->Trusted,
3388                               &SecretsObject);
3389     if (!NT_SUCCESS(Status))
3390     {
3391         ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
3392         goto done;
3393     }
3394 
3395     if (EncryptedData == NULL)
3396     {
3397         /* Open the Secret object */
3398         Status = LsapOpenDbObject(SecretsObject,
3399                                   NULL,
3400                                   KeyName->Buffer,
3401                                   LsaDbSecretObject,
3402                                   0,
3403                                   PolicyObject->Trusted,
3404                                   &SecretObject);
3405         if (!NT_SUCCESS(Status))
3406         {
3407             ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
3408             goto done;
3409         }
3410 
3411         /* Delete the secret */
3412         Status = LsapDeleteDbObject(SecretObject);
3413         if (NT_SUCCESS(Status))
3414             SecretObject = NULL;
3415     }
3416     else
3417     {
3418         /* Create the Secret object */
3419         Status = LsapCreateDbObject(SecretsObject,
3420                                     NULL,
3421                                     KeyName->Buffer,
3422                                     LsaDbSecretObject,
3423                                     0,
3424                                     PolicyObject->Trusted,
3425                                     &SecretObject);
3426         if (!NT_SUCCESS(Status))
3427         {
3428             ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
3429             goto done;
3430         }
3431 
3432         /* FIXME: Decrypt data */
3433         Value = EncryptedData->Buffer;
3434         ValueLength = EncryptedData->MaximumLength;
3435 
3436         /* Get the current time */
3437         Status = NtQuerySystemTime(&Time);
3438         if (!NT_SUCCESS(Status))
3439         {
3440             ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
3441             goto done;
3442         }
3443 
3444         /* Set the current value */
3445         Status = LsapSetObjectAttribute(SecretObject,
3446                                         L"CurrentValue",
3447                                         Value,
3448                                         ValueLength);
3449         if (!NT_SUCCESS(Status))
3450         {
3451             ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
3452             goto done;
3453         }
3454 
3455         /* Set the current time */
3456         Status = LsapSetObjectAttribute(SecretObject,
3457                                         L"CurrentTime",
3458                                         &Time,
3459                                         sizeof(LARGE_INTEGER));
3460         if (!NT_SUCCESS(Status))
3461         {
3462             ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
3463             goto done;
3464         }
3465 
3466         /* Get the current time */
3467         Status = NtQuerySystemTime(&Time);
3468         if (!NT_SUCCESS(Status))
3469         {
3470             ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
3471             goto done;
3472         }
3473 
3474         /* Set the old value */
3475         Status = LsapSetObjectAttribute(SecretObject,
3476                                         L"OldValue",
3477                                         NULL,
3478                                         0);
3479         if (!NT_SUCCESS(Status))
3480         {
3481             ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
3482             goto done;
3483         }
3484 
3485         /* Set the old time */
3486         Status = LsapSetObjectAttribute(SecretObject,
3487                                         L"OldTime",
3488                                         &Time,
3489                                         sizeof(LARGE_INTEGER));
3490         if (!NT_SUCCESS(Status))
3491         {
3492             ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
3493         }
3494     }
3495 
3496 done:
3497     if (SecretObject != NULL)
3498         LsapCloseDbObject(SecretObject);
3499 
3500     if (SecretsObject != NULL)
3501         LsapCloseDbObject(SecretsObject);
3502 
3503     return Status;
3504 }
3505 
3506 
3507 /* Function 43 */
3508 NTSTATUS WINAPI LsarRetrievePrivateData(
3509     LSAPR_HANDLE PolicyHandle,
3510     PRPC_UNICODE_STRING KeyName,
3511     PLSAPR_CR_CIPHER_VALUE *EncryptedData)
3512 {
3513     PLSA_DB_OBJECT PolicyObject = NULL;
3514     PLSA_DB_OBJECT SecretObject = NULL;
3515     PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL;
3516     ULONG CurrentValueLength = 0;
3517     PBYTE CurrentValue = NULL;
3518     NTSTATUS Status;
3519 
3520     TRACE("LsarRetrievePrivateData(%p %wZ %p)\n",
3521           PolicyHandle, KeyName, EncryptedData);
3522 
3523     /* Validate the SecretHandle */
3524     Status = LsapValidateDbObject(PolicyHandle,
3525                                   LsaDbPolicyObject,
3526                                   POLICY_CREATE_SECRET,
3527                                   &PolicyObject);
3528     if (!NT_SUCCESS(Status))
3529     {
3530         ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
3531         return Status;
3532     }
3533 
3534     /* Open the secret object */
3535     Status = LsapOpenDbObject(PolicyObject,
3536                               L"Secrets",
3537                               KeyName->Buffer,
3538                               LsaDbSecretObject,
3539                               0,
3540                               PolicyObject->Trusted,
3541                               &SecretObject);
3542     if (!NT_SUCCESS(Status))
3543     {
3544         ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
3545         goto done;
3546     }
3547 
3548     /* Get the size of the current value */
3549     Status = LsapGetObjectAttribute(SecretObject,
3550                                     L"CurrentValue",
3551                                     NULL,
3552                                     &CurrentValueLength);
3553     if (!NT_SUCCESS(Status))
3554         goto done;
3555 
3556     /* Allocate a buffer for the current value */
3557     CurrentValue = midl_user_allocate(CurrentValueLength);
3558     if (CurrentValue == NULL)
3559     {
3560         Status = STATUS_INSUFFICIENT_RESOURCES;
3561         goto done;
3562     }
3563 
3564     /* Get the current value */
3565     Status = LsapGetObjectAttribute(SecretObject,
3566                                     L"CurrentValue",
3567                                     CurrentValue,
3568                                     &CurrentValueLength);
3569     if (!NT_SUCCESS(Status))
3570         goto done;
3571 
3572     /* Allocate a buffer for the encrypted current value */
3573     EncCurrentValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE) + CurrentValueLength);
3574     if (EncCurrentValue == NULL)
3575     {
3576         Status = STATUS_INSUFFICIENT_RESOURCES;
3577         goto done;
3578     }
3579 
3580     /* FIXME: Encrypt the current value */
3581     EncCurrentValue->Length = (USHORT)(CurrentValueLength - sizeof(WCHAR));
3582     EncCurrentValue->MaximumLength = (USHORT)CurrentValueLength;
3583     EncCurrentValue->Buffer = (PBYTE)(EncCurrentValue + 1);
3584     RtlCopyMemory(EncCurrentValue->Buffer,
3585                   CurrentValue,
3586                   CurrentValueLength);
3587 
3588 done:
3589     if (NT_SUCCESS(Status))
3590     {
3591         if (EncryptedData != NULL)
3592             *EncryptedData = EncCurrentValue;
3593     }
3594     else
3595     {
3596         if (EncryptedData != NULL)
3597             *EncryptedData = NULL;
3598 
3599         if (EncCurrentValue != NULL)
3600             midl_user_free(EncCurrentValue);
3601     }
3602 
3603     if (SecretObject != NULL)
3604         LsapCloseDbObject(SecretObject);
3605 
3606     return Status;
3607 }
3608 
3609 
3610 /* Function 44 */
3611 NTSTATUS WINAPI LsarOpenPolicy2(
3612     LPWSTR SystemName,
3613     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
3614     ACCESS_MASK DesiredAccess,
3615     LSAPR_HANDLE *PolicyHandle)
3616 {
3617     return LsarOpenPolicy(SystemName,
3618                           ObjectAttributes,
3619                           DesiredAccess,
3620                           PolicyHandle);
3621 }
3622 
3623 
3624 /* Function 45 */
3625 NTSTATUS WINAPI LsarGetUserName(
3626     LPWSTR SystemName,
3627     PRPC_UNICODE_STRING *UserName,
3628     PRPC_UNICODE_STRING *DomainName)
3629 {
3630     UNIMPLEMENTED;
3631     return STATUS_NOT_IMPLEMENTED;
3632 }
3633 
3634 
3635 /* Function 46 */
3636 NTSTATUS WINAPI LsarQueryInformationPolicy2(
3637     LSAPR_HANDLE PolicyHandle,
3638     POLICY_INFORMATION_CLASS InformationClass,
3639     PLSAPR_POLICY_INFORMATION *PolicyInformation)
3640 {
3641     return LsarQueryInformationPolicy(PolicyHandle,
3642                                       InformationClass,
3643                                       PolicyInformation);
3644 }
3645 
3646 
3647 /* Function 47 */
3648 NTSTATUS WINAPI LsarSetInformationPolicy2(
3649     LSAPR_HANDLE PolicyHandle,
3650     POLICY_INFORMATION_CLASS InformationClass,
3651     PLSAPR_POLICY_INFORMATION PolicyInformation)
3652 {
3653     return LsarSetInformationPolicy(PolicyHandle,
3654                                     InformationClass,
3655                                     PolicyInformation);
3656 }
3657 
3658 
3659 /* Function 48 */
3660 NTSTATUS WINAPI LsarQueryTrustedDomainInfoByName(
3661     LSAPR_HANDLE PolicyHandle,
3662     PRPC_UNICODE_STRING TrustedDomainName,
3663     POLICY_INFORMATION_CLASS InformationClass,
3664     PLSAPR_TRUSTED_DOMAIN_INFO *PolicyInformation)
3665 {
3666     /* FIXME: We are not running an AD yet */
3667     return STATUS_OBJECT_NAME_NOT_FOUND;
3668 }
3669 
3670 
3671 /* Function 49 */
3672 NTSTATUS WINAPI LsarSetTrustedDomainInfoByName(
3673     LSAPR_HANDLE PolicyHandle,
3674     PRPC_UNICODE_STRING TrustedDomainName,
3675     POLICY_INFORMATION_CLASS InformationClass,
3676     PLSAPR_TRUSTED_DOMAIN_INFO PolicyInformation)
3677 {
3678     /* FIXME: We are not running an AD yet */
3679     return STATUS_OBJECT_NAME_NOT_FOUND;
3680 }
3681 
3682 
3683 /* Function 50 */
3684 NTSTATUS WINAPI LsarEnumerateTrustedDomainsEx(
3685     LSAPR_HANDLE PolicyHandle,
3686     DWORD *EnumerationContext,
3687     PLSAPR_TRUSTED_ENUM_BUFFER_EX EnumerationBuffer,
3688     DWORD PreferedMaximumLength)
3689 {
3690     /* FIXME: We are not running an AD yet */
3691     EnumerationBuffer->EntriesRead = 0;
3692     EnumerationBuffer->EnumerationBuffer = NULL;
3693     return STATUS_NO_MORE_ENTRIES;
3694 }
3695 
3696 
3697 /* Function 51 */
3698 NTSTATUS WINAPI LsarCreateTrustedDomainEx(
3699     LSAPR_HANDLE PolicyHandle,
3700     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
3701     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION AuthentificationInformation,
3702     ACCESS_MASK DesiredAccess,
3703     LSAPR_HANDLE *TrustedDomainHandle)
3704 {
3705     /* FIXME: We are not running an AD yet */
3706     return STATUS_DIRECTORY_SERVICE_REQUIRED;
3707 }
3708 
3709 
3710 /* Function 52 */
3711 NTSTATUS WINAPI LsarSetPolicyReplicationHandle(
3712     PLSAPR_HANDLE PolicyHandle)
3713 {
3714     /* Deprecated */
3715     return STATUS_NOT_IMPLEMENTED;
3716 }
3717 
3718 
3719 /* Function 53 */
3720 NTSTATUS WINAPI LsarQueryDomainInformationPolicy(
3721     LSAPR_HANDLE PolicyHandle,
3722     POLICY_INFORMATION_CLASS InformationClass,
3723     PLSAPR_POLICY_DOMAIN_INFORMATION *PolicyInformation)
3724 {
3725     UNIMPLEMENTED;
3726     return STATUS_NOT_IMPLEMENTED;
3727 }
3728 
3729 
3730 /* Function 54 */
3731 NTSTATUS WINAPI LsarSetDomainInformationPolicy(
3732     LSAPR_HANDLE PolicyHandle,
3733     POLICY_INFORMATION_CLASS InformationClass,
3734     PLSAPR_POLICY_DOMAIN_INFORMATION PolicyInformation)
3735 {
3736     UNIMPLEMENTED;
3737     return STATUS_NOT_IMPLEMENTED;
3738 }
3739 
3740 
3741 /* Function 55 */
3742 NTSTATUS WINAPI LsarOpenTrustedDomainByName(
3743     LSAPR_HANDLE PolicyHandle,
3744     PRPC_UNICODE_STRING TrustedDomainName,
3745     ACCESS_MASK DesiredAccess,
3746     LSAPR_HANDLE *TrustedDomainHandle)
3747 {
3748     /* FIXME: We are not running an AD yet */
3749     return STATUS_OBJECT_NAME_NOT_FOUND;
3750 }
3751 
3752 
3753 /* Function 56 */
3754 NTSTATUS WINAPI LsarTestCall(
3755     handle_t hBinding)
3756 {
3757     UNIMPLEMENTED;
3758     return STATUS_NOT_IMPLEMENTED;
3759 }
3760 
3761 
3762 /* Function 57 */
3763 NTSTATUS WINAPI LsarLookupSids2(
3764     LSAPR_HANDLE PolicyHandle,
3765     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
3766     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
3767     PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
3768     LSAP_LOOKUP_LEVEL LookupLevel,
3769     DWORD *MappedCount,
3770     DWORD LookupOptions,
3771     DWORD ClientRevision)
3772 {
3773     NTSTATUS Status;
3774 
3775     TRACE("LsarLookupSids2(%p %p %p %p %d %p %lu %lu)\n",
3776           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
3777           LookupLevel, MappedCount, LookupOptions, ClientRevision);
3778 
3779     TranslatedNames->Entries = SidEnumBuffer->Entries;
3780     TranslatedNames->Names = NULL;
3781     *ReferencedDomains = NULL;
3782 
3783     /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
3784 
3785     Status = LsapLookupSids(SidEnumBuffer,
3786                             ReferencedDomains,
3787                             TranslatedNames,
3788                             LookupLevel,
3789                             MappedCount,
3790                             LookupOptions,
3791                             ClientRevision);
3792 
3793     return Status;
3794 }
3795 
3796 
3797 /* Function 58 */
3798 NTSTATUS WINAPI LsarLookupNames2(
3799     LSAPR_HANDLE PolicyHandle,
3800     DWORD Count,
3801     PRPC_UNICODE_STRING Names,
3802     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
3803     PLSAPR_TRANSLATED_SIDS_EX TranslatedSids,
3804     LSAP_LOOKUP_LEVEL LookupLevel,
3805     DWORD *MappedCount,
3806     DWORD LookupOptions,
3807     DWORD ClientRevision)
3808 {
3809     LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2;
3810     ULONG i;
3811     NTSTATUS Status;
3812 
3813     TRACE("LsarLookupNames2(%p %lu %p %p %p %d %p %lu %lu)\n",
3814           PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
3815           LookupLevel, MappedCount, LookupOptions, ClientRevision);
3816 
3817     TranslatedSids->Entries = 0;
3818     TranslatedSids->Sids = NULL;
3819     *ReferencedDomains = NULL;
3820 
3821     if (Count == 0)
3822         return STATUS_NONE_MAPPED;
3823 
3824     TranslatedSidsEx2.Entries = 0;
3825     TranslatedSidsEx2.Sids = NULL;
3826 
3827     Status = LsapLookupNames(Count,
3828                              Names,
3829                              ReferencedDomains,
3830                              &TranslatedSidsEx2,
3831                              LookupLevel,
3832                              MappedCount,
3833                              LookupOptions,
3834                              ClientRevision);
3835     if (!NT_SUCCESS(Status))
3836         return Status;
3837 
3838     TranslatedSids->Entries = TranslatedSidsEx2.Entries;
3839     TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID));
3840     if (TranslatedSids->Sids == NULL)
3841     {
3842         MIDL_user_free(TranslatedSidsEx2.Sids);
3843         MIDL_user_free(*ReferencedDomains);
3844         *ReferencedDomains = NULL;
3845         return STATUS_INSUFFICIENT_RESOURCES;
3846     }
3847 
3848     for (i = 0; i < TranslatedSidsEx2.Entries; i++)
3849     {
3850         TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use;
3851         TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid);
3852         TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex;
3853         TranslatedSids->Sids[i].Flags = TranslatedSidsEx2.Sids[i].Flags;
3854     }
3855 
3856     MIDL_user_free(TranslatedSidsEx2.Sids);
3857 
3858     return STATUS_SUCCESS;
3859 }
3860 
3861 
3862 /* Function 59 */
3863 NTSTATUS WINAPI LsarCreateTrustedDomainEx2(
3864     LSAPR_HANDLE PolicyHandle,
3865     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
3866     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL AuthentificationInformation,
3867     ACCESS_MASK DesiredAccess,
3868     LSAPR_HANDLE *TrustedDomainHandle)
3869 {
3870     /* FIXME: We are not running an AD yet */
3871     return STATUS_DIRECTORY_SERVICE_REQUIRED;
3872 }
3873 
3874 
3875 /* Function 60 */
3876 NTSTATUS WINAPI CredrWrite(
3877     handle_t hBinding)
3878 {
3879     UNIMPLEMENTED;
3880     return STATUS_NOT_IMPLEMENTED;
3881 }
3882 
3883 
3884 /* Function 61 */
3885 NTSTATUS WINAPI CredrRead(
3886     handle_t hBinding)
3887 {
3888     UNIMPLEMENTED;
3889     return STATUS_NOT_IMPLEMENTED;
3890 }
3891 
3892 
3893 /* Function 62 */
3894 NTSTATUS WINAPI CredrEnumerate(
3895     handle_t hBinding)
3896 {
3897     UNIMPLEMENTED;
3898     return STATUS_NOT_IMPLEMENTED;
3899 }
3900 
3901 
3902 /* Function 63 */
3903 NTSTATUS WINAPI CredrWriteDomainCredentials(
3904     handle_t hBinding)
3905 {
3906     UNIMPLEMENTED;
3907     return STATUS_NOT_IMPLEMENTED;
3908 }
3909 
3910 
3911 /* Function 64 */
3912 NTSTATUS WINAPI CredrReadDomainCredentials(
3913     handle_t hBinding)
3914 {
3915     UNIMPLEMENTED;
3916     return STATUS_NOT_IMPLEMENTED;
3917 }
3918 
3919 
3920 /* Function 65 */
3921 NTSTATUS WINAPI CredrDelete(
3922     handle_t hBinding)
3923 {
3924     UNIMPLEMENTED;
3925     return STATUS_NOT_IMPLEMENTED;
3926 }
3927 
3928 
3929 /* Function 66 */
3930 NTSTATUS WINAPI CredrGetTargetInfo(
3931     handle_t hBinding)
3932 {
3933     UNIMPLEMENTED;
3934     return STATUS_NOT_IMPLEMENTED;
3935 }
3936 
3937 
3938 /* Function 67 */
3939 NTSTATUS WINAPI CredrProfileLoaded(
3940     handle_t hBinding)
3941 {
3942     UNIMPLEMENTED;
3943     return STATUS_NOT_IMPLEMENTED;
3944 }
3945 
3946 
3947 /* Function 68 */
3948 NTSTATUS WINAPI LsarLookupNames3(
3949     LSAPR_HANDLE PolicyHandle,
3950     DWORD Count,
3951     PRPC_UNICODE_STRING Names,
3952     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
3953     PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
3954     LSAP_LOOKUP_LEVEL LookupLevel,
3955     DWORD *MappedCount,
3956     DWORD LookupOptions,
3957     DWORD ClientRevision)
3958 {
3959     NTSTATUS Status;
3960 
3961     TRACE("LsarLookupNames3(%p %lu %p %p %p %d %p %lu %lu)\n",
3962           PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
3963           LookupLevel, MappedCount, LookupOptions, ClientRevision);
3964 
3965     TranslatedSids->Entries = 0;
3966     TranslatedSids->Sids = NULL;
3967     *ReferencedDomains = NULL;
3968 
3969     if (Count == 0)
3970         return STATUS_NONE_MAPPED;
3971 
3972     Status = LsapLookupNames(Count,
3973                              Names,
3974                              ReferencedDomains,
3975                              TranslatedSids,
3976                              LookupLevel,
3977                              MappedCount,
3978                              LookupOptions,
3979                              ClientRevision);
3980 
3981     return Status;
3982 }
3983 
3984 
3985 /* Function 69 */
3986 NTSTATUS WINAPI CredrGetSessionTypes(
3987     handle_t hBinding)
3988 {
3989     UNIMPLEMENTED;
3990     return STATUS_NOT_IMPLEMENTED;
3991 }
3992 
3993 
3994 /* Function 70 */
3995 NTSTATUS WINAPI LsarRegisterAuditEvent(
3996     handle_t hBinding)
3997 {
3998     UNIMPLEMENTED;
3999     return STATUS_NOT_IMPLEMENTED;
4000 }
4001 
4002 
4003 /* Function 71 */
4004 NTSTATUS WINAPI LsarGenAuditEvent(
4005     handle_t hBinding)
4006 {
4007     UNIMPLEMENTED;
4008     return STATUS_NOT_IMPLEMENTED;
4009 }
4010 
4011 
4012 /* Function 72 */
4013 NTSTATUS WINAPI LsarUnregisterAuditEvent(
4014     handle_t hBinding)
4015 {
4016     UNIMPLEMENTED;
4017     return STATUS_NOT_IMPLEMENTED;
4018 }
4019 
4020 
4021 /* Function 73 */
4022 NTSTATUS WINAPI LsarQueryForestTrustInformation(
4023     LSAPR_HANDLE PolicyHandle,
4024     PLSA_UNICODE_STRING TrustedDomainName,
4025     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
4026     PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
4027 {
4028     UNIMPLEMENTED;
4029     return STATUS_NOT_IMPLEMENTED;
4030 }
4031 
4032 
4033 /* Function 74 */
4034 NTSTATUS WINAPI LsarSetForestTrustInformation(
4035     LSAPR_HANDLE PolicyHandle,
4036     PLSA_UNICODE_STRING TrustedDomainName,
4037     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
4038     PLSA_FOREST_TRUST_INFORMATION ForestTrustInfo,
4039     BOOLEAN CheckOnly,
4040     PLSA_FOREST_TRUST_COLLISION_INFORMATION *CollisionInfo)
4041 {
4042     UNIMPLEMENTED;
4043     return STATUS_NOT_IMPLEMENTED;
4044 }
4045 
4046 
4047 /* Function 75 */
4048 NTSTATUS WINAPI CredrRename(
4049     handle_t hBinding)
4050 {
4051     UNIMPLEMENTED;
4052     return STATUS_NOT_IMPLEMENTED;
4053 }
4054 
4055 
4056 /* Function 76 */
4057 NTSTATUS WINAPI LsarLookupSids3(
4058     LSAPR_HANDLE PolicyHandle,
4059     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
4060     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
4061     PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
4062     LSAP_LOOKUP_LEVEL LookupLevel,
4063     DWORD *MappedCount,
4064     DWORD LookupOptions,
4065     DWORD ClientRevision)
4066 {
4067     NTSTATUS Status;
4068 
4069     TRACE("LsarLookupSids3(%p %p %p %p %d %p %lu %lu)\n",
4070           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
4071           LookupLevel, MappedCount, LookupOptions, ClientRevision);
4072 
4073     TranslatedNames->Entries = SidEnumBuffer->Entries;
4074     TranslatedNames->Names = NULL;
4075     *ReferencedDomains = NULL;
4076 
4077     /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
4078 
4079     Status = LsapLookupSids(SidEnumBuffer,
4080                             ReferencedDomains,
4081                             TranslatedNames,
4082                             LookupLevel,
4083                             MappedCount,
4084                             LookupOptions,
4085                             ClientRevision);
4086 
4087     return Status;
4088 }
4089 
4090 
4091 /* Function 77 */
4092 NTSTATUS WINAPI LsarLookupNames4(
4093     handle_t RpcHandle,
4094     DWORD Count,
4095     PRPC_UNICODE_STRING Names,
4096     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
4097     PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
4098     LSAP_LOOKUP_LEVEL LookupLevel,
4099     DWORD *MappedCount,
4100     DWORD LookupOptions,
4101     DWORD ClientRevision)
4102 {
4103     NTSTATUS Status;
4104 
4105     TRACE("LsarLookupNames4(%p %lu %p %p %p %d %p %lu %lu)\n",
4106           RpcHandle, Count, Names, ReferencedDomains, TranslatedSids,
4107           LookupLevel, MappedCount, LookupOptions, ClientRevision);
4108 
4109     TranslatedSids->Entries = 0;
4110     TranslatedSids->Sids = NULL;
4111     *ReferencedDomains = NULL;
4112 
4113     if (Count == 0)
4114         return STATUS_NONE_MAPPED;
4115 
4116     Status = LsapLookupNames(Count,
4117                              Names,
4118                              ReferencedDomains,
4119                              TranslatedSids,
4120                              LookupLevel,
4121                              MappedCount,
4122                              LookupOptions,
4123                              ClientRevision);
4124 
4125     return Status;
4126 }
4127 
4128 
4129 /* Function 78 */
4130 NTSTATUS WINAPI LsarOpenPolicySce(
4131     LPWSTR SystemName,
4132     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
4133     ACCESS_MASK DesiredAccess,
4134     LSAPR_HANDLE *PolicyHandle)
4135 {
4136     UNIMPLEMENTED;
4137     return STATUS_NOT_IMPLEMENTED;
4138 }
4139 
4140 
4141 /* Function 79 */
4142 NTSTATUS WINAPI LsarAdtRegisterSecurityEventSource(
4143     handle_t hBinding)
4144 {
4145     UNIMPLEMENTED;
4146     return STATUS_NOT_IMPLEMENTED;
4147 }
4148 
4149 
4150 /* Function 80 */
4151 NTSTATUS WINAPI LsarAdtUnregisterSecurityEventSource(
4152     handle_t hBinding)
4153 {
4154     UNIMPLEMENTED;
4155     return STATUS_NOT_IMPLEMENTED;
4156 }
4157 
4158 
4159 /* Function 81 */
4160 NTSTATUS WINAPI LsarAdtReportSecurityEvent(
4161     handle_t hBinding)
4162 {
4163     UNIMPLEMENTED;
4164     return STATUS_NOT_IMPLEMENTED;
4165 }
4166 
4167 /* EOF */
4168