mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:16:07 +00:00
[NETAPI32]
- Implement NetUserEnum partially. - Move common code into a separate file. svn path=/trunk/; revision=57980
This commit is contained in:
parent
730e837148
commit
da05d9ace1
5 changed files with 614 additions and 101 deletions
|
@ -11,6 +11,7 @@ list(APPEND SOURCE
|
||||||
ds.c
|
ds.c
|
||||||
group.c
|
group.c
|
||||||
local_group.c
|
local_group.c
|
||||||
|
misc.c
|
||||||
nbcmdqueue.c
|
nbcmdqueue.c
|
||||||
nbnamecache.c
|
nbnamecache.c
|
||||||
nbt.c
|
nbt.c
|
||||||
|
|
|
@ -56,99 +56,6 @@ typedef struct _ENUM_CONTEXT
|
||||||
|
|
||||||
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
||||||
|
|
||||||
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
NTSTATUS
|
|
||||||
GetAccountDomainSid(PSID *AccountDomainSid)
|
|
||||||
{
|
|
||||||
PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
|
|
||||||
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
LSA_HANDLE PolicyHandle = NULL;
|
|
||||||
ULONG Length = 0;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
||||||
|
|
||||||
Status = LsaOpenPolicy(NULL,
|
|
||||||
&ObjectAttributes,
|
|
||||||
POLICY_VIEW_LOCAL_INFORMATION,
|
|
||||||
&PolicyHandle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
||||||
PolicyAccountDomainInformation,
|
|
||||||
(PVOID *)&AccountDomainInfo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
Length = RtlLengthSid(AccountDomainInfo->DomainSid);
|
|
||||||
|
|
||||||
*AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
|
|
||||||
if (*AccountDomainSid == NULL)
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate SID\n");
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (AccountDomainInfo != NULL)
|
|
||||||
LsaFreeMemory(AccountDomainInfo);
|
|
||||||
|
|
||||||
LsaClose(PolicyHandle);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
NTSTATUS
|
|
||||||
GetBuiltinDomainSid(PSID *BuiltinDomainSid)
|
|
||||||
{
|
|
||||||
PSID Sid = NULL;
|
|
||||||
PULONG Ptr;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
*BuiltinDomainSid = NULL;
|
|
||||||
|
|
||||||
Sid = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
0,
|
|
||||||
RtlLengthRequiredSid(1));
|
|
||||||
if (Sid == NULL)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
Status = RtlInitializeSid(Sid,
|
|
||||||
&NtAuthority,
|
|
||||||
1);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
Ptr = RtlSubAuthoritySid(Sid, 0);
|
|
||||||
*Ptr = SECURITY_BUILTIN_DOMAIN_RID;
|
|
||||||
|
|
||||||
*BuiltinDomainSid = Sid;
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
if (Sid != NULL)
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetLocalGroupAdd (NETAPI32.@)
|
* NetLocalGroupAdd (NETAPI32.@)
|
||||||
|
|
127
reactos/dll/win32/netapi32/misc.c
Normal file
127
reactos/dll/win32/netapi32/misc.c
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: NetAPI DLL
|
||||||
|
* FILE: reactos/dll/win32/netapi32/misc.c
|
||||||
|
* PURPOSE: Helper functions
|
||||||
|
*
|
||||||
|
* PROGRAMMERS: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winerror.h"
|
||||||
|
#include "lmcons.h"
|
||||||
|
#include "ntsecapi.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
#define NTOS_MODE_USER
|
||||||
|
#include <ndk/rtlfuncs.h>
|
||||||
|
#include "ntsam.h"
|
||||||
|
#include "netapi32.h"
|
||||||
|
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||||
|
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetAccountDomainSid(PSID *AccountDomainSid)
|
||||||
|
{
|
||||||
|
PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
|
||||||
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
LSA_HANDLE PolicyHandle = NULL;
|
||||||
|
ULONG Length = 0;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
||||||
|
|
||||||
|
Status = LsaOpenPolicy(NULL,
|
||||||
|
&ObjectAttributes,
|
||||||
|
POLICY_VIEW_LOCAL_INFORMATION,
|
||||||
|
&PolicyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
||||||
|
PolicyAccountDomainInformation,
|
||||||
|
(PVOID *)&AccountDomainInfo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Length = RtlLengthSid(AccountDomainInfo->DomainSid);
|
||||||
|
|
||||||
|
*AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
|
||||||
|
if (*AccountDomainSid == NULL)
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate SID\n");
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (AccountDomainInfo != NULL)
|
||||||
|
LsaFreeMemory(AccountDomainInfo);
|
||||||
|
|
||||||
|
LsaClose(PolicyHandle);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetBuiltinDomainSid(PSID *BuiltinDomainSid)
|
||||||
|
{
|
||||||
|
PSID Sid = NULL;
|
||||||
|
PULONG Ptr;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
*BuiltinDomainSid = NULL;
|
||||||
|
|
||||||
|
Sid = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
RtlLengthRequiredSid(1));
|
||||||
|
if (Sid == NULL)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
Status = RtlInitializeSid(Sid,
|
||||||
|
&NtAuthority,
|
||||||
|
1);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
Ptr = RtlSubAuthoritySid(Sid, 0);
|
||||||
|
*Ptr = SECURITY_BUILTIN_DOMAIN_RID;
|
||||||
|
|
||||||
|
*BuiltinDomainSid = Sid;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Sid != NULL)
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -6,5 +6,12 @@ NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
NetpNtStatusToApiStatus(NTSTATUS Status);
|
NetpNtStatusToApiStatus(NTSTATUS Status);
|
||||||
|
|
||||||
|
/* misc.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetAccountDomainSid(PSID *AccountDomainSid);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetBuiltinDomainSid(PSID *BuiltinDomainSid);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -35,8 +35,29 @@
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
|
#define NTOS_MODE_USER
|
||||||
|
#include <ndk/rtlfuncs.h>
|
||||||
|
#include "ntsam.h"
|
||||||
|
#include "netapi32.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _ENUM_CONTEXT
|
||||||
|
{
|
||||||
|
SAM_HANDLE ServerHandle;
|
||||||
|
SAM_HANDLE BuiltinDomainHandle;
|
||||||
|
SAM_HANDLE AccountDomainHandle;
|
||||||
|
|
||||||
|
SAM_ENUMERATE_HANDLE EnumerationContext;
|
||||||
|
PSAM_RID_ENUMERATION Buffer;
|
||||||
|
ULONG Returned;
|
||||||
|
ULONG Index;
|
||||||
|
BOOLEAN BuiltinDone;
|
||||||
|
|
||||||
|
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
/* NOTE: So far, this is implemented to support tests that require user logins,
|
/* NOTE: So far, this is implemented to support tests that require user logins,
|
||||||
* but not designed to handle real user databases. Those should probably
|
* but not designed to handle real user databases. Those should probably
|
||||||
* be synced with either the host's user database or with Samba.
|
* be synced with either the host's user database or with Samba.
|
||||||
|
@ -134,7 +155,7 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetUserAdd (NETAPI32.@)
|
* NetUserAdd (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -257,7 +278,7 @@ NetUserChangePassword(LPCWSTR domainname,
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetUserDel (NETAPI32.@)
|
* NetUserDel (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -287,7 +308,7 @@ NetUserDel(LPCWSTR servername,
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetUserEnum (NETAPI32.@)
|
* NetUserEnum (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -300,15 +321,466 @@ NetUserEnum(LPCWSTR servername,
|
||||||
LPDWORD totalentries,
|
LPDWORD totalentries,
|
||||||
LPDWORD resume_handle)
|
LPDWORD resume_handle)
|
||||||
{
|
{
|
||||||
FIXME("(%s,%d, 0x%d,%p,%d,%p,%p,%p) stub!\n", debugstr_w(servername), level,
|
PSAM_RID_ENUMERATION CurrentUser;
|
||||||
filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
|
PENUM_CONTEXT EnumContext = NULL;
|
||||||
|
LPVOID Buffer = NULL;
|
||||||
|
PSID DomainSid = NULL;
|
||||||
|
PUSER_INFO_0 UserInfo0;
|
||||||
|
PUSER_INFO_1 UserInfo1;
|
||||||
|
PUSER_INFO_20 UserInfo20;
|
||||||
|
|
||||||
return ERROR_ACCESS_DENIED;
|
LPWSTR Ptr;
|
||||||
|
ULONG i;
|
||||||
|
ULONG Size;
|
||||||
|
|
||||||
|
SAM_HANDLE UserHandle = NULL;
|
||||||
|
PUSER_ACCOUNT_INFORMATION UserInfo = NULL;
|
||||||
|
|
||||||
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
FIXME("(%s %d 0x%d %p %d %p %p %p) stub!\n", debugstr_w(servername), level,
|
||||||
|
filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
|
||||||
|
|
||||||
|
*entriesread = 0;
|
||||||
|
*totalentries = 0;
|
||||||
|
*bufptr = NULL;
|
||||||
|
|
||||||
|
if (resume_handle != NULL && *resume_handle != 0)
|
||||||
|
{
|
||||||
|
EnumContext = (PENUM_CONTEXT)*resume_handle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
EnumContext->EnumerationContext = 0;
|
||||||
|
EnumContext->Buffer = NULL;
|
||||||
|
EnumContext->Returned = 0;
|
||||||
|
EnumContext->Index = 0;
|
||||||
|
EnumContext->BuiltinDone = FALSE;
|
||||||
|
|
||||||
|
Status = SamConnect(NULL,
|
||||||
|
&EnumContext->ServerHandle,
|
||||||
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamConnect failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetAccountDomainSid(&DomainSid);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SamOpenDomain(EnumContext->ServerHandle,
|
||||||
|
DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
|
||||||
|
DomainSid,
|
||||||
|
&EnumContext->AccountDomainHandle);
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamOpenDomain failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetBuiltinDomainSid(&DomainSid);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SamOpenDomain(EnumContext->ServerHandle,
|
||||||
|
DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
|
||||||
|
DomainSid,
|
||||||
|
&EnumContext->BuiltinDomainHandle);
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamOpenDomain failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// while (TRUE)
|
||||||
|
// {
|
||||||
|
TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
|
||||||
|
TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
|
||||||
|
|
||||||
|
if (EnumContext->Index >= EnumContext->Returned)
|
||||||
|
{
|
||||||
|
// if (EnumContext->BuiltinDone == TRUE)
|
||||||
|
// {
|
||||||
|
// ApiStatus = NERR_Success;
|
||||||
|
// goto done;
|
||||||
|
// }
|
||||||
|
|
||||||
|
TRACE("Calling SamEnumerateUsersInDomain\n");
|
||||||
|
Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
|
||||||
|
&EnumContext->EnumerationContext,
|
||||||
|
0,
|
||||||
|
(PVOID *)&EnumContext->Buffer,
|
||||||
|
prefmaxlen,
|
||||||
|
&EnumContext->Returned);
|
||||||
|
|
||||||
|
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_MORE_ENTRIES)
|
||||||
|
{
|
||||||
|
ApiStatus = NERR_BufTooSmall;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnumContext->BuiltinDone = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("EnumContext: %lu\n", EnumContext);
|
||||||
|
TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
|
||||||
|
TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
|
||||||
|
|
||||||
|
/* Get a pointer to the current user */
|
||||||
|
CurrentUser = &EnumContext->Buffer[EnumContext->Index];
|
||||||
|
|
||||||
|
TRACE("RID: %lu\n", CurrentUser->RelativeId);
|
||||||
|
|
||||||
|
Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
|
||||||
|
USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
|
||||||
|
CurrentUser->RelativeId,
|
||||||
|
&UserHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamOpenUser failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SamQueryInformationUser(UserHandle,
|
||||||
|
UserAccountInformation,
|
||||||
|
(PVOID *)&UserInfo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
SamCloseHandle(UserHandle);
|
||||||
|
UserHandle = NULL;
|
||||||
|
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Size = sizeof(USER_INFO_0) +
|
||||||
|
UserInfo->UserName.Length + sizeof(WCHAR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
Size = sizeof(USER_INFO_1) +
|
||||||
|
UserInfo->UserName.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectory.Length > 0)
|
||||||
|
Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Length > 0)
|
||||||
|
Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (UserInfo->ScriptPath.Length > 0)
|
||||||
|
Size = UserInfo->ScriptPath.Length + sizeof(WCHAR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case 2:
|
||||||
|
// case 3:
|
||||||
|
// case 10:
|
||||||
|
// case 11:
|
||||||
|
|
||||||
|
case 20:
|
||||||
|
Size = sizeof(USER_INFO_20) +
|
||||||
|
UserInfo->UserName.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (UserInfo->FullName.Length > 0)
|
||||||
|
Size += UserInfo->FullName.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Length > 0)
|
||||||
|
Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case 23:
|
||||||
|
|
||||||
|
default:
|
||||||
|
ApiStatus = ERROR_INVALID_LEVEL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiStatus = NetApiBufferAllocate(Size, &Buffer);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
UserInfo0 = (PUSER_INFO_0)Buffer;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
|
||||||
|
UserInfo0->usri0_name = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo0->usri0_name,
|
||||||
|
UserInfo->UserName.Buffer,
|
||||||
|
UserInfo->UserName.Length);
|
||||||
|
UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
UserInfo1 = (PUSER_INFO_1)Buffer;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));
|
||||||
|
|
||||||
|
UserInfo1->usri1_name = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo1->usri1_name,
|
||||||
|
UserInfo->UserName.Buffer,
|
||||||
|
UserInfo->UserName.Length);
|
||||||
|
UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
|
||||||
|
|
||||||
|
UserInfo1->usri1_password = NULL;
|
||||||
|
|
||||||
|
UserInfo1->usri1_password_age = 0; /* FIXME */
|
||||||
|
|
||||||
|
UserInfo1->usri1_priv = 0; /* FIXME */
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectory.Length > 0)
|
||||||
|
{
|
||||||
|
UserInfo1->usri1_home_dir = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo1->usri1_home_dir,
|
||||||
|
UserInfo->HomeDirectory.Buffer,
|
||||||
|
UserInfo->HomeDirectory.Length);
|
||||||
|
UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Length > 0)
|
||||||
|
{
|
||||||
|
UserInfo1->usri1_comment = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo1->usri1_comment,
|
||||||
|
UserInfo->AdminComment.Buffer,
|
||||||
|
UserInfo->AdminComment.Length);
|
||||||
|
UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo1->usri1_flags = UserInfo->UserAccountControl;
|
||||||
|
|
||||||
|
if (UserInfo->ScriptPath.Length > 0)
|
||||||
|
{
|
||||||
|
UserInfo1->usri1_script_path = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo1->usri1_script_path,
|
||||||
|
UserInfo->ScriptPath.Buffer,
|
||||||
|
UserInfo->ScriptPath.Length);
|
||||||
|
UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case 2:
|
||||||
|
// case 3:
|
||||||
|
// case 10:
|
||||||
|
// case 11:
|
||||||
|
|
||||||
|
case 20:
|
||||||
|
UserInfo20 = (PUSER_INFO_20)Buffer;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20));
|
||||||
|
|
||||||
|
UserInfo20->usri20_name = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo20->usri20_name,
|
||||||
|
UserInfo->UserName.Buffer,
|
||||||
|
UserInfo->UserName.Length);
|
||||||
|
UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (UserInfo->FullName.Length > 0)
|
||||||
|
{
|
||||||
|
UserInfo20->usri20_full_name = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo20->usri20_full_name,
|
||||||
|
UserInfo->FullName.Buffer,
|
||||||
|
UserInfo->FullName.Length);
|
||||||
|
UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Length > 0)
|
||||||
|
{
|
||||||
|
UserInfo20->usri20_comment = Ptr;
|
||||||
|
|
||||||
|
memcpy(UserInfo20->usri20_comment,
|
||||||
|
UserInfo->AdminComment.Buffer,
|
||||||
|
UserInfo->AdminComment.Length);
|
||||||
|
UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo20->usri20_flags = UserInfo->UserAccountControl;
|
||||||
|
UserInfo20->usri20_user_id = CurrentUser->RelativeId;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case 23:
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserInfo != NULL)
|
||||||
|
{
|
||||||
|
if (UserInfo->UserName.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->UserName.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->FullName.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->FullName.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectory.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->HomeDirectory.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->ScriptPath.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->ScriptPath.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->ProfilePath.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->ProfilePath.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->AdminComment.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->WorkStations.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->WorkStations.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->LogonHours.LogonHours != NULL)
|
||||||
|
SamFreeMemory(UserInfo->LogonHours.LogonHours);
|
||||||
|
|
||||||
|
SamFreeMemory(UserInfo);
|
||||||
|
UserInfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumContext->Index++;
|
||||||
|
|
||||||
|
(*entriesread)++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Returned)
|
||||||
|
ApiStatus = ERROR_MORE_DATA;
|
||||||
|
|
||||||
|
if (EnumContext != NULL)
|
||||||
|
*totalentries = EnumContext->Returned;
|
||||||
|
|
||||||
|
if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
if (EnumContext != NULL)
|
||||||
|
{
|
||||||
|
if (EnumContext->BuiltinDomainHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->BuiltinDomainHandle);
|
||||||
|
|
||||||
|
if (EnumContext->AccountDomainHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->AccountDomainHandle);
|
||||||
|
|
||||||
|
if (EnumContext->ServerHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->ServerHandle);
|
||||||
|
|
||||||
|
if (EnumContext->Buffer != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < EnumContext->Returned; i++)
|
||||||
|
{
|
||||||
|
SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SamFreeMemory(EnumContext->Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetApiBufferFree(EnumContext);
|
||||||
|
EnumContext = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserHandle != NULL)
|
||||||
|
SamCloseHandle(UserHandle);
|
||||||
|
|
||||||
|
if (UserInfo != NULL)
|
||||||
|
{
|
||||||
|
if (UserInfo->UserName.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->UserName.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->FullName.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->FullName.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectory.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->HomeDirectory.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->ScriptPath.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->ScriptPath.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->ProfilePath.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->ProfilePath.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->AdminComment.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->AdminComment.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->WorkStations.Buffer != NULL)
|
||||||
|
SamFreeMemory(UserInfo->WorkStations.Buffer);
|
||||||
|
|
||||||
|
if (UserInfo->LogonHours.LogonHours != NULL)
|
||||||
|
SamFreeMemory(UserInfo->LogonHours.LogonHours);
|
||||||
|
|
||||||
|
SamFreeMemory(UserInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resume_handle != NULL)
|
||||||
|
*resume_handle = (DWORD_PTR)EnumContext;
|
||||||
|
|
||||||
|
*bufptr = (LPBYTE)Buffer;
|
||||||
|
|
||||||
|
TRACE("return %lu\n", ApiStatus);
|
||||||
|
|
||||||
|
return ApiStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetUserGetGroups (NETAPI32.@)
|
* NetUserGetGroups (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -592,7 +1064,6 @@ NetUserSetGroups(LPCWSTR servername,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* NetUserSetInfo (NETAPI32.@)
|
* NetUserSetInfo (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue