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