xref: /reactos/dll/win32/lsasrv/lsarpc.c (revision 25720d75)
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 /* INCLUDES ****************************************************************/
11 
12 #include "lsasrv.h"
13 
14 typedef enum _LSA_DB_HANDLE_TYPE
15 {
16     LsaDbIgnoreHandle,
17     LsaDbPolicyHandle,
18     LsaDbAccountHandle
19 } LSA_DB_HANDLE_TYPE, *PLSA_DB_HANDLE_TYPE;
20 
21 typedef struct _LSA_DB_HANDLE
22 {
23     ULONG Signature;
24     LSA_DB_HANDLE_TYPE HandleType;
25     LONG RefCount;
26     ACCESS_MASK Access;
27 } LSA_DB_HANDLE, *PLSA_DB_HANDLE;
28 
29 #define LSAP_DB_SIGNATURE 0x12345678
30 
31 static RTL_CRITICAL_SECTION PolicyHandleTableLock;
32 
33 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
34 
35 
36 /* FUNCTIONS ***************************************************************/
37 
38 static LSAPR_HANDLE
39 LsapCreateDbHandle(LSA_DB_HANDLE_TYPE HandleType,
40                    ACCESS_MASK DesiredAccess)
41 {
42     PLSA_DB_HANDLE DbHandle;
43 
44 //    RtlEnterCriticalSection(&PolicyHandleTableLock);
45 
46     DbHandle = (PLSA_DB_HANDLE)RtlAllocateHeap(RtlGetProcessHeap(),
47                                                0,
48                                                sizeof(LSA_DB_HANDLE));
49     if (DbHandle != NULL)
50     {
51         DbHandle->Signature = LSAP_DB_SIGNATURE;
52         DbHandle->RefCount = 1;
53         DbHandle->HandleType = HandleType;
54         DbHandle->Access = DesiredAccess;
55     }
56 
57 //    RtlLeaveCriticalSection(&PolicyHandleTableLock);
58 
59     return (LSAPR_HANDLE)DbHandle;
60 }
61 
62 
63 static BOOL
64 LsapValidateDbHandle(LSAPR_HANDLE Handle,
65                      LSA_DB_HANDLE_TYPE HandleType)
66 {
67     PLSA_DB_HANDLE DbHandle = (PLSA_DB_HANDLE)Handle;
68     BOOL bValid = FALSE;
69 
70     _SEH2_TRY
71     {
72         if (DbHandle->Signature == LSAP_DB_SIGNATURE)
73         {
74             if (HandleType == LsaDbIgnoreHandle)
75                 bValid = TRUE;
76             else if (DbHandle->HandleType == HandleType)
77                 bValid = TRUE;
78         }
79     }
80     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
81     {
82         bValid = FALSE;
83     }
84     _SEH2_END;
85 
86 
87     return bValid;
88 }
89 
90 
91 
92 
93 VOID
94 LsarStartRpcServer(VOID)
95 {
96     RPC_STATUS Status;
97 
98     RtlInitializeCriticalSection(&PolicyHandleTableLock);
99 
100     TRACE("LsarStartRpcServer() called\n");
101 
102     Status = RpcServerUseProtseqEpW(L"ncacn_np",
103                                     10,
104                                     L"\\pipe\\lsarpc",
105                                     NULL);
106     if (Status != RPC_S_OK)
107     {
108         WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
109         return;
110     }
111 
112     Status = RpcServerRegisterIf(lsarpc_v0_0_s_ifspec,
113                                  NULL,
114                                  NULL);
115     if (Status != RPC_S_OK)
116     {
117         WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status);
118         return;
119     }
120 
121     Status = RpcServerListen(1, 20, TRUE);
122     if (Status != RPC_S_OK)
123     {
124         WARN("RpcServerListen() failed (Status %lx)\n", Status);
125         return;
126     }
127 
128     TRACE("LsarStartRpcServer() done\n");
129 }
130 
131 
132 void __RPC_USER LSAPR_HANDLE_rundown(LSAPR_HANDLE hHandle)
133 {
134 
135 }
136 
137 
138 /* Function 0 */
139 NTSTATUS LsarClose(
140     LSAPR_HANDLE *ObjectHandle)
141 {
142     NTSTATUS Status = STATUS_SUCCESS;
143 
144     TRACE("0x%p\n", ObjectHandle);
145 
146 //    RtlEnterCriticalSection(&PolicyHandleTableLock);
147 
148     if (LsapValidateDbHandle(*ObjectHandle, LsaDbIgnoreHandle))
149     {
150         RtlFreeHeap(RtlGetProcessHeap(), 0, *ObjectHandle);
151         *ObjectHandle = NULL;
152     }
153     else
154         Status = STATUS_INVALID_HANDLE;
155 
156 //    RtlLeaveCriticalSection(&PolicyHandleTableLock);
157 
158     return Status;
159 }
160 
161 
162 /* Function 1 */
163 NTSTATUS LsarDelete(
164     LSAPR_HANDLE ObjectHandle)
165 {
166     /* Deprecated */
167     return STATUS_NOT_SUPPORTED;
168 }
169 
170 
171 /* Function 2 */
172 NTSTATUS LsarEnumeratePrivileges(
173     LSAPR_HANDLE PolicyHandle,
174     DWORD *EnumerationContext,
175     PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
176     DWORD PreferedMaximumLength)
177 {
178     UNIMPLEMENTED;
179     return STATUS_NOT_IMPLEMENTED;
180 }
181 
182 
183 /* Function 3 */
184 NTSTATUS LsarQuerySecurityObject(
185     LSAPR_HANDLE ObjectHandle,
186     SECURITY_INFORMATION SecurityInformation,
187     PLSAPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor)
188 {
189     UNIMPLEMENTED;
190     return STATUS_NOT_IMPLEMENTED;
191 }
192 
193 
194 /* Function 4 */
195 NTSTATUS LsarSetSecurityObject(
196     LSAPR_HANDLE ObjectHandle,
197     SECURITY_INFORMATION SecurityInformation,
198     PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor)
199 {
200     UNIMPLEMENTED;
201     return STATUS_NOT_IMPLEMENTED;
202 }
203 
204 
205 /* Function 5 */
206 NTSTATUS LsarChangePassword(
207     handle_t IDL_handle,
208     PRPC_UNICODE_STRING String1,
209     PRPC_UNICODE_STRING String2,
210     PRPC_UNICODE_STRING String3,
211     PRPC_UNICODE_STRING String4,
212     PRPC_UNICODE_STRING String5)
213 {
214     /* Deprecated */
215     return STATUS_NOT_IMPLEMENTED;
216 }
217 
218 
219 /* Function 6 */
220 NTSTATUS LsarOpenPolicy(
221     LPWSTR SystemName,
222     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
223     ACCESS_MASK DesiredAccess,
224     LSAPR_HANDLE *PolicyHandle)
225 {
226     NTSTATUS Status = STATUS_SUCCESS;
227 
228     TRACE("LsarOpenPolicy called!\n");
229 
230     RtlEnterCriticalSection(&PolicyHandleTableLock);
231 
232     *PolicyHandle = LsapCreateDbHandle(LsaDbPolicyHandle,
233                                        DesiredAccess);
234     if (*PolicyHandle == NULL)
235         Status = STATUS_INSUFFICIENT_RESOURCES;
236 
237     RtlLeaveCriticalSection(&PolicyHandleTableLock);
238 
239     TRACE("LsarOpenPolicy done!\n");
240 
241     return Status;
242 }
243 
244 
245 /* Function 7 */
246 NTSTATUS LsarQueryInformationPolicy(
247     LSAPR_HANDLE PolicyHandle,
248     POLICY_INFORMATION_CLASS InformationClass,
249     PLSAPR_POLICY_INFORMATION *PolicyInformation)
250 {
251     UNIMPLEMENTED;
252     return STATUS_NOT_IMPLEMENTED;
253 }
254 
255 
256 /* Function 8 */
257 NTSTATUS LsarSetInformationPolicy(
258     LSAPR_HANDLE PolicyHandle,
259     POLICY_INFORMATION_CLASS InformationClass,
260     PLSAPR_POLICY_INFORMATION PolicyInformation)
261 {
262     UNIMPLEMENTED;
263     return STATUS_NOT_IMPLEMENTED;
264 }
265 
266 
267 /* Function 9 */
268 NTSTATUS LsarClearAuditLog(
269     LSAPR_HANDLE ObjectHandle)
270 {
271     /* Deprecated */
272     return STATUS_NOT_IMPLEMENTED;
273 }
274 
275 
276 /* Function 10 */
277 NTSTATUS LsarCreateAccount(
278     LSAPR_HANDLE PolicyHandle,
279     PRPC_SID AccountSid,
280     ACCESS_MASK DesiredAccess,
281     LSAPR_HANDLE *AccountHandle)
282 {
283     UNIMPLEMENTED;
284     return STATUS_NOT_IMPLEMENTED;
285 }
286 
287 
288 /* Function 11 */
289 NTSTATUS LsarEnumerateAccounts(
290     LSAPR_HANDLE PolicyHandle,
291     DWORD *EnumerationContext,
292     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer,
293     DWORD PreferedMaximumLength)
294 {
295     UNIMPLEMENTED;
296     return STATUS_NOT_IMPLEMENTED;
297 }
298 
299 
300 /* Function 12 */
301 NTSTATUS LsarCreateTrustedDomain(
302     LSAPR_HANDLE PolicyHandle,
303     PLSAPR_TRUST_INFORMATION TrustedDomainInformation,
304     ACCESS_MASK DesiredAccess,
305     LSAPR_HANDLE *TrustedDomainHandle)
306 {
307     UNIMPLEMENTED;
308     return STATUS_NOT_IMPLEMENTED;
309 }
310 
311 
312 /* Function 13 */
313 NTSTATUS LsarEnumerateTrustedDomains(
314     LSAPR_HANDLE PolicyHandle,
315     DWORD *EnumerationContext,
316     PLSAPR_TRUSTED_ENUM_BUFFER EnumerationBuffer,
317     DWORD PreferedMaximumLength)
318 {
319     UNIMPLEMENTED;
320     return STATUS_NOT_IMPLEMENTED;
321 }
322 
323 
324 /* Function 14 */
325 NTSTATUS LsarLookupNames(
326     LSAPR_HANDLE PolicyHandle,
327     DWORD Count,
328     PRPC_UNICODE_STRING Names,
329     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
330     PLSAPR_TRANSLATED_SIDS TranslatedSids,
331     LSAP_LOOKUP_LEVEL LookupLevel,
332     DWORD *MappedCount)
333 {
334     SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
335     static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
336     PLSAPR_REFERENCED_DOMAIN_LIST OutputDomains = NULL;
337     PLSA_TRANSLATED_SID OutputSids = NULL;
338     ULONG OutputSidsLength;
339     ULONG i;
340     PSID Sid;
341     ULONG SidLength;
342     NTSTATUS Status;
343 
344     TRACE("LsarLookupNames(%p, %lu, %p, %p, %p, %d, %p)\n",
345           PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
346           LookupLevel, MappedCount);
347 
348     TranslatedSids->Entries = Count;
349     TranslatedSids->Sids = NULL;
350     *ReferencedDomains = NULL;
351 
352     OutputSidsLength = Count * sizeof(LSA_TRANSLATED_SID);
353     OutputSids = MIDL_user_allocate(OutputSidsLength);
354     if (OutputSids == NULL)
355     {
356         return STATUS_INSUFFICIENT_RESOURCES;
357     }
358 
359     RtlZeroMemory(OutputSids, OutputSidsLength);
360 
361     OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
362     if (OutputDomains == NULL)
363     {
364         MIDL_user_free(OutputSids);
365         return STATUS_INSUFFICIENT_RESOURCES;
366     }
367 
368     OutputDomains->Entries = Count;
369     OutputDomains->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
370     if (OutputDomains->Domains == NULL)
371     {
372         MIDL_user_free(OutputDomains);
373         MIDL_user_free(OutputSids);
374         return STATUS_INSUFFICIENT_RESOURCES;
375     }
376 
377     Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
378                                          2,
379                                          SECURITY_BUILTIN_DOMAIN_RID,
380                                          DOMAIN_ALIAS_RID_ADMINS,
381                                          0, 0, 0, 0, 0, 0,
382                                          &Sid);
383     if (!NT_SUCCESS(Status))
384     {
385         MIDL_user_free(OutputDomains->Domains);
386         MIDL_user_free(OutputDomains);
387         MIDL_user_free(OutputSids);
388         return Status;
389     }
390 
391     SidLength = RtlLengthSid(Sid);
392 
393     for (i = 0; i < Count; i++)
394     {
395         OutputDomains->Domains[i].Sid = MIDL_user_allocate(SidLength);
396         RtlCopyMemory(OutputDomains->Domains[i].Sid, Sid, SidLength);
397 
398         OutputDomains->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
399         OutputDomains->Domains[i].Name.Length = DomainName.Length;
400         OutputDomains->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
401         RtlCopyMemory(OutputDomains->Domains[i].Name.Buffer, DomainName.Buffer, DomainName.MaximumLength);
402     }
403 
404     for (i = 0; i < Count; i++)
405     {
406         OutputSids[i].Use = SidTypeWellKnownGroup;
407         OutputSids[i].RelativeId = DOMAIN_ALIAS_RID_ADMINS;
408         OutputSids[i].DomainIndex = i;
409     }
410 
411     *ReferencedDomains = OutputDomains;
412 
413     *MappedCount = Count;
414 
415     TranslatedSids->Entries = Count;
416     TranslatedSids->Sids = OutputSids;
417 
418     return STATUS_SUCCESS;
419 }
420 
421 
422 /* Function 15 */
423 NTSTATUS LsarLookupSids(
424     LSAPR_HANDLE PolicyHandle,
425     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
426     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
427     PLSAPR_TRANSLATED_NAMES TranslatedNames,
428     LSAP_LOOKUP_LEVEL LookupLevel,
429     DWORD *MappedCount)
430 {
431     SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
432     static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
433     PLSAPR_REFERENCED_DOMAIN_LIST OutputDomains = NULL;
434     PLSAPR_TRANSLATED_NAME OutputNames = NULL;
435     ULONG OutputNamesLength;
436     ULONG i;
437     PSID Sid;
438     ULONG SidLength;
439     NTSTATUS Status;
440 
441     TRACE("LsarLookupSids(%p, %p, %p, %p, %d, %p)\n",
442           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
443           LookupLevel, MappedCount);
444 
445     TranslatedNames->Entries = SidEnumBuffer->Entries;
446     TranslatedNames->Names = NULL;
447     *ReferencedDomains = NULL;
448 
449     OutputNamesLength = SidEnumBuffer->Entries * sizeof(LSA_TRANSLATED_NAME);
450     OutputNames = MIDL_user_allocate(OutputNamesLength);
451     if (OutputNames == NULL)
452     {
453         return STATUS_INSUFFICIENT_RESOURCES;
454     }
455 
456     RtlZeroMemory(OutputNames, OutputNamesLength);
457 
458     OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
459     if (OutputDomains == NULL)
460     {
461         MIDL_user_free(OutputNames);
462         return STATUS_INSUFFICIENT_RESOURCES;
463     }
464 
465     OutputDomains->Entries = SidEnumBuffer->Entries;
466     OutputDomains->Domains = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSA_TRUST_INFORMATION));
467     if (OutputDomains->Domains == NULL)
468     {
469         MIDL_user_free(OutputDomains);
470         MIDL_user_free(OutputNames);
471         return STATUS_INSUFFICIENT_RESOURCES;
472     }
473 
474     Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
475                                          2,
476                                          SECURITY_BUILTIN_DOMAIN_RID,
477                                          DOMAIN_ALIAS_RID_ADMINS,
478                                          0, 0, 0, 0, 0, 0,
479                                          &Sid);
480     if (!NT_SUCCESS(Status))
481     {
482         MIDL_user_free(OutputDomains->Domains);
483         MIDL_user_free(OutputDomains);
484         MIDL_user_free(OutputNames);
485         return Status;
486     }
487 
488     SidLength = RtlLengthSid(Sid);
489 
490     for (i = 0; i < SidEnumBuffer->Entries; i++)
491     {
492         OutputDomains->Domains[i].Sid = MIDL_user_allocate(SidLength);
493         RtlCopyMemory(OutputDomains->Domains[i].Sid, Sid, SidLength);
494 
495         OutputDomains->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
496         OutputDomains->Domains[i].Name.Length = DomainName.Length;
497         OutputDomains->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
498         RtlCopyMemory(OutputDomains->Domains[i].Name.Buffer, DomainName.Buffer, DomainName.MaximumLength);
499     }
500 
501     Status = LsapLookupSids(SidEnumBuffer,
502                             OutputNames);
503 
504     *ReferencedDomains = OutputDomains;
505 
506     *MappedCount = SidEnumBuffer->Entries;
507 
508     TranslatedNames->Entries = SidEnumBuffer->Entries;
509     TranslatedNames->Names = OutputNames;
510 
511     return Status;
512 }
513 
514 
515 /* Function 16 */
516 NTSTATUS LsarCreateSecret(
517     LSAPR_HANDLE PolicyHandle,
518     PRPC_UNICODE_STRING SecretName,
519     ACCESS_MASK DesiredAccess,
520     LSAPR_HANDLE *SecretHandle)
521 {
522     UNIMPLEMENTED;
523     return STATUS_NOT_IMPLEMENTED;
524 }
525 
526 
527 /* Function 17 */
528 NTSTATUS LsarOpenAccount(
529     LSAPR_HANDLE PolicyHandle,
530     PRPC_SID AccountSid,
531     ACCESS_MASK DesiredAccess,
532     LSAPR_HANDLE *AccountHandle)
533 {
534     UNIMPLEMENTED;
535     return STATUS_NOT_IMPLEMENTED;
536 }
537 
538 
539 /* Function 18 */
540 NTSTATUS LsarEnumeratePrivilegesAccount(
541     LSAPR_HANDLE AccountHandle,
542     PLSAPR_PRIVILEGE_SET *Privileges)
543 {
544     UNIMPLEMENTED;
545     return STATUS_NOT_IMPLEMENTED;
546 }
547 
548 
549 /* Function 19 */
550 NTSTATUS LsarAddPrivilegesToAccount(
551     LSAPR_HANDLE AccountHandle,
552     PLSAPR_PRIVILEGE_SET Privileges)
553 {
554     UNIMPLEMENTED;
555     return STATUS_NOT_IMPLEMENTED;
556 }
557 
558 
559 /* Function 20 */
560 NTSTATUS LsarRemovePrivilegesFromAccount(
561     LSAPR_HANDLE AccountHandle,
562     BOOL AllPrivileges,
563     PLSAPR_PRIVILEGE_SET Privileges)
564 {
565     UNIMPLEMENTED;
566     return STATUS_NOT_IMPLEMENTED;
567 }
568 
569 
570 /* Function 21 */
571 NTSTATUS LsarGetQuotasForAccount(
572     LSAPR_HANDLE AccountHandle,
573     PQUOTA_LIMITS QuotaLimits)
574 {
575     UNIMPLEMENTED;
576     return STATUS_NOT_IMPLEMENTED;
577 }
578 
579 
580 /* Function 22 */
581 NTSTATUS LsarSetQuotasForAccount(
582     LSAPR_HANDLE AccountHandle,
583     PQUOTA_LIMITS QuotaLimits)
584 {
585     UNIMPLEMENTED;
586     return STATUS_NOT_IMPLEMENTED;
587 }
588 
589 
590 /* Function 23 */
591 NTSTATUS LsarGetSystemAccessAccount(
592     LSAPR_HANDLE AccountHandle,
593     ACCESS_MASK *SystemAccess)
594 {
595     UNIMPLEMENTED;
596     return STATUS_NOT_IMPLEMENTED;
597 }
598 
599 
600 /* Function 24 */
601 NTSTATUS LsarSetSystemAccessAccount(
602     LSAPR_HANDLE AccountHandle,
603     ACCESS_MASK SystemAccess)
604 {
605     UNIMPLEMENTED;
606     return STATUS_NOT_IMPLEMENTED;
607 }
608 
609 
610 /* Function 25 */
611 NTSTATUS LsarOpenTrustedDomain(
612     LSAPR_HANDLE PolicyHandle,
613     PRPC_SID TrustedDomainSid,
614     ACCESS_MASK DesiredAccess,
615     LSAPR_HANDLE *TrustedDomainHandle)
616 {
617     UNIMPLEMENTED;
618     return STATUS_NOT_IMPLEMENTED;
619 }
620 
621 
622 /* Function 26 */
623 NTSTATUS LsarQueryInfoTrustedDomain(
624     LSAPR_HANDLE TrustedDomainHandle,
625     TRUSTED_INFORMATION_CLASS InformationClass,
626     PLSAPR_TRUSTED_DOMAIN_INFO *TrustedDomainInformation)
627 {
628     UNIMPLEMENTED;
629     return STATUS_NOT_IMPLEMENTED;
630 }
631 
632 
633 /* Function 27 */
634 NTSTATUS LsarSetInformationTrustedDomain(
635     LSAPR_HANDLE TrustedDomainHandle,
636     TRUSTED_INFORMATION_CLASS InformationClass,
637     PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainInformation)
638 {
639     UNIMPLEMENTED;
640     return STATUS_NOT_IMPLEMENTED;
641 }
642 
643 
644 /* Function 28 */
645 NTSTATUS LsarOpenSecret(
646     LSAPR_HANDLE PolicyHandle,
647     PRPC_UNICODE_STRING SecretName,
648     ACCESS_MASK DesiredAccess,
649     LSAPR_HANDLE *SecretHandle)
650 {
651     UNIMPLEMENTED;
652     return STATUS_NOT_IMPLEMENTED;
653 }
654 
655 
656 /* Function 29 */
657 NTSTATUS LsarSetSecret(
658     LSAPR_HANDLE *SecretHandle,
659     PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue,
660     PLSAPR_CR_CIPHER_VALUE EncryptedOldValue)
661 {
662     UNIMPLEMENTED;
663     return STATUS_NOT_IMPLEMENTED;
664 }
665 
666 
667 /* Function 30 */
668 NTSTATUS LsarQuerySecret(
669     LSAPR_HANDLE SecretHandle,
670     PLSAPR_CR_CIPHER_VALUE *EncryptedCurrentValue,
671     PLARGE_INTEGER CurrentValueSetTime,
672     PLSAPR_CR_CIPHER_VALUE *EncryptedOldValue,
673     PLARGE_INTEGER OldValueSetTime)
674 {
675     UNIMPLEMENTED;
676     return STATUS_NOT_IMPLEMENTED;
677 }
678 
679 
680 /* Function 31 */
681 NTSTATUS LsarLookupPrivilegeValue(
682     LSAPR_HANDLE PolicyHandle,
683     PRPC_UNICODE_STRING Name,
684     PLUID Value)
685 {
686     NTSTATUS Status;
687 
688     TRACE("LsarLookupPrivilegeValue(%p, %wZ, %p)\n",
689           PolicyHandle, Name, Value);
690 
691     if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
692     {
693         ERR("Invalid handle\n");
694         return STATUS_INVALID_HANDLE;
695     }
696 
697     TRACE("Privilege: %wZ\n", Name);
698 
699     Status = LsarpLookupPrivilegeValue((PUNICODE_STRING)Name,
700                                        Value);
701 
702     return Status;
703 }
704 
705 
706 /* Function 32 */
707 NTSTATUS LsarLookupPrivilegeName(
708     LSAPR_HANDLE PolicyHandle,
709     PLUID Value,
710     PRPC_UNICODE_STRING *Name)
711 {
712     NTSTATUS Status;
713 
714     TRACE("LsarLookupPrivilegeName(%p, %p, %p)\n",
715           PolicyHandle, Value, Name);
716 
717     if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
718     {
719         ERR("Invalid handle\n");
720         return STATUS_INVALID_HANDLE;
721     }
722 
723     Status = LsarpLookupPrivilegeName(Value, (PUNICODE_STRING*)Name);
724 
725     return Status;
726 }
727 
728 
729 /* Function 33 */
730 NTSTATUS LsarLookupPrivilegeDisplayName(
731     LSAPR_HANDLE PolicyHandle,
732     PRPC_UNICODE_STRING Name,
733     USHORT ClientLanguage,
734     USHORT ClientSystemDefaultLanguage,
735     PRPC_UNICODE_STRING *DisplayName,
736     USHORT *LanguageReturned)
737 {
738     UNIMPLEMENTED;
739     return STATUS_NOT_IMPLEMENTED;
740 }
741 
742 
743 /* Function 34 */
744 NTSTATUS LsarDeleteObject(
745     LSAPR_HANDLE *ObjectHandle)
746 {
747     UNIMPLEMENTED;
748     return STATUS_NOT_IMPLEMENTED;
749 }
750 
751 
752 /* Function 35 */
753 NTSTATUS LsarEnumerateAccountsWithUserRight(
754     LSAPR_HANDLE PolicyHandle,
755     PRPC_UNICODE_STRING UserRight,
756     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer)
757 {
758     UNIMPLEMENTED;
759     return STATUS_NOT_IMPLEMENTED;
760 }
761 
762 
763 /* Function 36 */
764 NTSTATUS LsarEnmuerateAccountRights(
765     LSAPR_HANDLE PolicyHandle,
766     PRPC_SID AccountSid,
767     PLSAPR_USER_RIGHT_SET UserRights)
768 {
769     FIXME("(%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights);
770 
771     if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
772         return STATUS_INVALID_HANDLE;
773 
774     UserRights->Entries = 0;
775     UserRights->UserRights = NULL;
776     return STATUS_OBJECT_NAME_NOT_FOUND;
777 }
778 
779 
780 /* Function 37 */
781 NTSTATUS LsarAddAccountRights(
782     LSAPR_HANDLE PolicyHandle,
783     PRPC_SID AccountSid,
784     PLSAPR_USER_RIGHT_SET UserRights)
785 {
786     UNIMPLEMENTED;
787     return STATUS_NOT_IMPLEMENTED;
788 }
789 
790 
791 /* Function 38 */
792 NTSTATUS LsarRemoveAccountRights(
793     LSAPR_HANDLE PolicyHandle,
794     PRPC_SID AccountSid,
795     BOOL AllRights,
796     PLSAPR_USER_RIGHT_SET UserRights)
797 {
798     UNIMPLEMENTED;
799     return STATUS_NOT_IMPLEMENTED;
800 }
801 
802 
803 /* Function 39 */
804 NTSTATUS LsarQueryTrustedDomainInfo(
805     LSAPR_HANDLE PolicyHandle,
806     PRPC_SID TrustedDomainSid,
807     TRUSTED_INFORMATION_CLASS InformationClass,
808     PLSAPR_TRUSTED_DOMAIN_INFO *TrustedDomainInformation)
809 {
810     UNIMPLEMENTED;
811     return STATUS_NOT_IMPLEMENTED;
812 }
813 
814 
815 /* Function 40 */
816 NTSTATUS LsarSetTrustedDomainInfo(
817     LSAPR_HANDLE PolicyHandle,
818     PRPC_SID TrustedDomainSid,
819     TRUSTED_INFORMATION_CLASS InformationClass,
820     PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainInformation)
821 {
822     UNIMPLEMENTED;
823     return STATUS_NOT_IMPLEMENTED;
824 }
825 
826 
827 /* Function 41 */
828 NTSTATUS LsarDeleteTrustedDomain(
829     LSAPR_HANDLE PolicyHandle,
830     PRPC_SID TrustedDomainSid)
831 {
832     UNIMPLEMENTED;
833     return STATUS_NOT_IMPLEMENTED;
834 }
835 
836 
837 /* Function 42 */
838 NTSTATUS LsarStorePrivateData(
839     LSAPR_HANDLE PolicyHandle,
840     PRPC_UNICODE_STRING KeyName,
841     PLSAPR_CR_CIPHER_VALUE EncryptedData)
842 {
843     UNIMPLEMENTED;
844     return STATUS_NOT_IMPLEMENTED;
845 }
846 
847 
848 /* Function 43 */
849 NTSTATUS LsarRetrievePrivateData(
850     LSAPR_HANDLE PolicyHandle,
851     PRPC_UNICODE_STRING KeyName,
852     PLSAPR_CR_CIPHER_VALUE *EncryptedData)
853 {
854     UNIMPLEMENTED;
855     return STATUS_NOT_IMPLEMENTED;
856 }
857 
858 
859 /* Function 44 */
860 NTSTATUS LsarOpenPolicy2(
861     LPWSTR SystemName,
862     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
863     ACCESS_MASK DesiredAccess,
864     LSAPR_HANDLE *PolicyHandle)
865 {
866     UNIMPLEMENTED;
867     return STATUS_NOT_IMPLEMENTED;
868 }
869 
870 
871 /* Function 45 */
872 NTSTATUS LsarGetUserName(
873     LPWSTR SystemName,
874     PRPC_UNICODE_STRING *UserName,
875     PRPC_UNICODE_STRING *DomainName)
876 {
877     UNIMPLEMENTED;
878     return STATUS_NOT_IMPLEMENTED;
879 }
880 
881 
882 /* Function 46 */
883 NTSTATUS LsarQueryInformationPolicy2(
884     LSAPR_HANDLE PolicyHandle,
885     POLICY_INFORMATION_CLASS InformationClass,
886     unsigned long *PolicyInformation)
887 {
888     UNIMPLEMENTED;
889     return STATUS_NOT_IMPLEMENTED;
890 }
891 
892 
893 /* Function 47 */
894 NTSTATUS LsarSetInformationPolicy2(
895     LSAPR_HANDLE PolicyHandle,
896     POLICY_INFORMATION_CLASS InformationClass,
897     unsigned long PolicyInformation)
898 {
899     UNIMPLEMENTED;
900     return STATUS_NOT_IMPLEMENTED;
901 }
902 
903 
904 /* Function 48 */
905 NTSTATUS LsarQueryTrustedDomainInfoByName(
906     LSAPR_HANDLE PolicyHandle,
907     PRPC_UNICODE_STRING TrustedDomainName,
908     POLICY_INFORMATION_CLASS InformationClass,
909     unsigned long *PolicyInformation)
910 {
911     UNIMPLEMENTED;
912     return STATUS_NOT_IMPLEMENTED;
913 }
914 
915 
916 /* Function 49 */
917 NTSTATUS LsarSetTrustedDomainInfoByName(
918     LSAPR_HANDLE PolicyHandle,
919     PRPC_UNICODE_STRING TrustedDomainName,
920     POLICY_INFORMATION_CLASS InformationClass,
921     unsigned long PolicyInformation)
922 {
923     UNIMPLEMENTED;
924     return STATUS_NOT_IMPLEMENTED;
925 }
926 
927 
928 /* Function 50 */
929 NTSTATUS LsarEnumerateTrustedDomainsEx(
930     LSAPR_HANDLE PolicyHandle,
931     DWORD *EnumerationContext,
932     PLSAPR_TRUSTED_ENUM_BUFFER_EX EnumerationBuffer,
933     DWORD PreferedMaximumLength)
934 {
935     UNIMPLEMENTED;
936     return STATUS_NOT_IMPLEMENTED;
937 }
938 
939 
940 /* Function 51 */
941 NTSTATUS LsarCreateTrustedDomainEx(
942     LSAPR_HANDLE PolicyHandle,
943     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
944     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION AuthentificationInformation,
945     ACCESS_MASK DesiredAccess,
946     LSAPR_HANDLE *TrustedDomainHandle)
947 {
948     UNIMPLEMENTED;
949     return STATUS_NOT_IMPLEMENTED;
950 }
951 
952 
953 /* Function 52 */
954 NTSTATUS LsarSetPolicyReplicationHandle(
955     PLSAPR_HANDLE PolicyHandle)
956 {
957     /* Deprecated */
958     return STATUS_NOT_IMPLEMENTED;
959 }
960 
961 
962 /* Function 53 */
963 NTSTATUS LsarQueryDomainInformationPolicy(
964     LSAPR_HANDLE PolicyHandle,
965     POLICY_INFORMATION_CLASS InformationClass,
966     unsigned long *PolicyInformation)
967 {
968     UNIMPLEMENTED;
969     return STATUS_NOT_IMPLEMENTED;
970 }
971 
972 
973 /* Function 54 */
974 NTSTATUS LsarSetDomainInformationPolicy(
975     LSAPR_HANDLE PolicyHandle,
976     POLICY_INFORMATION_CLASS InformationClass,
977     unsigned long PolicyInformation)
978 {
979     UNIMPLEMENTED;
980     return STATUS_NOT_IMPLEMENTED;
981 }
982 
983 
984 /* Function 55 */
985 NTSTATUS LsarOpenTrustedDomainByName(
986     LSAPR_HANDLE PolicyHandle,
987     PRPC_UNICODE_STRING TrustedDomainName,
988     ACCESS_MASK DesiredAccess,
989     LSAPR_HANDLE *TrustedDomainHandle)
990 {
991     UNIMPLEMENTED;
992     return STATUS_NOT_IMPLEMENTED;
993 }
994 
995 
996 /* Function 56 */
997 NTSTATUS LsarTestCall(
998     handle_t hBinding)
999 {
1000     UNIMPLEMENTED;
1001     return STATUS_NOT_IMPLEMENTED;
1002 }
1003 
1004 
1005 /* Function 57 */
1006 NTSTATUS LsarLookupSids2(
1007     LSAPR_HANDLE PolicyHandle,
1008     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
1009     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1010     PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
1011     LSAP_LOOKUP_LEVEL LookupLevel,
1012     DWORD *MappedCount,
1013     DWORD LookupOptions,
1014     DWORD ClientRevision)
1015 {
1016     UNIMPLEMENTED;
1017     return STATUS_NOT_IMPLEMENTED;
1018 }
1019 
1020 
1021 /* Function 58 */
1022 NTSTATUS LsarLookupNames2(
1023     LSAPR_HANDLE PolicyHandle,
1024     DWORD Count,
1025     PRPC_UNICODE_STRING Names,
1026     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1027     PLSAPR_TRANSLATED_SID_EX TranslatedSids,
1028     LSAP_LOOKUP_LEVEL LookupLevel,
1029     DWORD *MappedCount,
1030     DWORD LookupOptions,
1031     DWORD ClientRevision)
1032 {
1033     UNIMPLEMENTED;
1034     return STATUS_NOT_IMPLEMENTED;
1035 }
1036 
1037 
1038 /* Function 59 */
1039 NTSTATUS LsarCreateTrustedDomainEx2(
1040     LSAPR_HANDLE PolicyHandle,
1041     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
1042     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL AuthentificationInformation,
1043     ACCESS_MASK DesiredAccess,
1044     LSAPR_HANDLE *TrustedDomainHandle)
1045 {
1046     UNIMPLEMENTED;
1047     return STATUS_NOT_IMPLEMENTED;
1048 }
1049 
1050 
1051 /* Function 60 */
1052 NTSTATUS CredrWrite(
1053     handle_t hBinding)
1054 {
1055     UNIMPLEMENTED;
1056     return STATUS_NOT_IMPLEMENTED;
1057 }
1058 
1059 
1060 /* Function 61 */
1061 NTSTATUS CredrRead(
1062     handle_t hBinding)
1063 {
1064     UNIMPLEMENTED;
1065     return STATUS_NOT_IMPLEMENTED;
1066 }
1067 
1068 
1069 /* Function 62 */
1070 NTSTATUS CredrEnumerate(
1071     handle_t hBinding)
1072 {
1073     UNIMPLEMENTED;
1074     return STATUS_NOT_IMPLEMENTED;
1075 }
1076 
1077 
1078 /* Function 63 */
1079 NTSTATUS CredrWriteDomainCredentials(
1080     handle_t hBinding)
1081 {
1082     UNIMPLEMENTED;
1083     return STATUS_NOT_IMPLEMENTED;
1084 }
1085 
1086 
1087 /* Function 64 */
1088 NTSTATUS CredrReadDomainCredentials(
1089     handle_t hBinding)
1090 {
1091     UNIMPLEMENTED;
1092     return STATUS_NOT_IMPLEMENTED;
1093 }
1094 
1095 
1096 /* Function 65 */
1097 NTSTATUS CredrDelete(
1098     handle_t hBinding)
1099 {
1100     UNIMPLEMENTED;
1101     return STATUS_NOT_IMPLEMENTED;
1102 }
1103 
1104 
1105 /* Function 66 */
1106 NTSTATUS CredrGetTargetInfo(
1107     handle_t hBinding)
1108 {
1109     UNIMPLEMENTED;
1110     return STATUS_NOT_IMPLEMENTED;
1111 }
1112 
1113 
1114 /* Function 67 */
1115 NTSTATUS CredrProfileLoaded(
1116     handle_t hBinding)
1117 {
1118     UNIMPLEMENTED;
1119     return STATUS_NOT_IMPLEMENTED;
1120 }
1121 
1122 
1123 /* Function 68 */
1124 NTSTATUS LsarLookupNames3(
1125     LSAPR_HANDLE PolicyHandle,
1126     DWORD Count,
1127     PRPC_UNICODE_STRING Names,
1128     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1129     PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
1130     LSAP_LOOKUP_LEVEL LookupLevel,
1131     DWORD *MappedCount,
1132     DWORD LookupOptions,
1133     DWORD ClientRevision)
1134 {
1135     UNIMPLEMENTED;
1136     return STATUS_NOT_IMPLEMENTED;
1137 }
1138 
1139 
1140 /* Function 69 */
1141 NTSTATUS CredrGetSessionTypes(
1142     handle_t hBinding)
1143 {
1144     UNIMPLEMENTED;
1145     return STATUS_NOT_IMPLEMENTED;
1146 }
1147 
1148 
1149 /* Function 70 */
1150 NTSTATUS LsarRegisterAuditEvent(
1151     handle_t hBinding)
1152 {
1153     UNIMPLEMENTED;
1154     return STATUS_NOT_IMPLEMENTED;
1155 }
1156 
1157 
1158 /* Function 71 */
1159 NTSTATUS LsarGenAuditEvent(
1160     handle_t hBinding)
1161 {
1162     UNIMPLEMENTED;
1163     return STATUS_NOT_IMPLEMENTED;
1164 }
1165 
1166 
1167 /* Function 72 */
1168 NTSTATUS LsarUnregisterAuditEvent(
1169     handle_t hBinding)
1170 {
1171     UNIMPLEMENTED;
1172     return STATUS_NOT_IMPLEMENTED;
1173 }
1174 
1175 
1176 /* Function 73 */
1177 NTSTATUS LsarQueryForestTrustInformation(
1178     LSAPR_HANDLE PolicyHandle,
1179     PLSA_UNICODE_STRING TrustedDomainName,
1180     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
1181     PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
1182 {
1183     UNIMPLEMENTED;
1184     return STATUS_NOT_IMPLEMENTED;
1185 }
1186 
1187 
1188 /* Function 74 */
1189 NTSTATUS LsarSetForestTrustInformation(
1190     LSAPR_HANDLE PolicyHandle,
1191     PLSA_UNICODE_STRING TrustedDomainName,
1192     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
1193     PLSA_FOREST_TRUST_INFORMATION ForestTrustInfo,
1194     BOOL CheckOnly,
1195     PLSA_FOREST_TRUST_COLLISION_INFORMATION *CollisionInfo)
1196 {
1197     UNIMPLEMENTED;
1198     return STATUS_NOT_IMPLEMENTED;
1199 }
1200 
1201 
1202 /* Function 75 */
1203 NTSTATUS CredrRename(
1204     handle_t hBinding)
1205 {
1206     UNIMPLEMENTED;
1207     return STATUS_NOT_IMPLEMENTED;
1208 }
1209 
1210 
1211 /* Function 76 */
1212 NTSTATUS LsarLookupSids3(
1213     LSAPR_HANDLE PolicyHandle,
1214     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
1215     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1216     PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
1217     LSAP_LOOKUP_LEVEL LookupLevel,
1218     DWORD *MappedCount,
1219     DWORD LookupOptions,
1220     DWORD ClientRevision)
1221 {
1222     UNIMPLEMENTED;
1223     return STATUS_NOT_IMPLEMENTED;
1224 }
1225 
1226 
1227 /* Function 77 */
1228 NTSTATUS LsarLookupNames4(
1229     handle_t RpcHandle,
1230     DWORD Count,
1231     PRPC_UNICODE_STRING Names,
1232     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1233     PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
1234     LSAP_LOOKUP_LEVEL LookupLevel,
1235     DWORD *MappedCount,
1236     DWORD LookupOptions,
1237     DWORD ClientRevision)
1238 {
1239     UNIMPLEMENTED;
1240     return STATUS_NOT_IMPLEMENTED;
1241 }
1242 
1243 
1244 /* Function 78 */
1245 NTSTATUS LsarOpenPolicySce(
1246     handle_t hBinding)
1247 {
1248     UNIMPLEMENTED;
1249     return STATUS_NOT_IMPLEMENTED;
1250 }
1251 
1252 
1253 /* Function 79 */
1254 NTSTATUS LsarAdtRegisterSecurityEventSource(
1255     handle_t hBinding)
1256 {
1257     UNIMPLEMENTED;
1258     return STATUS_NOT_IMPLEMENTED;
1259 }
1260 
1261 
1262 /* Function 80 */
1263 NTSTATUS LsarAdtUnregisterSecurityEventSource(
1264     handle_t hBinding)
1265 {
1266     UNIMPLEMENTED;
1267     return STATUS_NOT_IMPLEMENTED;
1268 }
1269 
1270 
1271 /* Function 81 */
1272 NTSTATUS LsarAdtReportSecurityEvent(
1273     handle_t hBinding)
1274 {
1275     UNIMPLEMENTED;
1276     return STATUS_NOT_IMPLEMENTED;
1277 }
1278 
1279 
1280 /* Function 82 */
1281 NTSTATUS CredrFindBestCredential(
1282     handle_t hBinding)
1283 {
1284     UNIMPLEMENTED;
1285     return STATUS_NOT_IMPLEMENTED;
1286 }
1287 
1288 
1289 /* Function 83 */
1290 NTSTATUS LsarSetAuditPolicy(
1291     handle_t hBinding)
1292 {
1293     UNIMPLEMENTED;
1294     return STATUS_NOT_IMPLEMENTED;
1295 }
1296 
1297 
1298 /* Function 84 */
1299 NTSTATUS LsarQueryAuditPolicy(
1300     handle_t hBinding)
1301 {
1302     UNIMPLEMENTED;
1303     return STATUS_NOT_IMPLEMENTED;
1304 }
1305 
1306 
1307 /* Function 85 */
1308 NTSTATUS LsarEnumerateAuditPolicy(
1309     handle_t hBinding)
1310 {
1311     UNIMPLEMENTED;
1312     return STATUS_NOT_IMPLEMENTED;
1313 }
1314 
1315 
1316 /* Function 86 */
1317 NTSTATUS LsarEnumerateAuditCategories(
1318     handle_t hBinding)
1319 {
1320     UNIMPLEMENTED;
1321     return STATUS_NOT_IMPLEMENTED;
1322 }
1323 
1324 
1325 /* Function 87 */
1326 NTSTATUS LsarEnumerateAuditSubCategories(
1327     handle_t hBinding)
1328 {
1329     UNIMPLEMENTED;
1330     return STATUS_NOT_IMPLEMENTED;
1331 }
1332 
1333 
1334 /* Function 88 */
1335 NTSTATUS LsarLookupAuditCategoryName(
1336     handle_t hBinding)
1337 {
1338     UNIMPLEMENTED;
1339     return STATUS_NOT_IMPLEMENTED;
1340 }
1341 
1342 
1343 /* Function 89 */
1344 NTSTATUS LsarLookupAuditSubCategoryName(
1345     handle_t hBinding)
1346 {
1347     UNIMPLEMENTED;
1348     return STATUS_NOT_IMPLEMENTED;
1349 }
1350 
1351 
1352 /* Function 90 */
1353 NTSTATUS LsarSetAuditSecurity(
1354     handle_t hBinding)
1355 {
1356     UNIMPLEMENTED;
1357     return STATUS_NOT_IMPLEMENTED;
1358 }
1359 
1360 
1361 /* Function 91 */
1362 NTSTATUS LsarQueryAuditSecurity(
1363     handle_t hBinding)
1364 {
1365     UNIMPLEMENTED;
1366     return STATUS_NOT_IMPLEMENTED;
1367 }
1368 
1369 
1370 /* Function 92 */
1371 NTSTATUS CredReadByTokenHandle(
1372     handle_t hBinding)
1373 {
1374     UNIMPLEMENTED;
1375     return STATUS_NOT_IMPLEMENTED;
1376 }
1377 
1378 
1379 /* Function 93 */
1380 NTSTATUS CredrRestoreCredentials(
1381     handle_t hBinding)
1382 {
1383     UNIMPLEMENTED;
1384     return STATUS_NOT_IMPLEMENTED;
1385 }
1386 
1387 
1388 /* Function 94 */
1389 NTSTATUS CredrBackupCredentials(
1390     handle_t hBinding)
1391 {
1392     UNIMPLEMENTED;
1393     return STATUS_NOT_IMPLEMENTED;
1394 }
1395 
1396 /* EOF */
1397