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