Author: ekohl Date: Sun Jun 30 13:02:45 2013 New Revision: 59388 URL: http://svn.reactos.org/svn/reactos?rev=59388&view=rev Log: [NETAPI32] Implement NetUserChangePassword.
Modified: trunk/reactos/dll/win32/netapi32/CMakeLists.txt trunk/reactos/dll/win32/netapi32/netapi32.h trunk/reactos/dll/win32/netapi32/user.c Modified: trunk/reactos/dll/win32/netapi32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netapi32/CMakeLists.txt?rev=59388&r1=59387&r2=59388&view=diff ============================================================================== --- trunk/reactos/dll/win32/netapi32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netapi32/CMakeLists.txt [iso-8859-1] Sun Jun 30 13:02:45 2013 @@ -31,7 +31,7 @@ add_importlibs(netapi32 iphlpapi ws2_32 advapi32 msvcrt kernel32 ntdll) -add_delay_importlibs(netapi32 samlib) +add_delay_importlibs(netapi32 samlib secur32) add_cd_file(TARGET netapi32 DESTINATION reactos/system32 FOR all) Modified: trunk/reactos/dll/win32/netapi32/netapi32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netapi32/netapi32.h?rev=59388&r1=59387&r2=59388&view=diff ============================================================================== --- trunk/reactos/dll/win32/netapi32/netapi32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netapi32/netapi32.h [iso-8859-1] Sun Jun 30 13:02:45 2013 @@ -25,6 +25,7 @@ #define NTOS_MODE_USER #include <ndk/kefuncs.h> +#include <ndk/obfuncs.h> #include <ndk/rtlfuncs.h> #include <ntsam.h> Modified: trunk/reactos/dll/win32/netapi32/user.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netapi32/user.c?rev=59388&r1=59387&r2=59388&view=diff ============================================================================== --- trunk/reactos/dll/win32/netapi32/user.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netapi32/user.c [iso-8859-1] Sun Jun 30 13:02:45 2013 @@ -20,7 +20,6 @@ /* * TODO: - * Implement NetUserChangePassword * Implement NetUserGetGroups * Implement NetUserSetGroups * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet. @@ -2100,8 +2099,137 @@ LPCWSTR oldpassword, LPCWSTR newpassword) { + PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL; + PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL; + ULONG RequestBufferSize; + ULONG ResponseBufferSize = 0; + LPWSTR Ptr; + ANSI_STRING PackageName; + ULONG AuthenticationPackage = 0; + HANDLE LsaHandle = NULL; + NET_API_STATUS ApiStatus = NERR_Success; + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ProtocolStatus; + TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username)); - return NERR_Success; + + /* FIXME: handle null domain or user name */ + + /* Check the parameters */ + if ((oldpassword == NULL) || + (newpassword == NULL)) + return ERROR_INVALID_PARAMETER; + + /* Connect to the LSA server */ + Status = LsaConnectUntrusted(&LsaHandle); + if (!NT_SUCCESS(Status)) + return NetpNtStatusToApiStatus(Status); + + /* Get the authentication package ID */ + RtlInitAnsiString(&PackageName, + MSV1_0_PACKAGE_NAME); + + Status = LsaLookupAuthenticationPackage(LsaHandle, + &PackageName, + &AuthenticationPackage); + if (!NT_SUCCESS(Status)) + { + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Calculate the request buffer size */ + RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + + ((wcslen(domainname) + 1) * sizeof(WCHAR)) + + ((wcslen(username) + 1) * sizeof(WCHAR)) + + ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) + + ((wcslen(newpassword) + 1) * sizeof(WCHAR)); + + /* Allocate the request buffer */ + ApiStatus = NetApiBufferAllocate(RequestBufferSize, + (PVOID*)&RequestBuffer); + if (ApiStatus != NERR_Success) + goto done; + + /* Initialize the request buffer */ + RequestBuffer->MessageType = MsV1_0ChangePassword; + RequestBuffer->Impersonating = TRUE; + + Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)); + + /* Pack the domain name */ + RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR); + RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); + RequestBuffer->DomainName.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->DomainName.Buffer, + domainname, + RequestBuffer->DomainName.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength); + + /* Pack the user name */ + RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR); + RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR); + RequestBuffer->AccountName.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->AccountName.Buffer, + username, + RequestBuffer->AccountName.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength); + + /* Pack the old password */ + RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR); + RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR); + RequestBuffer->OldPassword.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->OldPassword.Buffer, + oldpassword, + RequestBuffer->OldPassword.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength); + + /* Pack the new password */ + RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR); + RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR); + RequestBuffer->NewPassword.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->NewPassword.Buffer, + newpassword, + RequestBuffer->NewPassword.MaximumLength); + + /* Call the authentication package */ + Status = LsaCallAuthenticationPackage(LsaHandle, + AuthenticationPackage, + RequestBuffer, + RequestBufferSize, + (PVOID*)&ResponseBuffer, + &ResponseBufferSize, + &ProtocolStatus); + if (!NT_SUCCESS(Status)) + { + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + if (!NT_SUCCESS(ProtocolStatus)) + { + ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus); + goto done; + } + +done: + if (RequestBuffer != NULL) + NetApiBufferFree(RequestBuffer); + + if (ResponseBuffer != NULL) + LsaFreeReturnBuffer(ResponseBuffer); + + if (LsaHandle != NULL) + NtClose(LsaHandle); + + return ApiStatus; }