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