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