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