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