* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: SAM interface library
/* INCLUDES *****************************************************************/
-#define NDEBUG
#include "precomp.h"
+WINE_DEFAULT_DEBUG_CHANNEL(samlib);
+
+NTSTATUS
+WINAPI
+SystemFunction006(LPCSTR password,
+ LPSTR hash);
+
+NTSTATUS
+WINAPI
+SystemFunction007(PUNICODE_STRING string,
+ LPBYTE hash);
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
+void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
-static BOOL
-CreateBuiltinAliases (HKEY hAliasesKey)
+
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
- return TRUE;
+ HeapFree(GetProcessHeap(), 0, ptr);
}
-static BOOL
-CreateBuiltinGroups (HKEY hGroupsKey)
+handle_t __RPC_USER
+PSAMPR_SERVER_NAME_bind(PSAMPR_SERVER_NAME pszSystemName)
{
- return TRUE;
+ handle_t hBinding = NULL;
+ LPWSTR pszStringBinding;
+ RPC_STATUS status;
+
+ TRACE("PSAMPR_SERVER_NAME_bind() called\n");
+
+ status = RpcStringBindingComposeW(NULL,
+ L"ncacn_np",
+ pszSystemName,
+ L"\\pipe\\samr",
+ NULL,
+ &pszStringBinding);
+ if (status)
+ {
+ TRACE("RpcStringBindingCompose returned 0x%x\n", status);
+ return NULL;
+ }
+
+ /* Set the binding handle that will be used to bind to the server. */
+ status = RpcBindingFromStringBindingW(pszStringBinding,
+ &hBinding);
+ if (status)
+ {
+ TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
+ }
+
+ status = RpcStringFreeW(&pszStringBinding);
+ if (status)
+ {
+// TRACE("RpcStringFree returned 0x%x\n", status);
+ }
+
+ return hBinding;
}
-static BOOL
-CreateBuiltinUsers (HKEY hUsersKey)
+void __RPC_USER
+PSAMPR_SERVER_NAME_unbind(PSAMPR_SERVER_NAME pszSystemName,
+ handle_t hBinding)
{
- return TRUE;
+ RPC_STATUS status;
+
+ TRACE("PSAMPR_SERVER_NAME_unbind() called\n");
+
+ status = RpcBindingFree(&hBinding);
+ if (status)
+ {
+ TRACE("RpcBindingFree returned 0x%x\n", status);
+ }
}
-BOOL WINAPI
-SamInitializeSAM (VOID)
+NTSTATUS
+SampCheckPassword(IN SAMPR_HANDLE UserHandle,
+ IN PUNICODE_STRING Password)
{
- DWORD dwDisposition;
- HKEY hSamKey;
- HKEY hDomainsKey;
- HKEY hAccountKey;
- HKEY hBuiltinKey;
- HKEY hAliasesKey;
- HKEY hGroupsKey;
- HKEY hUsersKey;
+ USER_DOMAIN_PASSWORD_INFORMATION DomainPasswordInformation;
+ ULONG PasswordLength;
+ NTSTATUS Status;
- DPRINT("SamInitializeSAM() called\n");
+ TRACE("(%p %p)\n", UserHandle, Password);
- if (RegCreateKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\SAM",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hSamKey,
- &dwDisposition))
+ /* Get the domain password information */
+ Status = SamrGetUserDomainPasswordInformation(UserHandle,
+ &DomainPasswordInformation);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1 ("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
- return FALSE;
+ TRACE("SamrGetUserDomainPasswordInformation failed (Status 0x%08lx)\n", Status);
+ return Status;
}
- if (RegCreateKeyExW (hSamKey,
- L"Domains",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hDomainsKey,
- &dwDisposition))
+ PasswordLength = (ULONG)(Password->Length / sizeof(WCHAR));
+
+ /* Fail if the password is too short or too long */
+ if ((PasswordLength < DomainPasswordInformation.MinPasswordLength) ||
+ (PasswordLength > 256))
+ return STATUS_PASSWORD_RESTRICTION;
+
+ /* Check the password complexity */
+ if (DomainPasswordInformation.PasswordProperties & DOMAIN_PASSWORD_COMPLEX)
{
- DPRINT1 ("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hSamKey);
- return FALSE;
+ /* FIXME */
}
- RegCloseKey (hSamKey);
+ return STATUS_SUCCESS;
+}
+
- /* Create the 'Domains\\Account' key */
- if (RegCreateKeyExW (hDomainsKey,
- L"Account",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hAccountKey,
- &dwDisposition))
+NTSTATUS
+NTAPI
+SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
+ IN PSID MemberId)
+{
+ NTSTATUS Status;
+
+ TRACE("SamAddMemberToAlias(%p %p)\n",
+ AliasHandle, MemberId);
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to create 'Domains\\Account' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle,
+ (PRPC_SID)MemberId);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
- /* Create the 'Account\Aliases' key */
- if (RegCreateKeyExW (hAccountKey,
- L"Aliases",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hAliasesKey,
- &dwDisposition))
+NTSTATUS
+NTAPI
+SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
+ IN ULONG MemberId,
+ IN ULONG Attributes)
+{
+ NTSTATUS Status;
+
+ TRACE("SamAddMemberToGroup(%p %lu %lx)\n",
+ GroupHandle, MemberId, Attributes);
+
+ RpcTryExcept
+ {
+ Status = SamrAddMemberToGroup((SAMPR_HANDLE)GroupHandle,
+ MemberId,
+ Attributes);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to create 'Account\\Aliases' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hAccountKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
- RegCloseKey (hAliasesKey);
+NTSTATUS
+NTAPI
+SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle,
+ IN PSID *MemberIds,
+ IN ULONG MemberCount)
+{
+ SAMPR_PSID_ARRAY Buffer;
+ NTSTATUS Status;
- /* Create the 'Account\Groups' key */
- if (RegCreateKeyExW (hAccountKey,
- L"Groups",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hGroupsKey,
- &dwDisposition))
+ TRACE("SamAddMultipleMembersToAlias(%p %p %lu)\n",
+ AliasHandle, MemberIds, MemberCount);
+
+ if (MemberIds == NULL)
+ return STATUS_INVALID_PARAMETER_2;
+
+ Buffer.Count = MemberCount;
+ Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to create 'Account\\Groups' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hAccountKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = SamrAddMultipleMembersToAlias((SAMPR_HANDLE)AliasHandle,
+ &Buffer);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
- RegCloseKey (hGroupsKey);
+NTSTATUS
+NTAPI
+SamChangePasswordUser(IN SAM_HANDLE UserHandle,
+ IN PUNICODE_STRING OldPassword,
+ IN PUNICODE_STRING NewPassword)
+{
+ ENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
+ ENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
+ ENCRYPTED_LM_OWF_PASSWORD OldLmPassword;
+ ENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
+ OEM_STRING LmPwdString;
+ CHAR LmPwdBuffer[15];
+ BOOLEAN OldLmPasswordPresent = FALSE;
+ BOOLEAN NewLmPasswordPresent = FALSE;
+ NTSTATUS Status;
+
+ /* Calculate the NT hash for the old password */
+ Status = SystemFunction007(OldPassword,
+ (LPBYTE)&OldNtPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
- /* Create the 'Account\Users' key */
- if (RegCreateKeyExW (hAccountKey,
- L"Users",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hUsersKey,
- &dwDisposition))
- {
- DPRINT1 ("Failed to create 'Account\\Users' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hAccountKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ /* Calculate the NT hash for the new password */
+ Status = SystemFunction007(NewPassword,
+ (LPBYTE)&NewNtPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
+ return Status;
}
- RegCloseKey (hUsersKey);
+ /* Calculate the LM password and hash for the old password */
+ LmPwdString.Length = 15;
+ LmPwdString.MaximumLength = 15;
+ LmPwdString.Buffer = LmPwdBuffer;
+ ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
- RegCloseKey (hAccountKey);
+ Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+ OldPassword,
+ FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Calculate the LM hash value of the password */
+ Status = SystemFunction006(LmPwdString.Buffer,
+ (LPSTR)&OldLmPassword);
+ if (NT_SUCCESS(Status))
+ {
+ OldLmPasswordPresent = TRUE;
+ }
+ }
+ /* Calculate the LM password and hash for the new password */
+ LmPwdString.Length = 15;
+ LmPwdString.MaximumLength = 15;
+ LmPwdString.Buffer = LmPwdBuffer;
+ ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
- /* Create the 'Domains\\Builtin' */
- if (RegCreateKeyExW (hDomainsKey,
- L"Builtin",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hBuiltinKey,
- &dwDisposition))
+ Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+ NewPassword,
+ FALSE);
+ if (NT_SUCCESS(Status))
{
- DPRINT1 ("Failed to create Builtin key! (Error %lu)\n", GetLastError());
- RegCloseKey (hDomainsKey);
- return FALSE;
+ /* Calculate the LM hash value of the password */
+ Status = SystemFunction006(LmPwdString.Buffer,
+ (LPSTR)&NewLmPassword);
+ if (NT_SUCCESS(Status))
+ {
+ NewLmPasswordPresent = TRUE;
+ }
}
+ RpcTryExcept
+ {
+ Status = SamrChangePasswordUser((SAMPR_HANDLE)UserHandle,
+ OldLmPasswordPresent && NewLmPasswordPresent,
+ &OldLmPassword,
+ &NewLmPassword,
+ TRUE,
+ &OldNtPassword,
+ &NewNtPassword,
+ FALSE,
+ NULL,
+ FALSE,
+ NULL);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamChangePasswordUser2(IN PUNICODE_STRING ServerName,
+ IN PUNICODE_STRING UserName,
+ IN PUNICODE_STRING OldPassword,
+ IN PUNICODE_STRING NewPassword)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+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)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+NTAPI
+SamCloseHandle(IN SAM_HANDLE SamHandle)
+{
+ NTSTATUS Status;
+
+ TRACE("SamCloseHandle(%p)\n", SamHandle);
- /* Create the 'Builtin\Aliases' key */
- if (RegCreateKeyExW (hBuiltinKey,
- L"Aliases",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hAliasesKey,
- &dwDisposition))
+ RpcTryExcept
+ {
+ Status = SamrCloseHandle((SAMPR_HANDLE *)&SamHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to create 'Builtin\\Aliases' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamConnect(IN OUT PUNICODE_STRING ServerName OPTIONAL,
+ OUT PSAM_HANDLE ServerHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ NTSTATUS Status;
- /* Create builtin aliases */
- if (!CreateBuiltinAliases (hAliasesKey))
+ TRACE("SamConnect(%p %p 0x%08x %p)\n",
+ ServerName, ServerHandle, DesiredAccess, ObjectAttributes);
+
+ RpcTryExcept
+ {
+ Status = SamrConnect((PSAMPR_SERVER_NAME)ServerName,
+ (SAMPR_HANDLE *)ServerHandle,
+ DesiredAccess);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to create builtin aliases!\n");
- RegCloseKey (hAliasesKey);
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
+ IN PUNICODE_STRING AccountName,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PSAM_HANDLE AliasHandle,
+ OUT PULONG RelativeId)
+{
+ NTSTATUS Status;
- RegCloseKey (hAliasesKey);
+ TRACE("SamCreateAliasInDomain(%p %p 0x%08x %p %p)\n",
+ DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
+ *AliasHandle = NULL;
+ *RelativeId = 0;
- /* Create the 'Builtin\Groups' key */
- if (RegCreateKeyExW (hBuiltinKey,
- L"Groups",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hGroupsKey,
- &dwDisposition))
+ RpcTryExcept
{
- DPRINT1 ("Failed to create 'Builtin\\Groups' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle,
+ (PRPC_UNICODE_STRING)AccountName,
+ DesiredAccess,
+ (SAMPR_HANDLE *)AliasHandle,
+ RelativeId);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle,
+ IN PUNICODE_STRING AccountName,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PSAM_HANDLE GroupHandle,
+ OUT PULONG RelativeId)
+{
+ NTSTATUS Status;
- /* Create builtin groups */
- if (!CreateBuiltinGroups (hGroupsKey))
+ TRACE("SamCreateGroupInDomain(%p %p 0x%08x %p %p)\n",
+ DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId);
+
+ *GroupHandle = NULL;
+ *RelativeId = 0;
+
+ RpcTryExcept
+ {
+ Status = SamrCreateGroupInDomain((SAMPR_HANDLE)DomainHandle,
+ (PRPC_UNICODE_STRING)AccountName,
+ DesiredAccess,
+ (SAMPR_HANDLE *)GroupHandle,
+ RelativeId);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to create builtin groups!\n");
- RegCloseKey (hGroupsKey);
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
- RegCloseKey (hGroupsKey);
+ return Status;
+}
+
+
+NTSTATUS
+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)
+{
+ NTSTATUS Status;
+ TRACE("SamCreateUser2InDomain(%p %p %lu 0x%08x %p %p %p)\n",
+ DomainHandle, AccountName, AccountType, DesiredAccess,
+ UserHandle, GrantedAccess, RelativeId);
- /* Create the 'Builtin\Users' key */
- if (RegCreateKeyExW (hBuiltinKey,
- L"Users",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hUsersKey,
- &dwDisposition))
+ *UserHandle = NULL;
+ *RelativeId = 0;
+
+ RpcTryExcept
+ {
+ Status = SamrCreateUser2InDomain((SAMPR_HANDLE)DomainHandle,
+ (PRPC_UNICODE_STRING)AccountName,
+ AccountType,
+ DesiredAccess,
+ (SAMPR_HANDLE *)UserHandle,
+ GrantedAccess,
+ RelativeId);
+
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to create 'Builtin\\Users' key! (Error %lu)\n", GetLastError());
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
+
- /* Create builtin users */
- if (!CreateBuiltinUsers (hUsersKey))
+NTSTATUS
+NTAPI
+SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
+ IN PUNICODE_STRING AccountName,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PSAM_HANDLE UserHandle,
+ OUT PULONG RelativeId)
+{
+ NTSTATUS Status;
+
+ TRACE("SamCreateUserInDomain(%p %p 0x%08x %p %p)\n",
+ DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId);
+
+ *UserHandle = NULL;
+ *RelativeId = 0;
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to create builtin users!\n");
- RegCloseKey (hUsersKey);
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
- return FALSE;
+ Status = SamrCreateUserInDomain((SAMPR_HANDLE)DomainHandle,
+ (PRPC_UNICODE_STRING)AccountName,
+ DesiredAccess,
+ (SAMPR_HANDLE *)UserHandle,
+ RelativeId);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- RegCloseKey (hUsersKey);
+ return Status;
+}
- RegCloseKey (hBuiltinKey);
- RegCloseKey (hDomainsKey);
+NTSTATUS
+NTAPI
+SamDeleteAlias(IN SAM_HANDLE AliasHandle)
+{
+ SAMPR_HANDLE LocalAliasHandle;
+ NTSTATUS Status;
- DPRINT ("SamInitializeSAM() done\n");
+ TRACE("SamDeleteAlias(%p)\n", AliasHandle);
+
+ LocalAliasHandle = (SAMPR_HANDLE)AliasHandle;
+
+ if (LocalAliasHandle == NULL)
+ return STATUS_INVALID_HANDLE;
+
+ RpcTryExcept
+ {
+ Status = SamrDeleteAlias(&LocalAliasHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- return TRUE;
+ return Status;
}
-BOOL WINAPI
-SamGetDomainSid (PSID *Sid)
+NTSTATUS
+NTAPI
+SamDeleteGroup(IN SAM_HANDLE GroupHandle)
{
- DPRINT ("SamGetDomainSid() called\n");
+ SAMPR_HANDLE LocalGroupHandle;
+ NTSTATUS Status;
- return FALSE;
+ TRACE("SamDeleteGroup(%p)\n", GroupHandle);
+
+ LocalGroupHandle = (SAMPR_HANDLE)GroupHandle;
+
+ if (LocalGroupHandle == NULL)
+ return STATUS_INVALID_HANDLE;
+
+ RpcTryExcept
+ {
+ Status = SamrDeleteGroup(&LocalGroupHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
}
-BOOL WINAPI
-SamSetDomainSid (PSID Sid)
+NTSTATUS
+NTAPI
+SamDeleteUser(IN SAM_HANDLE UserHandle)
{
- HKEY hAccountKey;
+ SAMPR_HANDLE LocalUserHandle;
+ NTSTATUS Status;
- DPRINT ("SamSetDomainSid() called\n");
+ TRACE("SamDeleteUser(%p)\n", UserHandle);
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\SAM\\Domains\\Account",
- 0,
- KEY_ALL_ACCESS,
- &hAccountKey))
+ LocalUserHandle = (SAMPR_HANDLE)UserHandle;
+
+ if (LocalUserHandle == NULL)
+ return STATUS_INVALID_HANDLE;
+
+ RpcTryExcept
+ {
+ Status = SamrDeleteUser(&LocalUserHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to open the Account key! (Error %lu)\n", GetLastError());
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
- if (RegSetValueExW (hAccountKey,
- L"Sid",
- 0,
- REG_BINARY,
- (LPBYTE)Sid,
- RtlLengthSid (Sid)))
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
+ IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+ OUT PVOID *Buffer,
+ IN ULONG PreferedMaximumLength,
+ OUT PULONG CountReturned)
+{
+ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
+ DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength,
+ CountReturned);
+
+ if ((EnumerationContext == NULL) ||
+ (Buffer == NULL) ||
+ (CountReturned == NULL))
+ return STATUS_INVALID_PARAMETER;
+
+ *Buffer = NULL;
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to set Domain-SID value! (Error %lu)\n", GetLastError());
- RegCloseKey (hAccountKey);
- return FALSE;
+ Status = SamrEnumerateAliasesInDomain((SAMPR_HANDLE)DomainHandle,
+ EnumerationContext,
+ &EnumBuffer,
+ PreferedMaximumLength,
+ CountReturned);
+
+ if (EnumBuffer != NULL)
+ {
+ if (EnumBuffer->Buffer != NULL)
+ {
+ *Buffer = EnumBuffer->Buffer;
+ }
+
+ midl_user_free(EnumBuffer);
+ }
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- RegCloseKey (hAccountKey);
+ return Status;
+}
- DPRINT ("SamSetDomainSid() called\n");
- return TRUE;
+NTSTATUS
+NTAPI
+SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
+ IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+ OUT PVOID *Buffer,
+ IN ULONG PreferedMaximumLength,
+ OUT PULONG CountReturned)
+{
+ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
+ ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
+ CountReturned);
+
+ if ((EnumerationContext == NULL) ||
+ (Buffer == NULL) ||
+ (CountReturned == NULL))
+ return STATUS_INVALID_PARAMETER;
+
+ *Buffer = NULL;
+
+ RpcTryExcept
+ {
+ Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle,
+ EnumerationContext,
+ &EnumBuffer,
+ PreferedMaximumLength,
+ CountReturned);
+
+ if (EnumBuffer != NULL)
+ {
+ if (EnumBuffer->Buffer != NULL)
+ {
+ *Buffer = EnumBuffer->Buffer;
+ }
+
+ midl_user_free(EnumBuffer);
+ }
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
}
-/*
- * ERROR_USER_EXISTS
- */
-BOOL WINAPI
-SamCreateUser (PWSTR UserName,
- PWSTR UserPassword,
- PSID UserSid)
+NTSTATUS
+NTAPI
+SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle,
+ IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+ IN PVOID *Buffer,
+ IN ULONG PreferedMaximumLength,
+ OUT PULONG CountReturned)
{
- DWORD dwDisposition;
- HKEY hUsersKey;
- HKEY hUserKey;
+ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+ NTSTATUS Status;
- DPRINT ("SamCreateUser() called\n");
+ TRACE("SamEnumerateGroupsInDomain(%p %p %p %lu %p)\n",
+ DomainHandle, EnumerationContext, Buffer,
+ PreferedMaximumLength, CountReturned);
- /* FIXME: Check whether the SID is a real user sid */
+ if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
+ return STATUS_INVALID_PARAMETER;
- /* Open the Users key */
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\SAM\\Domains\\Account\\Users",
- 0,
- KEY_ALL_ACCESS,
- &hUsersKey))
+ *Buffer = NULL;
+
+ RpcTryExcept
+ {
+ Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle,
+ EnumerationContext,
+ &EnumBuffer,
+ PreferedMaximumLength,
+ CountReturned);
+ if (EnumBuffer != NULL)
+ {
+ if (EnumBuffer->Buffer != NULL)
+ *Buffer = EnumBuffer->Buffer;
+
+ midl_user_free(EnumBuffer);
+ }
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to open Account key! (Error %lu)\n", GetLastError());
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle,
+ IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+ IN ULONG UserAccountControl,
+ OUT PVOID *Buffer,
+ IN ULONG PreferedMaximumLength,
+ OUT PULONG CountReturned)
+{
+ PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
+ DomainHandle, EnumerationContext, UserAccountControl, Buffer,
+ PreferedMaximumLength, CountReturned);
+
+ if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
+ return STATUS_INVALID_PARAMETER;
+
+ *Buffer = NULL;
- /* Create user name key */
- if (RegCreateKeyExW (hUsersKey,
- UserName,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hUserKey,
- &dwDisposition))
+ RpcTryExcept
{
- DPRINT1 ("Failed to create/open the user key! (Error %lu)\n", GetLastError());
- RegCloseKey (hUsersKey);
- return FALSE;
+ Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle,
+ EnumerationContext,
+ UserAccountControl,
+ &EnumBuffer,
+ PreferedMaximumLength,
+ CountReturned);
+ if (EnumBuffer != NULL)
+ {
+ if (EnumBuffer->Buffer != NULL)
+ {
+ *Buffer = EnumBuffer->Buffer;
+ }
+
+ midl_user_free(EnumBuffer);
+ }
+
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamFreeMemory(IN PVOID Buffer)
+{
+ if (Buffer != NULL)
+ midl_user_free(Buffer);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+SamGetAliasMembership(IN SAM_HANDLE DomainHandle,
+ IN ULONG PassedCount,
+ IN PSID *Sids,
+ OUT PULONG MembershipCount,
+ OUT PULONG *Aliases)
+{
+ SAMPR_PSID_ARRAY SidArray;
+ SAMPR_ULONG_ARRAY Membership;
+ NTSTATUS Status;
+
+ TRACE("SamAliasMembership(%p %lu %p %p %p)\n",
+ DomainHandle, PassedCount, Sids, MembershipCount, Aliases);
+
+ if (Sids == NULL ||
+ MembershipCount == NULL ||
+ Aliases == NULL)
+ return STATUS_INVALID_PARAMETER;
- RegCloseKey (hUsersKey);
+ Membership.Element = NULL;
- if (dwDisposition == REG_OPENED_EXISTING_KEY)
+ RpcTryExcept
{
- DPRINT1 ("User already exists!\n");
- RegCloseKey (hUserKey);
- SetLastError (ERROR_USER_EXISTS);
- return FALSE;
+ SidArray.Count = PassedCount;
+ SidArray.Sids = (PSAMPR_SID_INFORMATION)Sids;
+
+ Status = SamrGetAliasMembership((SAMPR_HANDLE)DomainHandle,
+ &SidArray,
+ &Membership);
+ if (NT_SUCCESS(Status))
+ {
+ *MembershipCount = Membership.Count;
+ *Aliases = Membership.Element;
+ }
+ else
+ {
+ if (Membership.Element != NULL)
+ midl_user_free(Membership.Element);
+ }
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamGetCompatibilityMode(IN SAM_HANDLE ObjectHandle,
+ OUT PULONG Mode)
+{
+ TRACE("(%p %p)\n", ObjectHandle, Mode);
+
+ if (Mode == NULL)
+ return STATUS_INVALID_PARAMETER;
+ *Mode = SAM_SID_COMPATIBILITY_ALL;
- /* Set 'Name' value */
- if (RegSetValueExW (hUserKey,
- L"Name",
- 0,
- REG_SZ,
- (LPBYTE)UserName,
- (wcslen (UserName) + 1) * sizeof (WCHAR)))
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+SamGetDisplayEnumerationIndex(IN SAM_HANDLE DomainHandle,
+ IN DOMAIN_DISPLAY_INFORMATION DisplayInformation,
+ IN PUNICODE_STRING Prefix,
+ OUT PULONG Index)
+{
+ NTSTATUS Status;
+
+ TRACE("(%p %lu %wZ %p)\n",
+ DomainHandle, DisplayInformation, Prefix, Index);
+
+ if ((Prefix == NULL) ||
+ (Index == NULL))
+ return STATUS_INVALID_PARAMETER;
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to set the user name value! (Error %lu)\n", GetLastError());
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = SamrGetDisplayEnumerationIndex2((SAMPR_HANDLE)DomainHandle,
+ DisplayInformation,
+ (PRPC_UNICODE_STRING)Prefix,
+ Index);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
- /* Set 'Password' value */
- if (RegSetValueExW (hUserKey,
- L"Password",
- 0,
- REG_SZ,
- (LPBYTE)UserPassword,
- (wcslen (UserPassword) + 1) * sizeof (WCHAR)))
+NTSTATUS
+NTAPI
+SamGetGroupsForUser(IN SAM_HANDLE UserHandle,
+ OUT PGROUP_MEMBERSHIP *Groups,
+ OUT PULONG MembershipCount)
+{
+ PSAMPR_GET_GROUPS_BUFFER GroupsBuffer = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamGetGroupsForUser(%p %p %p)\n",
+ UserHandle, Groups, MembershipCount);
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to set the user name value! (Error %lu)\n", GetLastError());
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = SamrGetGroupsForUser((SAMPR_HANDLE)UserHandle,
+ &GroupsBuffer);
+ if (NT_SUCCESS(Status))
+ {
+ *Groups = GroupsBuffer->Groups;
+ *MembershipCount = GroupsBuffer->MembershipCount;
+
+ MIDL_user_free(GroupsBuffer);
+ }
+ else
+ {
+ if (GroupsBuffer != NULL)
+ {
+ if (GroupsBuffer->Groups != NULL)
+ MIDL_user_free(GroupsBuffer->Groups);
+
+ MIDL_user_free(GroupsBuffer);
+ }
+ }
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
+ OUT PSID **MemberIds,
+ OUT PULONG MemberCount)
+{
+ SAMPR_PSID_ARRAY_OUT SidArray;
+ NTSTATUS Status;
+
+ TRACE("SamGetMembersInAlias(%p %p %p)\n",
+ AliasHandle, MemberIds, MemberCount);
- /* Set 'Sid' value */
- if (RegSetValueExW (hUserKey,
- L"Sid",
- 0,
- REG_BINARY,
- (LPBYTE)UserSid,
- RtlLengthSid (UserSid)))
+ if ((MemberIds == NULL) ||
+ (MemberCount == NULL))
+ return STATUS_INVALID_PARAMETER;
+
+ *MemberIds = NULL;
+ *MemberCount = 0;
+
+ SidArray.Sids = NULL;
+
+ RpcTryExcept
+ {
+ Status = SamrGetMembersInAlias((SAMPR_HANDLE)AliasHandle,
+ &SidArray);
+ if (NT_SUCCESS(Status))
+ {
+ *MemberCount = SidArray.Count;
+ *MemberIds = (PSID *)SidArray.Sids;
+ }
+
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to set the user SID value! (Error %lu)\n", GetLastError());
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ return Status;
+}
- RegCloseKey (hUserKey);
- DPRINT ("SamCreateUser() done\n");
+NTSTATUS
+NTAPI
+SamGetMembersInGroup(IN SAM_HANDLE GroupHandle,
+ OUT PULONG *MemberIds,
+ OUT PULONG *Attributes,
+ OUT PULONG MemberCount)
+{
+ PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamGetMembersInGroup(%p %p %p %p)\n",
+ GroupHandle, MemberIds, Attributes, MemberCount);
+
+ RpcTryExcept
+ {
+ Status = SamrGetMembersInGroup((SAMPR_HANDLE)GroupHandle,
+ &MembersBuffer);
+ if (NT_SUCCESS(Status))
+ {
+ *MemberIds = MembersBuffer->Members;
+ *Attributes = MembersBuffer->Attributes;
+ *MemberCount = MembersBuffer->MemberCount;
+
+ MIDL_user_free(MembersBuffer);
+ }
+ else
+ {
+ if (MembersBuffer != NULL)
+ {
+ if (MembersBuffer->Members != NULL)
+ MIDL_user_free(MembersBuffer->Members);
+
+ if (MembersBuffer->Attributes != NULL)
+ MIDL_user_free(MembersBuffer->Attributes);
+
+ MIDL_user_free(MembersBuffer);
+ }
+ }
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- return TRUE;
+ return Status;
}
-/*
- * ERROR_WRONG_PASSWORD
- * ERROR_NO_SUCH_USER
- */
-BOOL WINAPI
-SamCheckUserPassword (PWSTR UserName,
- PWSTR UserPassword)
+NTSTATUS
+NTAPI
+SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
+ IN PUNICODE_STRING Name,
+ OUT PSID *DomainId)
{
- WCHAR szPassword[256];
- DWORD dwLength;
- HKEY hUsersKey;
- HKEY hUserKey;
+ NTSTATUS Status;
- DPRINT ("SamCheckUserPassword() called\n");
+ TRACE("SamLookupDomainInSamServer(%p %p %p)\n",
+ ServerHandle, Name, DomainId);
- /* Open the Users key */
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\SAM\\Domains\\Account\\Users",
- 0,
- KEY_READ,
- &hUsersKey))
+ RpcTryExcept
+ {
+ Status = SamrLookupDomainInSamServer((SAMPR_HANDLE)ServerHandle,
+ (PRPC_UNICODE_STRING)Name,
+ (PRPC_SID *)DomainId);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError());
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
- /* Open the user key */
- if (RegOpenKeyExW (hUsersKey,
- UserName,
- 0,
- KEY_READ,
- &hUserKey))
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle,
+ IN ULONG Count,
+ IN PULONG RelativeIds,
+ OUT PUNICODE_STRING *Names,
+ OUT PSID_NAME_USE *Use OPTIONAL)
+{
+ SAMPR_RETURNED_USTRING_ARRAY NamesBuffer = {0, NULL};
+ SAMPR_ULONG_ARRAY UseBuffer = {0, NULL};
+ ULONG i;
+ NTSTATUS Status;
+
+ TRACE("SamLookupIdsInDomain(%p %lu %p %p %p)\n",
+ DomainHandle, Count, RelativeIds, Names, Use);
+
+ *Names = NULL;
+
+ if (Use != NULL)
+ *Use = NULL;
+
+ RpcTryExcept
{
- if (GetLastError () == ERROR_FILE_NOT_FOUND)
- {
- DPRINT1 ("Invalid user name!\n");
- SetLastError (ERROR_NO_SUCH_USER);
- }
- else
- {
- DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError());
- }
+ Status = SamrLookupIdsInDomain((SAMPR_HANDLE)DomainHandle,
+ Count,
+ RelativeIds,
+ &NamesBuffer,
+ &UseBuffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- RegCloseKey (hUsersKey);
- return FALSE;
+ if (NT_SUCCESS(Status))
+ {
+ *Names = midl_user_allocate(Count * sizeof(RPC_UNICODE_STRING));
+ if (*Names == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ for (i = 0; i < Count; i++)
+ {
+ (*Names)[i].Buffer = midl_user_allocate(NamesBuffer.Element[i].MaximumLength);
+ if ((*Names)[i].Buffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+ }
+
+ for (i = 0; i < Count; i++)
+ {
+ (*Names)[i].Length = NamesBuffer.Element[i].Length;
+ (*Names)[i].MaximumLength = NamesBuffer.Element[i].MaximumLength;
+
+ RtlCopyMemory((*Names)[i].Buffer,
+ NamesBuffer.Element[i].Buffer,
+ NamesBuffer.Element[i].Length);
+ }
+
+ if (Use != NULL)
+ {
+ *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE));
+ if (*Use == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ RtlCopyMemory(*Use,
+ UseBuffer.Element,
+ Count * sizeof(SID_NAME_USE));
+ }
+ }
+
+done:
+ if (!NT_SUCCESS(Status))
+ {
+ if (*Names != NULL)
+ {
+ for (i = 0; i < Count; i++)
+ {
+ if ((*Names)[i].Buffer != NULL)
+ midl_user_free((*Names)[i].Buffer);
+ }
+
+ midl_user_free(*Names);
+ }
+
+ if (Use != NULL && *Use != NULL)
+ midl_user_free(*Use);
+ }
+
+ if (NamesBuffer.Element != NULL)
+ {
+ for (i = 0; i < NamesBuffer.Count; i++)
+ {
+ if (NamesBuffer.Element[i].Buffer != NULL)
+ midl_user_free(NamesBuffer.Element[i].Buffer);
+ }
+
+ midl_user_free(NamesBuffer.Element);
}
- RegCloseKey (hUsersKey);
+ if (UseBuffer.Element != NULL)
+ midl_user_free(UseBuffer.Element);
- /* Get the password */
- dwLength = 256 * sizeof(WCHAR);
- if (RegQueryValueExW (hUserKey,
- L"Password",
- NULL,
- NULL,
- (LPBYTE)szPassword,
- &dwLength))
+ return 0;
+}
+
+
+NTSTATUS
+NTAPI
+SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle,
+ IN ULONG Count,
+ IN PUNICODE_STRING Names,
+ OUT PULONG *RelativeIds,
+ OUT PSID_NAME_USE *Use)
+{
+ SAMPR_ULONG_ARRAY RidBuffer = {0, NULL};
+ SAMPR_ULONG_ARRAY UseBuffer = {0, NULL};
+ NTSTATUS Status;
+
+ TRACE("SamLookupNamesInDomain(%p %lu %p %p %p)\n",
+ DomainHandle, Count, Names, RelativeIds, Use);
+
+ *RelativeIds = NULL;
+ *Use = NULL;
+
+ RpcTryExcept
{
- DPRINT1 ("Failed to read the password! (Error %lu)\n", GetLastError());
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = SamrLookupNamesInDomain((SAMPR_HANDLE)DomainHandle,
+ Count,
+ (PRPC_UNICODE_STRING)Names,
+ &RidBuffer,
+ &UseBuffer);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ if (NT_SUCCESS(Status))
+ {
+ *RelativeIds = midl_user_allocate(Count * sizeof(ULONG));
+ if (*RelativeIds == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE));
+ if (*Use == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ RtlCopyMemory(*RelativeIds,
+ RidBuffer.Element,
+ Count * sizeof(ULONG));
+
+ RtlCopyMemory(*Use,
+ UseBuffer.Element,
+ Count * sizeof(SID_NAME_USE));
+ }
+
+done:
+ if (!NT_SUCCESS(Status))
+ {
+ if (*RelativeIds != NULL)
+ midl_user_free(*RelativeIds);
+
+ if (*Use != NULL)
+ midl_user_free(*Use);
+ }
+
+ if (RidBuffer.Element != NULL)
+ midl_user_free(RidBuffer.Element);
+
+ if (UseBuffer.Element != NULL)
+ midl_user_free(UseBuffer.Element);
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamOpenAlias(IN SAM_HANDLE DomainHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG AliasId,
+ OUT PSAM_HANDLE AliasHandle)
+{
+ NTSTATUS Status;
- RegCloseKey (hUserKey);
+ TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n",
+ DomainHandle, DesiredAccess, AliasId, AliasHandle);
- /* Compare passwords */
- if ((wcslen (szPassword) != wcslen (UserPassword)) ||
- (wcscmp (szPassword, UserPassword) != 0))
+ RpcTryExcept
{
- DPRINT1 ("Wrong password!\n");
- SetLastError (ERROR_WRONG_PASSWORD);
- return FALSE;
+ Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle,
+ DesiredAccess,
+ AliasId,
+ (SAMPR_HANDLE *)AliasHandle);
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamOpenDomain(IN SAM_HANDLE ServerHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN PSID DomainId,
+ OUT PSAM_HANDLE DomainHandle)
+{
+ NTSTATUS Status;
+
+ TRACE("SamOpenDomain(%p 0x%08x %p %p)\n",
+ ServerHandle, DesiredAccess, DomainId, DomainHandle);
+
+ RpcTryExcept
+ {
+ Status = SamrOpenDomain((SAMPR_HANDLE)ServerHandle,
+ DesiredAccess,
+ (PRPC_SID)DomainId,
+ (SAMPR_HANDLE *)DomainHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamOpenGroup(IN SAM_HANDLE DomainHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG GroupId,
+ OUT PSAM_HANDLE GroupHandle)
+{
+ NTSTATUS Status;
+
+ TRACE("SamOpenGroup(%p 0x%08x %p %p)\n",
+ DomainHandle, DesiredAccess, GroupId, GroupHandle);
+
+ RpcTryExcept
+ {
+ Status = SamrOpenGroup((SAMPR_HANDLE)DomainHandle,
+ DesiredAccess,
+ GroupId,
+ (SAMPR_HANDLE *)GroupHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamOpenUser(IN SAM_HANDLE DomainHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG UserId,
+ OUT PSAM_HANDLE UserHandle)
+{
+ NTSTATUS Status;
+
+ TRACE("SamOpenUser(%p 0x%08x %lx %p)\n",
+ DomainHandle, DesiredAccess, UserId, UserHandle);
- DPRINT ("SamCheckUserPassword() done\n");
+ RpcTryExcept
+ {
+ Status = SamrOpenUser((SAMPR_HANDLE)DomainHandle,
+ DesiredAccess,
+ UserId,
+ (SAMPR_HANDLE *)UserHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- return TRUE;
+ return Status;
}
-BOOL WINAPI
-SamGetUserSid (PWSTR UserName,
- PSID *Sid)
+NTSTATUS
+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)
{
- PSID lpSid;
- DWORD dwLength;
- HKEY hUsersKey;
- HKEY hUserKey;
+ SAMPR_DISPLAY_INFO_BUFFER LocalBuffer;
+ NTSTATUS Status;
- DPRINT ("SamGetUserSid() called\n");
+ TRACE("(%p %lu %lu %lu %lu %p %p %p %p)\n",
+ DomainHandle, DisplayInformation, Index, EntryCount,
+ PreferredMaximumLength, TotalAvailable, TotalReturned,
+ ReturnedEntryCount, SortedBuffer);
- if (Sid != NULL)
- *Sid = NULL;
+ if ((TotalAvailable == NULL) ||
+ (TotalReturned == NULL) ||
+ (ReturnedEntryCount == NULL) ||
+ (SortedBuffer == NULL))
+ return STATUS_INVALID_PARAMETER;
- /* Open the Users key */
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
- L"SAM\\SAM\\Domains\\Account\\Users",
- 0,
- KEY_READ,
- &hUsersKey))
+ RpcTryExcept
{
- DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError());
- return FALSE;
+ Status = SamrQueryDisplayInformation3((SAMPR_HANDLE)DomainHandle,
+ DisplayInformation,
+ Index,
+ EntryCount,
+ PreferredMaximumLength,
+ TotalAvailable,
+ TotalReturned,
+ &LocalBuffer);
+ if (NT_SUCCESS(Status))
+ {
+ switch (DisplayInformation)
+ {
+ case DomainDisplayUser:
+ *ReturnedEntryCount = LocalBuffer.UserInformation.EntriesRead;
+ *SortedBuffer = LocalBuffer.UserInformation.Buffer;
+ break;
+
+ case DomainDisplayMachine:
+ *ReturnedEntryCount = LocalBuffer.MachineInformation.EntriesRead;
+ *SortedBuffer = LocalBuffer.MachineInformation.Buffer;
+ break;
+
+ case DomainDisplayGroup:
+ *ReturnedEntryCount = LocalBuffer.GroupInformation.EntriesRead;
+ *SortedBuffer = LocalBuffer.GroupInformation.Buffer;
+ break;
+
+ case DomainDisplayOemUser:
+ *ReturnedEntryCount = LocalBuffer.OemUserInformation.EntriesRead;
+ *SortedBuffer = LocalBuffer.OemUserInformation.Buffer;
+ break;
+
+ case DomainDisplayOemGroup:
+ *ReturnedEntryCount = LocalBuffer.OemGroupInformation.EntriesRead;
+ *SortedBuffer = LocalBuffer.OemGroupInformation.Buffer;
+ break;
+
+ case DomainDisplayServer:
+ /* FIXME */
+ break;
+ }
+ }
+ else
+ {
+ *ReturnedEntryCount = 0;
+ *SortedBuffer = NULL;
+ }
}
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
- /* Open the user key */
- if (RegOpenKeyExW (hUsersKey,
- UserName,
- 0,
- KEY_READ,
- &hUserKey))
+
+NTSTATUS
+NTAPI
+SamQueryInformationAlias(IN SAM_HANDLE AliasHandle,
+ IN ALIAS_INFORMATION_CLASS AliasInformationClass,
+ OUT PVOID *Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamQueryInformationAlias(%p %lu %p)\n",
+ AliasHandle, AliasInformationClass, Buffer);
+
+ RpcTryExcept
{
- if (GetLastError () == ERROR_FILE_NOT_FOUND)
- {
- DPRINT1 ("Invalid user name!\n");
- SetLastError (ERROR_NO_SUCH_USER);
- }
- else
- {
- DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError());
- }
+ Status = SamrQueryInformationAlias((SAMPR_HANDLE)AliasHandle,
+ AliasInformationClass,
+ (PSAMPR_ALIAS_INFO_BUFFER *)Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- RegCloseKey (hUsersKey);
- return FALSE;
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
+ IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
+ OUT PVOID *Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamQueryInformationDomain(%p %lu %p)\n",
+ DomainHandle, DomainInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle,
+ DomainInformationClass,
+ (PSAMPR_DOMAIN_INFO_BUFFER *)Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
- RegCloseKey (hUsersKey);
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamQueryInformationGroup(IN SAM_HANDLE GroupHandle,
+ IN GROUP_INFORMATION_CLASS GroupInformationClass,
+ OUT PVOID *Buffer)
+{
+ NTSTATUS Status;
- /* Get SID size */
- dwLength = 0;
- if (RegQueryValueExW (hUserKey,
- L"Sid",
- NULL,
- NULL,
- NULL,
- &dwLength))
+ TRACE("SamQueryInformationGroup(%p %lu %p)\n",
+ GroupHandle, GroupInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrQueryInformationGroup((SAMPR_HANDLE)GroupHandle,
+ GroupInformationClass,
+ (PSAMPR_GROUP_INFO_BUFFER *)Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to read the SID size! (Error %lu)\n", GetLastError());
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
- /* Allocate sid buffer */
- DPRINT ("Required SID buffer size: %lu\n", dwLength);
- lpSid = (PSID)RtlAllocateHeap (RtlGetProcessHeap (),
- 0,
- dwLength);
- if (lpSid == NULL)
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamQueryInformationUser(IN SAM_HANDLE UserHandle,
+ IN USER_INFORMATION_CLASS UserInformationClass,
+ OUT PVOID *Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamQueryInformationUser(%p %lu %p)\n",
+ UserHandle, UserInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle,
+ UserInformationClass,
+ (PSAMPR_USER_INFO_BUFFER *)Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle,
+ IN SECURITY_INFORMATION SecurityInformation,
+ OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
+{
+ PSAMPR_SR_SECURITY_DESCRIPTOR SamSecurityDescriptor = NULL;
+ NTSTATUS Status;
+
+ TRACE("SamQuerySecurityObject(%p %lu %p)\n",
+ ObjectHandle, SecurityInformation, SecurityDescriptor);
+
+ *SecurityDescriptor = NULL;
+
+ RpcTryExcept
+ {
+ Status = SamrQuerySecurityObject((SAMPR_HANDLE)ObjectHandle,
+ SecurityInformation,
+ &SamSecurityDescriptor);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1 ("Failed to allocate SID buffer!\n");
- RegCloseKey (hUserKey);
- return FALSE;
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
}
+ RpcEndExcept;
+
+ TRACE("SamSecurityDescriptor: %p\n", SamSecurityDescriptor);
- /* Read sid */
- if (RegQueryValueExW (hUserKey,
- L"Sid",
- NULL,
- NULL,
- (LPBYTE)lpSid,
- &dwLength))
+ if (SamSecurityDescriptor != NULL)
{
- DPRINT1 ("Failed to read the SID! (Error %lu)\n", GetLastError());
- RtlFreeHeap (RtlGetProcessHeap (),
- 0,
- lpSid);
- RegCloseKey (hUserKey);
- return FALSE;
+ TRACE("SamSecurityDescriptor->Length: %lu\n", SamSecurityDescriptor->Length);
+ TRACE("SamSecurityDescriptor->SecurityDescriptor: %p\n", SamSecurityDescriptor->SecurityDescriptor);
+
+ *SecurityDescriptor = SamSecurityDescriptor->SecurityDescriptor;
+
+ midl_user_free(SamSecurityDescriptor);
}
- RegCloseKey (hUserKey);
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle,
+ IN PSID MemberId)
+{
+ NTSTATUS Status;
- *Sid = lpSid;
+ TRACE("SamRemoveMemberFromAlias(%p %ul)\n",
+ AliasHandle, MemberId);
- DPRINT ("SamGetUserSid() done\n");
+ RpcTryExcept
+ {
+ Status = SamrRemoveMemberFromAlias((SAMPR_HANDLE)AliasHandle,
+ MemberId);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamRemoveMemberFromForeignDomain(IN SAM_HANDLE DomainHandle,
+ IN PSID MemberId)
+{
+ NTSTATUS Status;
+
+ TRACE("SamRemoveMemberFromForeignDomain(%p %ul)\n",
+ DomainHandle, MemberId);
+
+ RpcTryExcept
+ {
+ Status = SamrRemoveMemberFromForeignDomain((SAMPR_HANDLE)DomainHandle,
+ MemberId);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamRemoveMemberFromGroup(IN SAM_HANDLE GroupHandle,
+ IN ULONG MemberId)
+{
+ NTSTATUS Status;
+
+ TRACE("SamRemoveMemberFromGroup(%p %ul)\n",
+ GroupHandle, MemberId);
+
+ RpcTryExcept
+ {
+ Status = SamrRemoveMemberFromGroup((SAMPR_HANDLE)GroupHandle,
+ MemberId);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamRemoveMultipleMembersFromAlias(IN SAM_HANDLE AliasHandle,
+ IN PSID *MemberIds,
+ IN ULONG MemberCount)
+{
+ SAMPR_PSID_ARRAY Buffer;
+ NTSTATUS Status;
+
+ TRACE("SamRemoveMultipleMembersFromAlias(%p %p %lu)\n",
+ AliasHandle, MemberIds, MemberCount);
+
+ if (MemberIds == NULL)
+ return STATUS_INVALID_PARAMETER_2;
+
+ Buffer.Count = MemberCount;
+ Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
+
+ RpcTryExcept
+ {
+ Status = SamrRemoveMultipleMembersFromAlias((SAMPR_HANDLE)AliasHandle,
+ &Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamRidToSid(IN SAM_HANDLE ObjectHandle,
+ IN ULONG Rid,
+ OUT PSID *Sid)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetInformationAlias(IN SAM_HANDLE AliasHandle,
+ IN ALIAS_INFORMATION_CLASS AliasInformationClass,
+ IN PVOID Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamSetInformationAlias(%p %lu %p)\n",
+ AliasHandle, AliasInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationAlias((SAMPR_HANDLE)AliasHandle,
+ AliasInformationClass,
+ Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetInformationDomain(IN SAM_HANDLE DomainHandle,
+ IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
+ IN PVOID Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamSetInformationDomain(%p %lu %p)\n",
+ DomainHandle, DomainInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationDomain((SAMPR_HANDLE)DomainHandle,
+ DomainInformationClass,
+ Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetInformationGroup(IN SAM_HANDLE GroupHandle,
+ IN GROUP_INFORMATION_CLASS GroupInformationClass,
+ IN PVOID Buffer)
+{
+ NTSTATUS Status;
+
+ TRACE("SamSetInformationGroup(%p %lu %p)\n",
+ GroupHandle, GroupInformationClass, Buffer);
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationGroup((SAMPR_HANDLE)GroupHandle,
+ GroupInformationClass,
+ Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetInformationUser(IN SAM_HANDLE UserHandle,
+ IN USER_INFORMATION_CLASS UserInformationClass,
+ IN PVOID Buffer)
+{
+ PSAMPR_USER_SET_PASSWORD_INFORMATION PasswordBuffer;
+ SAMPR_USER_INTERNAL1_INFORMATION Internal1Buffer;
+ USER_ALL_INFORMATION InternalAllBuffer;
+ OEM_STRING LmPwdString;
+ CHAR LmPwdBuffer[15];
+ NTSTATUS Status;
+
+ TRACE("SamSetInformationUser(%p %lu %p)\n",
+ UserHandle, UserInformationClass, Buffer);
+
+ if (UserInformationClass == UserSetPasswordInformation)
+ {
+ PasswordBuffer = (PSAMPR_USER_SET_PASSWORD_INFORMATION)Buffer;
+
+ Status = SampCheckPassword(UserHandle,
+ (PUNICODE_STRING)&PasswordBuffer->Password);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ /* Calculate the NT hash value of the passord */
+ Status = SystemFunction007((PUNICODE_STRING)&PasswordBuffer->Password,
+ (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ Internal1Buffer.NtPasswordPresent = TRUE;
+ Internal1Buffer.LmPasswordPresent = FALSE;
+
+ /* Build the LM password */
+ LmPwdString.Length = 15;
+ LmPwdString.MaximumLength = 15;
+ LmPwdString.Buffer = LmPwdBuffer;
+ ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
+
+ Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+ (PUNICODE_STRING)&PasswordBuffer->Password,
+ FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Calculate the LM hash value of the password */
+ Status = SystemFunction006(LmPwdString.Buffer,
+ (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword);
+ if (NT_SUCCESS(Status))
+ Internal1Buffer.LmPasswordPresent = TRUE;
+ }
+
+ Internal1Buffer.PasswordExpired = PasswordBuffer->PasswordExpired;
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
+ UserInternal1Information,
+ (PVOID)&Internal1Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
+ }
+
+ return Status;
+ }
+ else if (UserInformationClass == UserAllInformation)
+ {
+ RtlCopyMemory(&InternalAllBuffer,
+ Buffer,
+ sizeof(USER_ALL_INFORMATION));
+
+ if (InternalAllBuffer.WhichFields & (USER_ALL_LMPASSWORDPRESENT | USER_ALL_NTPASSWORDPRESENT))
+ {
+ if (InternalAllBuffer.WhichFields & USER_ALL_OWFPASSWORD)
+ {
+ /* Check NT password hash */
+ if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
+ {
+ if (InternalAllBuffer.NtPassword.Length != sizeof(ENCRYPTED_NT_OWF_PASSWORD))
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Check LM password hash */
+ if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
+ {
+ if (InternalAllBuffer.LmPassword.Length != sizeof(ENCRYPTED_LM_OWF_PASSWORD))
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ /*
+ * Only allow the NT password to be set.
+ * The LM password will be created here.
+ */
+ if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT)
+ {
+ TRACE("Do not try to set a clear text LM password!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT)
+ {
+ Status = SampCheckPassword(UserHandle,
+ &InternalAllBuffer.NtPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ /* Calculate the NT password hash */
+ Status = SystemFunction007((PUNICODE_STRING)&InternalAllBuffer.NtPassword,
+ (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ InternalAllBuffer.NtPasswordPresent = TRUE;
+ InternalAllBuffer.LmPasswordPresent = FALSE;
+
+ InternalAllBuffer.NtPassword.Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ InternalAllBuffer.NtPassword.MaximumLength = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ InternalAllBuffer.NtPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedNtOwfPassword;
+
+ /* Build the LM password */
+ LmPwdString.Length = 15;
+ LmPwdString.MaximumLength = 15;
+ LmPwdString.Buffer = LmPwdBuffer;
+ ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
+
+ Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+ (PUNICODE_STRING)&InternalAllBuffer.NtPassword,
+ FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Calculate the LM password hash */
+ Status = SystemFunction006(LmPwdString.Buffer,
+ (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword);
+ if (NT_SUCCESS(Status))
+ {
+ InternalAllBuffer.WhichFields |= USER_ALL_LMPASSWORDPRESENT;
+ InternalAllBuffer.LmPasswordPresent = TRUE;
+
+ InternalAllBuffer.LmPassword.Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ InternalAllBuffer.LmPassword.MaximumLength = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ InternalAllBuffer.LmPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedLmOwfPassword;
+ }
+ }
+ }
+ }
+ }
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
+ UserAllInformation,
+ (PVOID)&InternalAllBuffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status);
+ }
+
+ return Status;
+ }
+
+ RpcTryExcept
+ {
+ Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
+ UserInformationClass,
+ Buffer);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetMemberAttributesOfGroup(IN SAM_HANDLE GroupHandle,
+ IN ULONG MemberId,
+ IN ULONG Attributes)
+{
+ NTSTATUS Status;
+
+ TRACE("SamSetMemberAttributesOfGroup(%p %lu 0x%lx)\n",
+ GroupHandle, MemberId, Attributes);
+
+ RpcTryExcept
+ {
+ Status = SamrSetMemberAttributesOfGroup((SAMPR_HANDLE)GroupHandle,
+ MemberId,
+ Attributes);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamSetSecurityObject(IN SAM_HANDLE ObjectHandle,
+ IN SECURITY_INFORMATION SecurityInformation,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+ SAMPR_SR_SECURITY_DESCRIPTOR DescriptorToPass;
+ ULONG Length;
+ NTSTATUS Status;
+
+ TRACE("SamSetSecurityObject(%p %lu %p)\n",
+ ObjectHandle, SecurityInformation, SecurityDescriptor);
+
+ /* Retrieve the length of the relative security descriptor */
+ Length = 0;
+ Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
+ NULL,
+ &Length);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ return STATUS_INVALID_PARAMETER;
+
+
+ /* Allocate a buffer for the security descriptor */
+ DescriptorToPass.Length = Length;
+ DescriptorToPass.SecurityDescriptor = MIDL_user_allocate(Length);
+ if (DescriptorToPass.SecurityDescriptor == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Convert the given security descriptor to a relative security descriptor */
+ Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
+ (PSECURITY_DESCRIPTOR)DescriptorToPass.SecurityDescriptor,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+
+ RpcTryExcept
+ {
+ Status = SamrSetSecurityObject((SAMPR_HANDLE)ObjectHandle,
+ SecurityInformation,
+ &DescriptorToPass);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+done:
+ if (DescriptorToPass.SecurityDescriptor != NULL)
+ MIDL_user_free(DescriptorToPass.SecurityDescriptor);
+
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
+{
+ NTSTATUS Status;
+
+ TRACE("(%p)\n", ServerHandle);
+
+ RpcTryExcept
+ {
+ Status = SamrShutdownSamServer((SAMPR_HANDLE)ServerHandle);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = I_RpcMapWin32Status(RpcExceptionCode());
+ }
+ RpcEndExcept;
- return TRUE;
+ return Status;
}
/* EOF */