[SAMLIB]
[reactos.git] / reactos / dll / win32 / samlib / samlib.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * PURPOSE: SAM interface library
23 * FILE: lib/samlib/samlib.c
24 * PROGRAMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include "precomp.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(samlib);
32
33 NTSTATUS
34 WINAPI
35 SystemFunction006(LPCSTR password,
36 LPSTR hash);
37
38 NTSTATUS
39 WINAPI
40 SystemFunction007(PUNICODE_STRING string,
41 LPBYTE hash);
42
43 /* GLOBALS *******************************************************************/
44
45
46 /* FUNCTIONS *****************************************************************/
47
48 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
49 {
50 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
51 }
52
53
54 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
55 {
56 HeapFree(GetProcessHeap(), 0, ptr);
57 }
58
59
60 handle_t __RPC_USER
61 PSAMPR_SERVER_NAME_bind(PSAMPR_SERVER_NAME pszSystemName)
62 {
63 handle_t hBinding = NULL;
64 LPWSTR pszStringBinding;
65 RPC_STATUS status;
66
67 TRACE("PSAMPR_SERVER_NAME_bind() called\n");
68
69 status = RpcStringBindingComposeW(NULL,
70 L"ncacn_np",
71 pszSystemName,
72 L"\\pipe\\samr",
73 NULL,
74 &pszStringBinding);
75 if (status)
76 {
77 TRACE("RpcStringBindingCompose returned 0x%x\n", status);
78 return NULL;
79 }
80
81 /* Set the binding handle that will be used to bind to the server. */
82 status = RpcBindingFromStringBindingW(pszStringBinding,
83 &hBinding);
84 if (status)
85 {
86 TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
87 }
88
89 status = RpcStringFreeW(&pszStringBinding);
90 if (status)
91 {
92 // TRACE("RpcStringFree returned 0x%x\n", status);
93 }
94
95 return hBinding;
96 }
97
98
99 void __RPC_USER
100 PSAMPR_SERVER_NAME_unbind(PSAMPR_SERVER_NAME pszSystemName,
101 handle_t hBinding)
102 {
103 RPC_STATUS status;
104
105 TRACE("PSAMPR_SERVER_NAME_unbind() called\n");
106
107 status = RpcBindingFree(&hBinding);
108 if (status)
109 {
110 TRACE("RpcBindingFree returned 0x%x\n", status);
111 }
112 }
113
114
115 NTSTATUS
116 SampCheckPassword(IN SAMPR_HANDLE UserHandle,
117 IN PUNICODE_STRING Password)
118 {
119 USER_DOMAIN_PASSWORD_INFORMATION DomainPasswordInformation;
120 ULONG PasswordLength;
121 NTSTATUS Status;
122
123 TRACE("(%p %p)\n", UserHandle, Password);
124
125 /* Get the domain password information */
126 Status = SamrGetUserDomainPasswordInformation(UserHandle,
127 &DomainPasswordInformation);
128 if (!NT_SUCCESS(Status))
129 {
130 TRACE("SamrGetUserDomainPasswordInformation failed (Status 0x%08lx)\n", Status);
131 return Status;
132 }
133
134 PasswordLength = (ULONG)(Password->Length / sizeof(WCHAR));
135
136 /* Fail if the password is too short or too long */
137 if ((PasswordLength < DomainPasswordInformation.MinPasswordLength) ||
138 (PasswordLength > 256))
139 return STATUS_PASSWORD_RESTRICTION;
140
141 /* Check the password complexity */
142 if (DomainPasswordInformation.PasswordProperties & DOMAIN_PASSWORD_COMPLEX)
143 {
144 /* FIXME */
145 }
146
147 return STATUS_SUCCESS;
148 }
149
150
151 NTSTATUS
152 NTAPI
153 SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
154 IN PSID MemberId)
155 {
156 NTSTATUS Status;
157
158 TRACE("SamAddMemberToAlias(%p %p)\n",
159 AliasHandle, MemberId);
160
161 RpcTryExcept
162 {
163 Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle,
164 (PRPC_SID)MemberId);
165 }
166 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
167 {
168 Status = I_RpcMapWin32Status(RpcExceptionCode());
169 }
170 RpcEndExcept;
171
172 return Status;
173 }
174
175
176 NTSTATUS
177 NTAPI
178 SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
179 IN ULONG MemberId,
180 IN ULONG Attributes)
181 {
182 NTSTATUS Status;
183
184 TRACE("SamAddMemberToGroup(%p %lu %lx)\n",
185 GroupHandle, MemberId, Attributes);
186
187 RpcTryExcept
188 {
189 Status = SamrAddMemberToGroup((SAMPR_HANDLE)GroupHandle,
190 MemberId,
191 Attributes);
192 }
193 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
194 {
195 Status = I_RpcMapWin32Status(RpcExceptionCode());
196 }
197 RpcEndExcept;
198
199 return Status;
200 }
201
202
203 NTSTATUS
204 NTAPI
205 SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle,
206 IN PSID *MemberIds,
207 IN ULONG MemberCount)
208 {
209 SAMPR_PSID_ARRAY Buffer;
210 NTSTATUS Status;
211
212 TRACE("SamAddMultipleMembersToAlias(%p %p %lu)\n",
213 AliasHandle, MemberIds, MemberCount);
214
215 if (MemberIds == NULL)
216 return STATUS_INVALID_PARAMETER_2;
217
218 Buffer.Count = MemberCount;
219 Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
220
221 RpcTryExcept
222 {
223 Status = SamrAddMultipleMembersToAlias((SAMPR_HANDLE)AliasHandle,
224 &Buffer);
225 }
226 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
227 {
228 Status = I_RpcMapWin32Status(RpcExceptionCode());
229 }
230 RpcEndExcept;
231
232 return Status;
233 }
234
235
236 NTSTATUS
237 NTAPI
238 SamChangePasswordUser(IN SAM_HANDLE UserHandle,
239 IN PUNICODE_STRING OldPassword,
240 IN PUNICODE_STRING NewPassword)
241 {
242 ENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
243 ENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
244 ENCRYPTED_LM_OWF_PASSWORD OldLmPassword;
245 ENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
246 OEM_STRING LmPwdString;
247 CHAR LmPwdBuffer[15];
248 BOOLEAN OldLmPasswordPresent = FALSE;
249 BOOLEAN NewLmPasswordPresent = FALSE;
250 NTSTATUS Status;
251
252 /* Calculate the NT hash for the old password */
253 Status = SystemFunction007(OldPassword,
254 (LPBYTE)&OldNtPassword);
255 if (!NT_SUCCESS(Status))
256 {
257 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
258 return Status;
259 }
260
261 /* Calculate the NT hash for the new password */
262 Status = SystemFunction007(NewPassword,
263 (LPBYTE)&NewNtPassword);
264 if (!NT_SUCCESS(Status))
265 {
266 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
267 return Status;
268 }
269
270 /* Calculate the LM password and hash for the old password */
271 LmPwdString.Length = 15;
272 LmPwdString.MaximumLength = 15;
273 LmPwdString.Buffer = LmPwdBuffer;
274 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
275
276 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
277 OldPassword,
278 FALSE);
279 if (NT_SUCCESS(Status))
280 {
281 /* Calculate the LM hash value of the password */
282 Status = SystemFunction006(LmPwdString.Buffer,
283 (LPSTR)&OldLmPassword);
284 if (NT_SUCCESS(Status))
285 {
286 OldLmPasswordPresent = TRUE;
287 }
288 }
289
290 /* Calculate the LM password and hash for the new password */
291 LmPwdString.Length = 15;
292 LmPwdString.MaximumLength = 15;
293 LmPwdString.Buffer = LmPwdBuffer;
294 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
295
296 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
297 NewPassword,
298 FALSE);
299 if (NT_SUCCESS(Status))
300 {
301 /* Calculate the LM hash value of the password */
302 Status = SystemFunction006(LmPwdString.Buffer,
303 (LPSTR)&NewLmPassword);
304 if (NT_SUCCESS(Status))
305 {
306 NewLmPasswordPresent = TRUE;
307 }
308 }
309
310 RpcTryExcept
311 {
312 Status = SamrChangePasswordUser((SAMPR_HANDLE)UserHandle,
313 OldLmPasswordPresent && NewLmPasswordPresent,
314 &OldLmPassword,
315 &NewLmPassword,
316 TRUE,
317 &OldNtPassword,
318 &NewNtPassword,
319 FALSE,
320 NULL,
321 FALSE,
322 NULL);
323 }
324 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
325 {
326 Status = I_RpcMapWin32Status(RpcExceptionCode());
327 }
328 RpcEndExcept;
329
330 return Status;
331 }
332
333
334 NTSTATUS
335 NTAPI
336 SamChangePasswordUser2(IN PUNICODE_STRING ServerName,
337 IN PUNICODE_STRING UserName,
338 IN PUNICODE_STRING OldPassword,
339 IN PUNICODE_STRING NewPassword)
340 {
341 UNIMPLEMENTED;
342 return STATUS_NOT_IMPLEMENTED;
343 }
344
345
346 NTSTATUS
347 NTAPI
348 SamChangePasswordUser3(IN PUNICODE_STRING ServerName,
349 IN PUNICODE_STRING UserName,
350 IN PUNICODE_STRING OldPassword,
351 IN PUNICODE_STRING NewPassword,
352 OUT PDOMAIN_PASSWORD_INFORMATION *EffectivePasswordPolicy,
353 OUT PUSER_PWD_CHANGE_FAILURE_INFORMATION *PasswordChangeFailureInfo)
354 {
355 UNIMPLEMENTED;
356 return STATUS_NOT_IMPLEMENTED;
357 }
358
359
360 NTSTATUS
361 NTAPI
362 SamCloseHandle(IN SAM_HANDLE SamHandle)
363 {
364 NTSTATUS Status;
365
366 TRACE("SamCloseHandle(%p)\n", SamHandle);
367
368 RpcTryExcept
369 {
370 Status = SamrCloseHandle((SAMPR_HANDLE *)&SamHandle);
371 }
372 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
373 {
374 Status = I_RpcMapWin32Status(RpcExceptionCode());
375 }
376 RpcEndExcept;
377
378 return Status;
379 }
380
381
382 NTSTATUS
383 NTAPI
384 SamConnect(IN OUT PUNICODE_STRING ServerName OPTIONAL,
385 OUT PSAM_HANDLE ServerHandle,
386 IN ACCESS_MASK DesiredAccess,
387 IN POBJECT_ATTRIBUTES ObjectAttributes)
388 {
389 NTSTATUS Status;
390
391 TRACE("SamConnect(%p %p 0x%08x %p)\n",
392 ServerName, ServerHandle, DesiredAccess, ObjectAttributes);
393
394 RpcTryExcept
395 {
396 Status = SamrConnect((PSAMPR_SERVER_NAME)ServerName,
397 (SAMPR_HANDLE *)ServerHandle,
398 DesiredAccess);
399 }
400 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
401 {
402 Status = I_RpcMapWin32Status(RpcExceptionCode());
403 }
404 RpcEndExcept;
405
406 return Status;
407 }
408
409
410 NTSTATUS
411 NTAPI
412 SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
413 IN PUNICODE_STRING AccountName,
414 IN ACCESS_MASK DesiredAccess,
415 OUT PSAM_HANDLE AliasHandle,
416 OUT PULONG RelativeId)
417 {
418 NTSTATUS Status;
419
420 TRACE("SamCreateAliasInDomain(%p %p 0x%08x %p %p)\n",
421 DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
422
423 *AliasHandle = NULL;
424 *RelativeId = 0;
425
426 RpcTryExcept
427 {
428 Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle,
429 (PRPC_UNICODE_STRING)AccountName,
430 DesiredAccess,
431 (SAMPR_HANDLE *)AliasHandle,
432 RelativeId);
433 }
434 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
435 {
436 Status = I_RpcMapWin32Status(RpcExceptionCode());
437 }
438 RpcEndExcept;
439
440 return Status;
441 }
442
443
444 NTSTATUS
445 NTAPI
446 SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle,
447 IN PUNICODE_STRING AccountName,
448 IN ACCESS_MASK DesiredAccess,
449 OUT PSAM_HANDLE GroupHandle,
450 OUT PULONG RelativeId)
451 {
452 NTSTATUS Status;
453
454 TRACE("SamCreateGroupInDomain(%p %p 0x%08x %p %p)\n",
455 DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId);
456
457 *GroupHandle = NULL;
458 *RelativeId = 0;
459
460 RpcTryExcept
461 {
462 Status = SamrCreateGroupInDomain((SAMPR_HANDLE)DomainHandle,
463 (PRPC_UNICODE_STRING)AccountName,
464 DesiredAccess,
465 (SAMPR_HANDLE *)GroupHandle,
466 RelativeId);
467 }
468 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
469 {
470 Status = I_RpcMapWin32Status(RpcExceptionCode());
471 }
472 RpcEndExcept;
473
474 return Status;
475 }
476
477
478 NTSTATUS
479 NTAPI
480 SamCreateUser2InDomain(IN SAM_HANDLE DomainHandle,
481 IN PUNICODE_STRING AccountName,
482 IN ULONG AccountType,
483 IN ACCESS_MASK DesiredAccess,
484 OUT PSAM_HANDLE UserHandle,
485 OUT PULONG GrantedAccess,
486 OUT PULONG RelativeId)
487 {
488 NTSTATUS Status;
489
490 TRACE("SamCreateUser2InDomain(%p %p %lu 0x%08x %p %p %p)\n",
491 DomainHandle, AccountName, AccountType, DesiredAccess,
492 UserHandle, GrantedAccess, RelativeId);
493
494 *UserHandle = NULL;
495 *RelativeId = 0;
496
497 RpcTryExcept
498 {
499 Status = SamrCreateUser2InDomain((SAMPR_HANDLE)DomainHandle,
500 (PRPC_UNICODE_STRING)AccountName,
501 AccountType,
502 DesiredAccess,
503 (SAMPR_HANDLE *)UserHandle,
504 GrantedAccess,
505 RelativeId);
506
507 }
508 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
509 {
510 Status = I_RpcMapWin32Status(RpcExceptionCode());
511 }
512 RpcEndExcept;
513
514 return Status;
515 }
516
517
518 NTSTATUS
519 NTAPI
520 SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
521 IN PUNICODE_STRING AccountName,
522 IN ACCESS_MASK DesiredAccess,
523 OUT PSAM_HANDLE UserHandle,
524 OUT PULONG RelativeId)
525 {
526 NTSTATUS Status;
527
528 TRACE("SamCreateUserInDomain(%p %p 0x%08x %p %p)\n",
529 DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId);
530
531 *UserHandle = NULL;
532 *RelativeId = 0;
533
534 RpcTryExcept
535 {
536 Status = SamrCreateUserInDomain((SAMPR_HANDLE)DomainHandle,
537 (PRPC_UNICODE_STRING)AccountName,
538 DesiredAccess,
539 (SAMPR_HANDLE *)UserHandle,
540 RelativeId);
541 }
542 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
543 {
544 Status = I_RpcMapWin32Status(RpcExceptionCode());
545 }
546 RpcEndExcept;
547
548 return Status;
549 }
550
551
552 NTSTATUS
553 NTAPI
554 SamDeleteAlias(IN SAM_HANDLE AliasHandle)
555 {
556 SAMPR_HANDLE LocalAliasHandle;
557 NTSTATUS Status;
558
559 TRACE("SamDeleteAlias(%p)\n", AliasHandle);
560
561 LocalAliasHandle = (SAMPR_HANDLE)AliasHandle;
562
563 if (LocalAliasHandle == NULL)
564 return STATUS_INVALID_HANDLE;
565
566 RpcTryExcept
567 {
568 Status = SamrDeleteAlias(&LocalAliasHandle);
569 }
570 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
571 {
572 Status = I_RpcMapWin32Status(RpcExceptionCode());
573 }
574 RpcEndExcept;
575
576 return Status;
577 }
578
579
580 NTSTATUS
581 NTAPI
582 SamDeleteGroup(IN SAM_HANDLE GroupHandle)
583 {
584 SAMPR_HANDLE LocalGroupHandle;
585 NTSTATUS Status;
586
587 TRACE("SamDeleteGroup(%p)\n", GroupHandle);
588
589 LocalGroupHandle = (SAMPR_HANDLE)GroupHandle;
590
591 if (LocalGroupHandle == NULL)
592 return STATUS_INVALID_HANDLE;
593
594 RpcTryExcept
595 {
596 Status = SamrDeleteGroup(&LocalGroupHandle);
597 }
598 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
599 {
600 Status = I_RpcMapWin32Status(RpcExceptionCode());
601 }
602 RpcEndExcept;
603
604 return Status;
605 }
606
607
608 NTSTATUS
609 NTAPI
610 SamDeleteUser(IN SAM_HANDLE UserHandle)
611 {
612 SAMPR_HANDLE LocalUserHandle;
613 NTSTATUS Status;
614
615 TRACE("SamDeleteUser(%p)\n", UserHandle);
616
617 LocalUserHandle = (SAMPR_HANDLE)UserHandle;
618
619 if (LocalUserHandle == NULL)
620 return STATUS_INVALID_HANDLE;
621
622 RpcTryExcept
623 {
624 Status = SamrDeleteUser(&LocalUserHandle);
625 }
626 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
627 {
628 Status = I_RpcMapWin32Status(RpcExceptionCode());
629 }
630 RpcEndExcept;
631
632 return Status;
633 }
634
635
636 NTSTATUS
637 NTAPI
638 SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
639 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
640 OUT PVOID *Buffer,
641 IN ULONG PreferedMaximumLength,
642 OUT PULONG CountReturned)
643 {
644 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
645 NTSTATUS Status;
646
647 TRACE("SamEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
648 DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength,
649 CountReturned);
650
651 if ((EnumerationContext == NULL) ||
652 (Buffer == NULL) ||
653 (CountReturned == NULL))
654 return STATUS_INVALID_PARAMETER;
655
656 *Buffer = NULL;
657
658 RpcTryExcept
659 {
660 Status = SamrEnumerateAliasesInDomain((SAMPR_HANDLE)DomainHandle,
661 EnumerationContext,
662 &EnumBuffer,
663 PreferedMaximumLength,
664 CountReturned);
665
666 if (EnumBuffer != NULL)
667 {
668 if (EnumBuffer->Buffer != NULL)
669 {
670 *Buffer = EnumBuffer->Buffer;
671 }
672
673 midl_user_free(EnumBuffer);
674 }
675 }
676 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
677 {
678 Status = I_RpcMapWin32Status(RpcExceptionCode());
679 }
680 RpcEndExcept;
681
682 return Status;
683 }
684
685
686 NTSTATUS
687 NTAPI
688 SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
689 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
690 OUT PVOID *Buffer,
691 IN ULONG PreferedMaximumLength,
692 OUT PULONG CountReturned)
693 {
694 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
695 NTSTATUS Status;
696
697 TRACE("SamEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
698 ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
699 CountReturned);
700
701 if ((EnumerationContext == NULL) ||
702 (Buffer == NULL) ||
703 (CountReturned == NULL))
704 return STATUS_INVALID_PARAMETER;
705
706 *Buffer = NULL;
707
708 RpcTryExcept
709 {
710 Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle,
711 EnumerationContext,
712 &EnumBuffer,
713 PreferedMaximumLength,
714 CountReturned);
715
716 if (EnumBuffer != NULL)
717 {
718 if (EnumBuffer->Buffer != NULL)
719 {
720 *Buffer = EnumBuffer->Buffer;
721 }
722
723 midl_user_free(EnumBuffer);
724 }
725 }
726 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
727 {
728 Status = I_RpcMapWin32Status(RpcExceptionCode());
729 }
730 RpcEndExcept;
731
732 return Status;
733 }
734
735
736 NTSTATUS
737 NTAPI
738 SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle,
739 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
740 IN PVOID *Buffer,
741 IN ULONG PreferedMaximumLength,
742 OUT PULONG CountReturned)
743 {
744 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
745 NTSTATUS Status;
746
747 TRACE("SamEnumerateGroupsInDomain(%p %p %p %lu %p)\n",
748 DomainHandle, EnumerationContext, Buffer,
749 PreferedMaximumLength, CountReturned);
750
751 if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
752 return STATUS_INVALID_PARAMETER;
753
754 *Buffer = NULL;
755
756 RpcTryExcept
757 {
758 Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle,
759 EnumerationContext,
760 &EnumBuffer,
761 PreferedMaximumLength,
762 CountReturned);
763 if (EnumBuffer != NULL)
764 {
765 if (EnumBuffer->Buffer != NULL)
766 *Buffer = EnumBuffer->Buffer;
767
768 midl_user_free(EnumBuffer);
769 }
770 }
771 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
772 {
773 Status = I_RpcMapWin32Status(RpcExceptionCode());
774 }
775 RpcEndExcept;
776
777 return Status;
778 }
779
780
781 NTSTATUS
782 NTAPI
783 SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle,
784 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
785 IN ULONG UserAccountControl,
786 OUT PVOID *Buffer,
787 IN ULONG PreferedMaximumLength,
788 OUT PULONG CountReturned)
789 {
790 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
791 NTSTATUS Status;
792
793 TRACE("SamEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
794 DomainHandle, EnumerationContext, UserAccountControl, Buffer,
795 PreferedMaximumLength, CountReturned);
796
797 if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
798 return STATUS_INVALID_PARAMETER;
799
800 *Buffer = NULL;
801
802 RpcTryExcept
803 {
804 Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle,
805 EnumerationContext,
806 UserAccountControl,
807 &EnumBuffer,
808 PreferedMaximumLength,
809 CountReturned);
810 if (EnumBuffer != NULL)
811 {
812 if (EnumBuffer->Buffer != NULL)
813 {
814 *Buffer = EnumBuffer->Buffer;
815 }
816
817 midl_user_free(EnumBuffer);
818 }
819
820 }
821 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
822 {
823 Status = I_RpcMapWin32Status(RpcExceptionCode());
824 }
825 RpcEndExcept;
826
827 return Status;
828 }
829
830
831 NTSTATUS
832 NTAPI
833 SamFreeMemory(IN PVOID Buffer)
834 {
835 if (Buffer != NULL)
836 midl_user_free(Buffer);
837
838 return STATUS_SUCCESS;
839 }
840
841
842 NTSTATUS
843 NTAPI
844 SamGetAliasMembership(IN SAM_HANDLE DomainHandle,
845 IN ULONG PassedCount,
846 IN PSID *Sids,
847 OUT PULONG MembershipCount,
848 OUT PULONG *Aliases)
849 {
850 SAMPR_PSID_ARRAY SidArray;
851 SAMPR_ULONG_ARRAY Membership;
852 NTSTATUS Status;
853
854 TRACE("SamAliasMembership(%p %lu %p %p %p)\n",
855 DomainHandle, PassedCount, Sids, MembershipCount, Aliases);
856
857 if (Sids == NULL ||
858 MembershipCount == NULL ||
859 Aliases == NULL)
860 return STATUS_INVALID_PARAMETER;
861
862 Membership.Element = NULL;
863
864 RpcTryExcept
865 {
866 SidArray.Count = PassedCount;
867 SidArray.Sids = (PSAMPR_SID_INFORMATION)Sids;
868
869 Status = SamrGetAliasMembership((SAMPR_HANDLE)DomainHandle,
870 &SidArray,
871 &Membership);
872 if (NT_SUCCESS(Status))
873 {
874 *MembershipCount = Membership.Count;
875 *Aliases = Membership.Element;
876 }
877 else
878 {
879 if (Membership.Element != NULL)
880 midl_user_free(Membership.Element);
881 }
882 }
883 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
884 {
885 Status = I_RpcMapWin32Status(RpcExceptionCode());
886 }
887 RpcEndExcept;
888
889 return Status;
890 }
891
892
893 NTSTATUS
894 NTAPI
895 SamGetCompatibilityMode(IN SAM_HANDLE ObjectHandle,
896 OUT PULONG Mode)
897 {
898 TRACE("(%p %p)\n", ObjectHandle, Mode);
899
900 if (Mode == NULL)
901 return STATUS_INVALID_PARAMETER;
902
903 *Mode = SAM_SID_COMPATIBILITY_ALL;
904
905 return STATUS_SUCCESS;
906 }
907
908
909 NTSTATUS
910 NTAPI
911 SamGetDisplayEnumerationIndex(IN SAM_HANDLE DomainHandle,
912 IN DOMAIN_DISPLAY_INFORMATION DisplayInformation,
913 IN PUNICODE_STRING Prefix,
914 OUT PULONG Index)
915 {
916 NTSTATUS Status;
917
918 TRACE("(%p %lu %wZ %p)\n",
919 DomainHandle, DisplayInformation, Prefix, Index);
920
921 if ((Prefix == NULL) ||
922 (Index == NULL))
923 return STATUS_INVALID_PARAMETER;
924
925 RpcTryExcept
926 {
927 Status = SamrGetDisplayEnumerationIndex2((SAMPR_HANDLE)DomainHandle,
928 DisplayInformation,
929 (PRPC_UNICODE_STRING)Prefix,
930 Index);
931 }
932 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
933 {
934 Status = I_RpcMapWin32Status(RpcExceptionCode());
935 }
936 RpcEndExcept;
937
938 return Status;
939 }
940
941
942 NTSTATUS
943 NTAPI
944 SamGetGroupsForUser(IN SAM_HANDLE UserHandle,
945 OUT PGROUP_MEMBERSHIP *Groups,
946 OUT PULONG MembershipCount)
947 {
948 PSAMPR_GET_GROUPS_BUFFER GroupsBuffer = NULL;
949 NTSTATUS Status;
950
951 TRACE("SamGetGroupsForUser(%p %p %p)\n",
952 UserHandle, Groups, MembershipCount);
953
954 RpcTryExcept
955 {
956 Status = SamrGetGroupsForUser((SAMPR_HANDLE)UserHandle,
957 &GroupsBuffer);
958 if (NT_SUCCESS(Status))
959 {
960 *Groups = GroupsBuffer->Groups;
961 *MembershipCount = GroupsBuffer->MembershipCount;
962
963 MIDL_user_free(GroupsBuffer);
964 }
965 else
966 {
967 if (GroupsBuffer != NULL)
968 {
969 if (GroupsBuffer->Groups != NULL)
970 MIDL_user_free(GroupsBuffer->Groups);
971
972 MIDL_user_free(GroupsBuffer);
973 }
974 }
975 }
976 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
977 {
978 Status = I_RpcMapWin32Status(RpcExceptionCode());
979 }
980 RpcEndExcept;
981
982 return Status;
983 }
984
985
986 NTSTATUS
987 NTAPI
988 SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
989 OUT PSID **MemberIds,
990 OUT PULONG MemberCount)
991 {
992 SAMPR_PSID_ARRAY_OUT SidArray;
993 NTSTATUS Status;
994
995 TRACE("SamGetMembersInAlias(%p %p %p)\n",
996 AliasHandle, MemberIds, MemberCount);
997
998 if ((MemberIds == NULL) ||
999 (MemberCount == NULL))
1000 return STATUS_INVALID_PARAMETER;
1001
1002 *MemberIds = NULL;
1003 *MemberCount = 0;
1004
1005 SidArray.Sids = NULL;
1006
1007 RpcTryExcept
1008 {
1009 Status = SamrGetMembersInAlias((SAMPR_HANDLE)AliasHandle,
1010 &SidArray);
1011 if (NT_SUCCESS(Status))
1012 {
1013 *MemberCount = SidArray.Count;
1014 *MemberIds = (PSID *)SidArray.Sids;
1015 }
1016
1017 }
1018 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1019 {
1020 Status = I_RpcMapWin32Status(RpcExceptionCode());
1021 }
1022 RpcEndExcept;
1023
1024 return Status;
1025 }
1026
1027
1028 NTSTATUS
1029 NTAPI
1030 SamGetMembersInGroup(IN SAM_HANDLE GroupHandle,
1031 OUT PULONG *MemberIds,
1032 OUT PULONG *Attributes,
1033 OUT PULONG MemberCount)
1034 {
1035 PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL;
1036 NTSTATUS Status;
1037
1038 TRACE("SamGetMembersInGroup(%p %p %p %p)\n",
1039 GroupHandle, MemberIds, Attributes, MemberCount);
1040
1041 RpcTryExcept
1042 {
1043 Status = SamrGetMembersInGroup((SAMPR_HANDLE)GroupHandle,
1044 &MembersBuffer);
1045 if (NT_SUCCESS(Status))
1046 {
1047 *MemberIds = MembersBuffer->Members;
1048 *Attributes = MembersBuffer->Attributes;
1049 *MemberCount = MembersBuffer->MemberCount;
1050
1051 MIDL_user_free(MembersBuffer);
1052 }
1053 else
1054 {
1055 if (MembersBuffer != NULL)
1056 {
1057 if (MembersBuffer->Members != NULL)
1058 MIDL_user_free(MembersBuffer->Members);
1059
1060 if (MembersBuffer->Attributes != NULL)
1061 MIDL_user_free(MembersBuffer->Attributes);
1062
1063 MIDL_user_free(MembersBuffer);
1064 }
1065 }
1066 }
1067 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1068 {
1069 Status = I_RpcMapWin32Status(RpcExceptionCode());
1070 }
1071 RpcEndExcept;
1072
1073 return Status;
1074 }
1075
1076
1077 NTSTATUS
1078 NTAPI
1079 SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
1080 IN PUNICODE_STRING Name,
1081 OUT PSID *DomainId)
1082 {
1083 NTSTATUS Status;
1084
1085 TRACE("SamLookupDomainInSamServer(%p %p %p)\n",
1086 ServerHandle, Name, DomainId);
1087
1088 RpcTryExcept
1089 {
1090 Status = SamrLookupDomainInSamServer((SAMPR_HANDLE)ServerHandle,
1091 (PRPC_UNICODE_STRING)Name,
1092 (PRPC_SID *)DomainId);
1093 }
1094 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1095 {
1096 Status = I_RpcMapWin32Status(RpcExceptionCode());
1097 }
1098 RpcEndExcept;
1099
1100 return Status;
1101 }
1102
1103
1104 NTSTATUS
1105 NTAPI
1106 SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle,
1107 IN ULONG Count,
1108 IN PULONG RelativeIds,
1109 OUT PUNICODE_STRING *Names,
1110 OUT PSID_NAME_USE *Use OPTIONAL)
1111 {
1112 SAMPR_RETURNED_USTRING_ARRAY NamesBuffer = {0, NULL};
1113 SAMPR_ULONG_ARRAY UseBuffer = {0, NULL};
1114 ULONG i;
1115 NTSTATUS Status;
1116
1117 TRACE("SamLookupIdsInDomain(%p %lu %p %p %p)\n",
1118 DomainHandle, Count, RelativeIds, Names, Use);
1119
1120 *Names = NULL;
1121
1122 if (Use != NULL)
1123 *Use = NULL;
1124
1125 RpcTryExcept
1126 {
1127 Status = SamrLookupIdsInDomain((SAMPR_HANDLE)DomainHandle,
1128 Count,
1129 RelativeIds,
1130 &NamesBuffer,
1131 &UseBuffer);
1132 }
1133 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1134 {
1135 Status = I_RpcMapWin32Status(RpcExceptionCode());
1136 }
1137 RpcEndExcept;
1138
1139 if (NT_SUCCESS(Status))
1140 {
1141 *Names = midl_user_allocate(Count * sizeof(RPC_UNICODE_STRING));
1142 if (*Names == NULL)
1143 {
1144 Status = STATUS_INSUFFICIENT_RESOURCES;
1145 goto done;
1146 }
1147
1148 for (i = 0; i < Count; i++)
1149 {
1150 (*Names)[i].Buffer = midl_user_allocate(NamesBuffer.Element[i].MaximumLength);
1151 if ((*Names)[i].Buffer == NULL)
1152 {
1153 Status = STATUS_INSUFFICIENT_RESOURCES;
1154 goto done;
1155 }
1156 }
1157
1158 for (i = 0; i < Count; i++)
1159 {
1160 (*Names)[i].Length = NamesBuffer.Element[i].Length;
1161 (*Names)[i].MaximumLength = NamesBuffer.Element[i].MaximumLength;
1162
1163 RtlCopyMemory((*Names)[i].Buffer,
1164 NamesBuffer.Element[i].Buffer,
1165 NamesBuffer.Element[i].Length);
1166 }
1167
1168 if (Use != NULL)
1169 {
1170 *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE));
1171 if (*Use == NULL)
1172 {
1173 Status = STATUS_INSUFFICIENT_RESOURCES;
1174 goto done;
1175 }
1176
1177 RtlCopyMemory(*Use,
1178 UseBuffer.Element,
1179 Count * sizeof(SID_NAME_USE));
1180 }
1181 }
1182
1183 done:
1184 if (!NT_SUCCESS(Status))
1185 {
1186 if (*Names != NULL)
1187 {
1188 for (i = 0; i < Count; i++)
1189 {
1190 if ((*Names)[i].Buffer != NULL)
1191 midl_user_free((*Names)[i].Buffer);
1192 }
1193
1194 midl_user_free(*Names);
1195 }
1196
1197 if (Use != NULL && *Use != NULL)
1198 midl_user_free(*Use);
1199 }
1200
1201 if (NamesBuffer.Element != NULL)
1202 {
1203 for (i = 0; i < NamesBuffer.Count; i++)
1204 {
1205 if (NamesBuffer.Element[i].Buffer != NULL)
1206 midl_user_free(NamesBuffer.Element[i].Buffer);
1207 }
1208
1209 midl_user_free(NamesBuffer.Element);
1210 }
1211
1212 if (UseBuffer.Element != NULL)
1213 midl_user_free(UseBuffer.Element);
1214
1215 return 0;
1216 }
1217
1218
1219 NTSTATUS
1220 NTAPI
1221 SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle,
1222 IN ULONG Count,
1223 IN PUNICODE_STRING Names,
1224 OUT PULONG *RelativeIds,
1225 OUT PSID_NAME_USE *Use)
1226 {
1227 SAMPR_ULONG_ARRAY RidBuffer = {0, NULL};
1228 SAMPR_ULONG_ARRAY UseBuffer = {0, NULL};
1229 NTSTATUS Status;
1230
1231 TRACE("SamLookupNamesInDomain(%p %lu %p %p %p)\n",
1232 DomainHandle, Count, Names, RelativeIds, Use);
1233
1234 *RelativeIds = NULL;
1235 *Use = NULL;
1236
1237 RpcTryExcept
1238 {
1239 Status = SamrLookupNamesInDomain((SAMPR_HANDLE)DomainHandle,
1240 Count,
1241 (PRPC_UNICODE_STRING)Names,
1242 &RidBuffer,
1243 &UseBuffer);
1244 }
1245 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1246 {
1247 Status = I_RpcMapWin32Status(RpcExceptionCode());
1248 }
1249 RpcEndExcept;
1250
1251 if (NT_SUCCESS(Status))
1252 {
1253 *RelativeIds = midl_user_allocate(Count * sizeof(ULONG));
1254 if (*RelativeIds == NULL)
1255 {
1256 Status = STATUS_INSUFFICIENT_RESOURCES;
1257 goto done;
1258 }
1259
1260 *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE));
1261 if (*Use == NULL)
1262 {
1263 Status = STATUS_INSUFFICIENT_RESOURCES;
1264 goto done;
1265 }
1266
1267 RtlCopyMemory(*RelativeIds,
1268 RidBuffer.Element,
1269 Count * sizeof(ULONG));
1270
1271 RtlCopyMemory(*Use,
1272 UseBuffer.Element,
1273 Count * sizeof(SID_NAME_USE));
1274 }
1275
1276 done:
1277 if (!NT_SUCCESS(Status))
1278 {
1279 if (*RelativeIds != NULL)
1280 midl_user_free(*RelativeIds);
1281
1282 if (*Use != NULL)
1283 midl_user_free(*Use);
1284 }
1285
1286 if (RidBuffer.Element != NULL)
1287 midl_user_free(RidBuffer.Element);
1288
1289 if (UseBuffer.Element != NULL)
1290 midl_user_free(UseBuffer.Element);
1291
1292 return Status;
1293 }
1294
1295
1296 NTSTATUS
1297 NTAPI
1298 SamOpenAlias(IN SAM_HANDLE DomainHandle,
1299 IN ACCESS_MASK DesiredAccess,
1300 IN ULONG AliasId,
1301 OUT PSAM_HANDLE AliasHandle)
1302 {
1303 NTSTATUS Status;
1304
1305 TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n",
1306 DomainHandle, DesiredAccess, AliasId, AliasHandle);
1307
1308 RpcTryExcept
1309 {
1310 Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle,
1311 DesiredAccess,
1312 AliasId,
1313 (SAMPR_HANDLE *)AliasHandle);
1314 }
1315 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1316 {
1317 Status = I_RpcMapWin32Status(RpcExceptionCode());
1318 }
1319 RpcEndExcept;
1320
1321 return Status;
1322 }
1323
1324
1325 NTSTATUS
1326 NTAPI
1327 SamOpenDomain(IN SAM_HANDLE ServerHandle,
1328 IN ACCESS_MASK DesiredAccess,
1329 IN PSID DomainId,
1330 OUT PSAM_HANDLE DomainHandle)
1331 {
1332 NTSTATUS Status;
1333
1334 TRACE("SamOpenDomain(%p 0x%08x %p %p)\n",
1335 ServerHandle, DesiredAccess, DomainId, DomainHandle);
1336
1337 RpcTryExcept
1338 {
1339 Status = SamrOpenDomain((SAMPR_HANDLE)ServerHandle,
1340 DesiredAccess,
1341 (PRPC_SID)DomainId,
1342 (SAMPR_HANDLE *)DomainHandle);
1343 }
1344 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1345 {
1346 Status = I_RpcMapWin32Status(RpcExceptionCode());
1347 }
1348 RpcEndExcept;
1349
1350 return Status;
1351 }
1352
1353
1354 NTSTATUS
1355 NTAPI
1356 SamOpenGroup(IN SAM_HANDLE DomainHandle,
1357 IN ACCESS_MASK DesiredAccess,
1358 IN ULONG GroupId,
1359 OUT PSAM_HANDLE GroupHandle)
1360 {
1361 NTSTATUS Status;
1362
1363 TRACE("SamOpenGroup(%p 0x%08x %p %p)\n",
1364 DomainHandle, DesiredAccess, GroupId, GroupHandle);
1365
1366 RpcTryExcept
1367 {
1368 Status = SamrOpenGroup((SAMPR_HANDLE)DomainHandle,
1369 DesiredAccess,
1370 GroupId,
1371 (SAMPR_HANDLE *)GroupHandle);
1372 }
1373 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1374 {
1375 Status = I_RpcMapWin32Status(RpcExceptionCode());
1376 }
1377 RpcEndExcept;
1378
1379 return Status;
1380 }
1381
1382
1383 NTSTATUS
1384 NTAPI
1385 SamOpenUser(IN SAM_HANDLE DomainHandle,
1386 IN ACCESS_MASK DesiredAccess,
1387 IN ULONG UserId,
1388 OUT PSAM_HANDLE UserHandle)
1389 {
1390 NTSTATUS Status;
1391
1392 TRACE("SamOpenUser(%p 0x%08x %lx %p)\n",
1393 DomainHandle, DesiredAccess, UserId, UserHandle);
1394
1395 RpcTryExcept
1396 {
1397 Status = SamrOpenUser((SAMPR_HANDLE)DomainHandle,
1398 DesiredAccess,
1399 UserId,
1400 (SAMPR_HANDLE *)UserHandle);
1401 }
1402 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1403 {
1404 Status = I_RpcMapWin32Status(RpcExceptionCode());
1405 }
1406 RpcEndExcept;
1407
1408 return Status;
1409 }
1410
1411
1412 NTSTATUS
1413 NTAPI
1414 SamQueryDisplayInformation(IN SAM_HANDLE DomainHandle,
1415 IN DOMAIN_DISPLAY_INFORMATION DisplayInformation,
1416 IN ULONG Index,
1417 IN ULONG EntryCount,
1418 IN ULONG PreferredMaximumLength,
1419 OUT PULONG TotalAvailable,
1420 OUT PULONG TotalReturned,
1421 OUT PULONG ReturnedEntryCount,
1422 OUT PVOID *SortedBuffer)
1423 {
1424 SAMPR_DISPLAY_INFO_BUFFER LocalBuffer;
1425 NTSTATUS Status;
1426
1427 TRACE("(%p %lu %lu %lu %lu %p %p %p %p)\n",
1428 DomainHandle, DisplayInformation, Index, EntryCount,
1429 PreferredMaximumLength, TotalAvailable, TotalReturned,
1430 ReturnedEntryCount, SortedBuffer);
1431
1432 if ((TotalAvailable == NULL) ||
1433 (TotalReturned == NULL) ||
1434 (ReturnedEntryCount == NULL) ||
1435 (SortedBuffer == NULL))
1436 return STATUS_INVALID_PARAMETER;
1437
1438 RpcTryExcept
1439 {
1440 Status = SamrQueryDisplayInformation3((SAMPR_HANDLE)DomainHandle,
1441 DisplayInformation,
1442 Index,
1443 EntryCount,
1444 PreferredMaximumLength,
1445 TotalAvailable,
1446 TotalReturned,
1447 &LocalBuffer);
1448 if (NT_SUCCESS(Status))
1449 {
1450 switch (DisplayInformation)
1451 {
1452 case DomainDisplayUser:
1453 *ReturnedEntryCount = LocalBuffer.UserInformation.EntriesRead;
1454 *SortedBuffer = LocalBuffer.UserInformation.Buffer;
1455 break;
1456
1457 case DomainDisplayMachine:
1458 *ReturnedEntryCount = LocalBuffer.MachineInformation.EntriesRead;
1459 *SortedBuffer = LocalBuffer.MachineInformation.Buffer;
1460 break;
1461
1462 case DomainDisplayGroup:
1463 *ReturnedEntryCount = LocalBuffer.GroupInformation.EntriesRead;
1464 *SortedBuffer = LocalBuffer.GroupInformation.Buffer;
1465 break;
1466
1467 case DomainDisplayOemUser:
1468 *ReturnedEntryCount = LocalBuffer.OemUserInformation.EntriesRead;
1469 *SortedBuffer = LocalBuffer.OemUserInformation.Buffer;
1470 break;
1471
1472 case DomainDisplayOemGroup:
1473 *ReturnedEntryCount = LocalBuffer.OemGroupInformation.EntriesRead;
1474 *SortedBuffer = LocalBuffer.OemGroupInformation.Buffer;
1475 break;
1476
1477 case DomainDisplayServer:
1478 /* FIXME */
1479 break;
1480 }
1481 }
1482 else
1483 {
1484 *ReturnedEntryCount = 0;
1485 *SortedBuffer = NULL;
1486 }
1487 }
1488 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1489 {
1490 Status = I_RpcMapWin32Status(RpcExceptionCode());
1491 }
1492 RpcEndExcept;
1493
1494 return Status;
1495 }
1496
1497
1498 NTSTATUS
1499 NTAPI
1500 SamQueryInformationAlias(IN SAM_HANDLE AliasHandle,
1501 IN ALIAS_INFORMATION_CLASS AliasInformationClass,
1502 OUT PVOID *Buffer)
1503 {
1504 NTSTATUS Status;
1505
1506 TRACE("SamQueryInformationAlias(%p %lu %p)\n",
1507 AliasHandle, AliasInformationClass, Buffer);
1508
1509 RpcTryExcept
1510 {
1511 Status = SamrQueryInformationAlias((SAMPR_HANDLE)AliasHandle,
1512 AliasInformationClass,
1513 (PSAMPR_ALIAS_INFO_BUFFER *)Buffer);
1514 }
1515 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1516 {
1517 Status = I_RpcMapWin32Status(RpcExceptionCode());
1518 }
1519 RpcEndExcept;
1520
1521 return Status;
1522 }
1523
1524
1525 NTSTATUS
1526 NTAPI
1527 SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
1528 IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
1529 OUT PVOID *Buffer)
1530 {
1531 NTSTATUS Status;
1532
1533 TRACE("SamQueryInformationDomain(%p %lu %p)\n",
1534 DomainHandle, DomainInformationClass, Buffer);
1535
1536 RpcTryExcept
1537 {
1538 Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle,
1539 DomainInformationClass,
1540 (PSAMPR_DOMAIN_INFO_BUFFER *)Buffer);
1541 }
1542 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1543 {
1544 Status = I_RpcMapWin32Status(RpcExceptionCode());
1545 }
1546 RpcEndExcept;
1547
1548 return Status;
1549 }
1550
1551
1552 NTSTATUS
1553 NTAPI
1554 SamQueryInformationGroup(IN SAM_HANDLE GroupHandle,
1555 IN GROUP_INFORMATION_CLASS GroupInformationClass,
1556 OUT PVOID *Buffer)
1557 {
1558 NTSTATUS Status;
1559
1560 TRACE("SamQueryInformationGroup(%p %lu %p)\n",
1561 GroupHandle, GroupInformationClass, Buffer);
1562
1563 RpcTryExcept
1564 {
1565 Status = SamrQueryInformationGroup((SAMPR_HANDLE)GroupHandle,
1566 GroupInformationClass,
1567 (PSAMPR_GROUP_INFO_BUFFER *)Buffer);
1568 }
1569 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1570 {
1571 Status = I_RpcMapWin32Status(RpcExceptionCode());
1572 }
1573 RpcEndExcept;
1574
1575 return Status;
1576 }
1577
1578
1579 NTSTATUS
1580 NTAPI
1581 SamQueryInformationUser(IN SAM_HANDLE UserHandle,
1582 IN USER_INFORMATION_CLASS UserInformationClass,
1583 OUT PVOID *Buffer)
1584 {
1585 NTSTATUS Status;
1586
1587 TRACE("SamQueryInformationUser(%p %lu %p)\n",
1588 UserHandle, UserInformationClass, Buffer);
1589
1590 RpcTryExcept
1591 {
1592 Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle,
1593 UserInformationClass,
1594 (PSAMPR_USER_INFO_BUFFER *)Buffer);
1595 }
1596 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1597 {
1598 Status = I_RpcMapWin32Status(RpcExceptionCode());
1599 }
1600 RpcEndExcept;
1601
1602 return Status;
1603 }
1604
1605
1606 NTSTATUS
1607 NTAPI
1608 SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle,
1609 IN SECURITY_INFORMATION SecurityInformation,
1610 OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
1611 {
1612 PSAMPR_SR_SECURITY_DESCRIPTOR SamSecurityDescriptor = NULL;
1613 NTSTATUS Status;
1614
1615 TRACE("SamQuerySecurityObject(%p %lu %p)\n",
1616 ObjectHandle, SecurityInformation, SecurityDescriptor);
1617
1618 *SecurityDescriptor = NULL;
1619
1620 RpcTryExcept
1621 {
1622 Status = SamrQuerySecurityObject((SAMPR_HANDLE)ObjectHandle,
1623 SecurityInformation,
1624 &SamSecurityDescriptor);
1625 }
1626 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1627 {
1628 Status = I_RpcMapWin32Status(RpcExceptionCode());
1629 }
1630 RpcEndExcept;
1631
1632 TRACE("SamSecurityDescriptor: %p\n", SamSecurityDescriptor);
1633
1634 if (SamSecurityDescriptor != NULL)
1635 {
1636 TRACE("SamSecurityDescriptor->Length: %lu\n", SamSecurityDescriptor->Length);
1637 TRACE("SamSecurityDescriptor->SecurityDescriptor: %p\n", SamSecurityDescriptor->SecurityDescriptor);
1638
1639 *SecurityDescriptor = SamSecurityDescriptor->SecurityDescriptor;
1640
1641 midl_user_free(SamSecurityDescriptor);
1642 }
1643
1644 return Status;
1645 }
1646
1647
1648 NTSTATUS
1649 NTAPI
1650 SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle,
1651 IN PSID MemberId)
1652 {
1653 NTSTATUS Status;
1654
1655 TRACE("SamRemoveMemberFromAlias(%p %ul)\n",
1656 AliasHandle, MemberId);
1657
1658 RpcTryExcept
1659 {
1660 Status = SamrRemoveMemberFromAlias((SAMPR_HANDLE)AliasHandle,
1661 MemberId);
1662 }
1663 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1664 {
1665 Status = I_RpcMapWin32Status(RpcExceptionCode());
1666 }
1667 RpcEndExcept;
1668
1669 return Status;
1670 }
1671
1672
1673 NTSTATUS
1674 NTAPI
1675 SamRemoveMemberFromForeignDomain(IN SAM_HANDLE DomainHandle,
1676 IN PSID MemberId)
1677 {
1678 NTSTATUS Status;
1679
1680 TRACE("SamRemoveMemberFromForeignDomain(%p %ul)\n",
1681 DomainHandle, MemberId);
1682
1683 RpcTryExcept
1684 {
1685 Status = SamrRemoveMemberFromForeignDomain((SAMPR_HANDLE)DomainHandle,
1686 MemberId);
1687 }
1688 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1689 {
1690 Status = I_RpcMapWin32Status(RpcExceptionCode());
1691 }
1692 RpcEndExcept;
1693
1694 return Status;
1695 }
1696
1697
1698 NTSTATUS
1699 NTAPI
1700 SamRemoveMemberFromGroup(IN SAM_HANDLE GroupHandle,
1701 IN ULONG MemberId)
1702 {
1703 NTSTATUS Status;
1704
1705 TRACE("SamRemoveMemberFromGroup(%p %ul)\n",
1706 GroupHandle, MemberId);
1707
1708 RpcTryExcept
1709 {
1710 Status = SamrRemoveMemberFromGroup((SAMPR_HANDLE)GroupHandle,
1711 MemberId);
1712 }
1713 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1714 {
1715 Status = I_RpcMapWin32Status(RpcExceptionCode());
1716 }
1717 RpcEndExcept;
1718
1719 return Status;
1720 }
1721
1722
1723 NTSTATUS
1724 NTAPI
1725 SamRemoveMultipleMembersFromAlias(IN SAM_HANDLE AliasHandle,
1726 IN PSID *MemberIds,
1727 IN ULONG MemberCount)
1728 {
1729 SAMPR_PSID_ARRAY Buffer;
1730 NTSTATUS Status;
1731
1732 TRACE("SamRemoveMultipleMembersFromAlias(%p %p %lu)\n",
1733 AliasHandle, MemberIds, MemberCount);
1734
1735 if (MemberIds == NULL)
1736 return STATUS_INVALID_PARAMETER_2;
1737
1738 Buffer.Count = MemberCount;
1739 Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
1740
1741 RpcTryExcept
1742 {
1743 Status = SamrRemoveMultipleMembersFromAlias((SAMPR_HANDLE)AliasHandle,
1744 &Buffer);
1745 }
1746 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1747 {
1748 Status = I_RpcMapWin32Status(RpcExceptionCode());
1749 }
1750 RpcEndExcept;
1751
1752 return Status;
1753 }
1754
1755
1756 NTSTATUS
1757 NTAPI
1758 SamRidToSid(IN SAM_HANDLE ObjectHandle,
1759 IN ULONG Rid,
1760 OUT PSID *Sid)
1761 {
1762 UNIMPLEMENTED;
1763 return STATUS_NOT_IMPLEMENTED;
1764 }
1765
1766
1767 NTSTATUS
1768 NTAPI
1769 SamSetInformationAlias(IN SAM_HANDLE AliasHandle,
1770 IN ALIAS_INFORMATION_CLASS AliasInformationClass,
1771 IN PVOID Buffer)
1772 {
1773 NTSTATUS Status;
1774
1775 TRACE("SamSetInformationAlias(%p %lu %p)\n",
1776 AliasHandle, AliasInformationClass, Buffer);
1777
1778 RpcTryExcept
1779 {
1780 Status = SamrSetInformationAlias((SAMPR_HANDLE)AliasHandle,
1781 AliasInformationClass,
1782 Buffer);
1783 }
1784 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1785 {
1786 Status = I_RpcMapWin32Status(RpcExceptionCode());
1787 }
1788 RpcEndExcept;
1789
1790 return Status;
1791 }
1792
1793
1794 NTSTATUS
1795 NTAPI
1796 SamSetInformationDomain(IN SAM_HANDLE DomainHandle,
1797 IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
1798 IN PVOID Buffer)
1799 {
1800 NTSTATUS Status;
1801
1802 TRACE("SamSetInformationDomain(%p %lu %p)\n",
1803 DomainHandle, DomainInformationClass, Buffer);
1804
1805 RpcTryExcept
1806 {
1807 Status = SamrSetInformationDomain((SAMPR_HANDLE)DomainHandle,
1808 DomainInformationClass,
1809 Buffer);
1810 }
1811 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1812 {
1813 Status = I_RpcMapWin32Status(RpcExceptionCode());
1814 }
1815 RpcEndExcept;
1816
1817 return Status;
1818 }
1819
1820
1821 NTSTATUS
1822 NTAPI
1823 SamSetInformationGroup(IN SAM_HANDLE GroupHandle,
1824 IN GROUP_INFORMATION_CLASS GroupInformationClass,
1825 IN PVOID Buffer)
1826 {
1827 NTSTATUS Status;
1828
1829 TRACE("SamSetInformationGroup(%p %lu %p)\n",
1830 GroupHandle, GroupInformationClass, Buffer);
1831
1832 RpcTryExcept
1833 {
1834 Status = SamrSetInformationGroup((SAMPR_HANDLE)GroupHandle,
1835 GroupInformationClass,
1836 Buffer);
1837 }
1838 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1839 {
1840 Status = I_RpcMapWin32Status(RpcExceptionCode());
1841 }
1842 RpcEndExcept;
1843
1844 return Status;
1845 }
1846
1847
1848 NTSTATUS
1849 NTAPI
1850 SamSetInformationUser(IN SAM_HANDLE UserHandle,
1851 IN USER_INFORMATION_CLASS UserInformationClass,
1852 IN PVOID Buffer)
1853 {
1854 PSAMPR_USER_SET_PASSWORD_INFORMATION PasswordBuffer;
1855 SAMPR_USER_INTERNAL1_INFORMATION Internal1Buffer;
1856 USER_ALL_INFORMATION InternalAllBuffer;
1857 OEM_STRING LmPwdString;
1858 CHAR LmPwdBuffer[15];
1859 NTSTATUS Status;
1860
1861 TRACE("SamSetInformationUser(%p %lu %p)\n",
1862 UserHandle, UserInformationClass, Buffer);
1863
1864 if (UserInformationClass == UserSetPasswordInformation)
1865 {
1866 PasswordBuffer = (PSAMPR_USER_SET_PASSWORD_INFORMATION)Buffer;
1867
1868 Status = SampCheckPassword(UserHandle,
1869 (PUNICODE_STRING)&PasswordBuffer->Password);
1870 if (!NT_SUCCESS(Status))
1871 {
1872 TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
1873 return Status;
1874 }
1875
1876 /* Calculate the NT hash value of the passord */
1877 Status = SystemFunction007((PUNICODE_STRING)&PasswordBuffer->Password,
1878 (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword);
1879 if (!NT_SUCCESS(Status))
1880 {
1881 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
1882 return Status;
1883 }
1884
1885 Internal1Buffer.NtPasswordPresent = TRUE;
1886 Internal1Buffer.LmPasswordPresent = FALSE;
1887
1888 /* Build the LM password */
1889 LmPwdString.Length = 15;
1890 LmPwdString.MaximumLength = 15;
1891 LmPwdString.Buffer = LmPwdBuffer;
1892 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
1893
1894 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
1895 (PUNICODE_STRING)&PasswordBuffer->Password,
1896 FALSE);
1897 if (NT_SUCCESS(Status))
1898 {
1899 /* Calculate the LM hash value of the password */
1900 Status = SystemFunction006(LmPwdString.Buffer,
1901 (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword);
1902 if (NT_SUCCESS(Status))
1903 Internal1Buffer.LmPasswordPresent = TRUE;
1904 }
1905
1906 Internal1Buffer.PasswordExpired = PasswordBuffer->PasswordExpired;
1907
1908 RpcTryExcept
1909 {
1910 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
1911 UserInternal1Information,
1912 (PVOID)&Internal1Buffer);
1913 }
1914 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1915 {
1916 Status = I_RpcMapWin32Status(RpcExceptionCode());
1917 }
1918 RpcEndExcept;
1919
1920 if (!NT_SUCCESS(Status))
1921 {
1922 TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
1923 }
1924
1925 return Status;
1926 }
1927 else if (UserInformationClass == UserAllInformation)
1928 {
1929 RtlCopyMemory(&InternalAllBuffer,
1930 Buffer,
1931 sizeof(USER_ALL_INFORMATION));
1932
1933 if (InternalAllBuffer.WhichFields & (USER_ALL_LMPASSWORDPRESENT | USER_ALL_NTPASSWORDPRESENT))
1934 {
1935 if (InternalAllBuffer.WhichFields & USER_ALL_OWFPASSWORD)
1936 {
1937 /* Check NT password hash */
1938 if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
1939 {
1940 if (InternalAllBuffer.NtPassword.Length != sizeof(ENCRYPTED_NT_OWF_PASSWORD))
1941 return STATUS_INVALID_PARAMETER;
1942 }
1943
1944 /* Check LM password hash */
1945 if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
1946 {
1947 if (InternalAllBuffer.LmPassword.Length != sizeof(ENCRYPTED_LM_OWF_PASSWORD))
1948 return STATUS_INVALID_PARAMETER;
1949 }
1950 }
1951 else
1952 {
1953 /*
1954 * Only allow the NT password to be set.
1955 * The LM password will be created here.
1956 */
1957 if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
1958 {
1959 TRACE("Do not try to set a clear text LM password!\n");
1960 return STATUS_INVALID_PARAMETER;
1961 }
1962
1963 if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
1964 {
1965 Status = SampCheckPassword(UserHandle,
1966 &InternalAllBuffer.NtPassword);
1967 if (!NT_SUCCESS(Status))
1968 {
1969 TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
1970 return Status;
1971 }
1972
1973 /* Calculate the NT password hash */
1974 Status = SystemFunction007((PUNICODE_STRING)&InternalAllBuffer.NtPassword,
1975 (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword);
1976 if (!NT_SUCCESS(Status))
1977 {
1978 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
1979 return Status;
1980 }
1981
1982 InternalAllBuffer.NtPasswordPresent = TRUE;
1983 InternalAllBuffer.LmPasswordPresent = FALSE;
1984
1985 InternalAllBuffer.NtPassword.Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
1986 InternalAllBuffer.NtPassword.MaximumLength = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
1987 InternalAllBuffer.NtPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedNtOwfPassword;
1988
1989 /* Build the LM password */
1990 LmPwdString.Length = 15;
1991 LmPwdString.MaximumLength = 15;
1992 LmPwdString.Buffer = LmPwdBuffer;
1993 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
1994
1995 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
1996 (PUNICODE_STRING)&InternalAllBuffer.NtPassword,
1997 FALSE);
1998 if (NT_SUCCESS(Status))
1999 {
2000 /* Calculate the LM password hash */
2001 Status = SystemFunction006(LmPwdString.Buffer,
2002 (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword);
2003 if (NT_SUCCESS(Status))
2004 {
2005 InternalAllBuffer.WhichFields |= USER_ALL_LMPASSWORDPRESENT;
2006 InternalAllBuffer.LmPasswordPresent = TRUE;
2007
2008 InternalAllBuffer.LmPassword.Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
2009 InternalAllBuffer.LmPassword.MaximumLength = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
2010 InternalAllBuffer.LmPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedLmOwfPassword;
2011 }
2012 }
2013 }
2014 }
2015 }
2016
2017 RpcTryExcept
2018 {
2019 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
2020 UserAllInformation,
2021 (PVOID)&InternalAllBuffer);
2022 }
2023 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2024 {
2025 Status = I_RpcMapWin32Status(RpcExceptionCode());
2026 }
2027 RpcEndExcept;
2028
2029 if (!NT_SUCCESS(Status))
2030 {
2031 TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
2032 }
2033
2034 return Status;
2035 }
2036
2037 RpcTryExcept
2038 {
2039 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
2040 UserInformationClass,
2041 Buffer);
2042 }
2043 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2044 {
2045 Status = I_RpcMapWin32Status(RpcExceptionCode());
2046 }
2047 RpcEndExcept;
2048
2049 return Status;
2050 }
2051
2052
2053 NTSTATUS
2054 NTAPI
2055 SamSetMemberAttributesOfGroup(IN SAM_HANDLE GroupHandle,
2056 IN ULONG MemberId,
2057 IN ULONG Attributes)
2058 {
2059 NTSTATUS Status;
2060
2061 TRACE("SamSetMemberAttributesOfGroup(%p %lu 0x%lx)\n",
2062 GroupHandle, MemberId, Attributes);
2063
2064 RpcTryExcept
2065 {
2066 Status = SamrSetMemberAttributesOfGroup((SAMPR_HANDLE)GroupHandle,
2067 MemberId,
2068 Attributes);
2069 }
2070 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2071 {
2072 Status = I_RpcMapWin32Status(RpcExceptionCode());
2073 }
2074 RpcEndExcept;
2075
2076 return Status;
2077 }
2078
2079
2080 NTSTATUS
2081 NTAPI
2082 SamSetSecurityObject(IN SAM_HANDLE ObjectHandle,
2083 IN SECURITY_INFORMATION SecurityInformation,
2084 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
2085 {
2086 SAMPR_SR_SECURITY_DESCRIPTOR DescriptorToPass;
2087 ULONG Length;
2088 NTSTATUS Status;
2089
2090 TRACE("SamSetSecurityObject(%p %lu %p)\n",
2091 ObjectHandle, SecurityInformation, SecurityDescriptor);
2092
2093 /* Retrieve the length of the relative security descriptor */
2094 Length = 0;
2095 Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
2096 NULL,
2097 &Length);
2098 if (Status != STATUS_BUFFER_TOO_SMALL)
2099 return STATUS_INVALID_PARAMETER;
2100
2101
2102 /* Allocate a buffer for the security descriptor */
2103 DescriptorToPass.Length = Length;
2104 DescriptorToPass.SecurityDescriptor = MIDL_user_allocate(Length);
2105 if (DescriptorToPass.SecurityDescriptor == NULL)
2106 return STATUS_INSUFFICIENT_RESOURCES;
2107
2108 /* Convert the given security descriptor to a relative security descriptor */
2109 Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
2110 (PSECURITY_DESCRIPTOR)DescriptorToPass.SecurityDescriptor,
2111 &Length);
2112 if (!NT_SUCCESS(Status))
2113 goto done;
2114
2115 RpcTryExcept
2116 {
2117 Status = SamrSetSecurityObject((SAMPR_HANDLE)ObjectHandle,
2118 SecurityInformation,
2119 &DescriptorToPass);
2120 }
2121 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2122 {
2123 Status = I_RpcMapWin32Status(RpcExceptionCode());
2124 }
2125 RpcEndExcept;
2126
2127 done:
2128 if (DescriptorToPass.SecurityDescriptor != NULL)
2129 MIDL_user_free(DescriptorToPass.SecurityDescriptor);
2130
2131 return Status;
2132 }
2133
2134
2135 NTSTATUS
2136 NTAPI
2137 SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
2138 {
2139 NTSTATUS Status;
2140
2141 TRACE("(%p)\n", ServerHandle);
2142
2143 RpcTryExcept
2144 {
2145 Status = SamrShutdownSamServer((SAMPR_HANDLE)ServerHandle);
2146 }
2147 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2148 {
2149 Status = I_RpcMapWin32Status(RpcExceptionCode());
2150 }
2151 RpcEndExcept;
2152
2153 return Status;
2154 }
2155
2156 /* EOF */