mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
[NETAPI32]
Implement NetLocalGroupGetMembers. Level 0 support only. Will be tested and fixed when level 1 support will be added. svn path=/trunk/; revision=59176
This commit is contained in:
parent
45d6f4dc1b
commit
bc21f371e4
1 changed files with 218 additions and 26 deletions
|
@ -45,6 +45,17 @@ typedef struct _ENUM_CONTEXT
|
||||||
|
|
||||||
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
} ENUM_CONTEXT, *PENUM_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _MEMBER_ENUM_CONTEXT
|
||||||
|
{
|
||||||
|
SAM_HANDLE ServerHandle;
|
||||||
|
SAM_HANDLE DomainHandle;
|
||||||
|
SAM_HANDLE AliasHandle;
|
||||||
|
|
||||||
|
PSID *Sids;
|
||||||
|
ULONG Count;
|
||||||
|
ULONG Index;
|
||||||
|
} MEMBER_ENUM_CONTEXT, *PMEMBER_ENUM_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
|
@ -149,6 +160,66 @@ FreeAliasInfo(PALIAS_GENERAL_INFORMATION AliasInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
NET_API_STATUS
|
||||||
|
BuildAliasMemberBuffer(PSID MemberSid,
|
||||||
|
DWORD level,
|
||||||
|
LPVOID *Buffer)
|
||||||
|
{
|
||||||
|
LPVOID LocalBuffer = NULL;
|
||||||
|
PLOCALGROUP_MEMBERS_INFO_0 MembersInfo0;
|
||||||
|
PVOID Ptr;
|
||||||
|
ULONG Size = 0;
|
||||||
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
|
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Size = sizeof(LOCALGROUP_MEMBERS_INFO_0) +
|
||||||
|
RtlLengthSid(MemberSid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ApiStatus = ERROR_INVALID_LEVEL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ZeroMemory(LocalBuffer, Size);
|
||||||
|
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
MembersInfo0 = (PLOCALGROUP_MEMBERS_INFO_0)LocalBuffer;
|
||||||
|
|
||||||
|
Ptr = (PVOID)MembersInfo0++;
|
||||||
|
MembersInfo0->lgrmi0_sid = (PSID)Ptr;
|
||||||
|
|
||||||
|
memcpy(MembersInfo0->lgrmi0_sid,
|
||||||
|
MemberSid,
|
||||||
|
RtlLengthSid(MemberSid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ApiStatus == NERR_Success)
|
||||||
|
{
|
||||||
|
*Buffer = LocalBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (LocalBuffer != NULL)
|
||||||
|
NetApiBufferFree(LocalBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
OpenAliasByName(SAM_HANDLE DomainHandle,
|
OpenAliasByName(SAM_HANDLE DomainHandle,
|
||||||
|
@ -913,7 +984,9 @@ done:
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetLocalGroupGetMembers (NETAPI32.@)
|
* NetLocalGroupGetMembers (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
NET_API_STATUS WINAPI NetLocalGroupGetMembers(
|
NET_API_STATUS
|
||||||
|
WINAPI
|
||||||
|
NetLocalGroupGetMembers(
|
||||||
LPCWSTR servername,
|
LPCWSTR servername,
|
||||||
LPCWSTR localgroupname,
|
LPCWSTR localgroupname,
|
||||||
DWORD level,
|
DWORD level,
|
||||||
|
@ -923,45 +996,164 @@ NET_API_STATUS WINAPI NetLocalGroupGetMembers(
|
||||||
LPDWORD totalentries,
|
LPDWORD totalentries,
|
||||||
PDWORD_PTR resumehandle)
|
PDWORD_PTR resumehandle)
|
||||||
{
|
{
|
||||||
FIXME("(%s %s %d %p %d, %p %p %p) stub!\n", debugstr_w(servername),
|
UNICODE_STRING ServerName;
|
||||||
|
UNICODE_STRING AliasName;
|
||||||
|
PMEMBER_ENUM_CONTEXT EnumContext = NULL;
|
||||||
|
LPVOID Buffer = NULL;
|
||||||
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
TRACE("(%s %s %d %p %d, %p %p %p) stub!\n", debugstr_w(servername),
|
||||||
debugstr_w(localgroupname), level, bufptr, prefmaxlen, entriesread,
|
debugstr_w(localgroupname), level, bufptr, prefmaxlen, entriesread,
|
||||||
totalentries, resumehandle);
|
totalentries, resumehandle);
|
||||||
|
|
||||||
if (level == 3)
|
*entriesread = 0;
|
||||||
|
*totalentries = 0;
|
||||||
|
*bufptr = NULL;
|
||||||
|
|
||||||
|
if (servername != NULL)
|
||||||
|
RtlInitUnicodeString(&ServerName, servername);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&AliasName, localgroupname);
|
||||||
|
|
||||||
|
if (resumehandle != NULL && *resumehandle != 0)
|
||||||
{
|
{
|
||||||
WCHAR userName[MAX_COMPUTERNAME_LENGTH + 1];
|
EnumContext = (PMEMBER_ENUM_CONTEXT)*resumehandle;
|
||||||
DWORD userNameLen;
|
}
|
||||||
DWORD len,needlen;
|
else
|
||||||
PLOCALGROUP_MEMBERS_INFO_3 ptr;
|
{
|
||||||
|
/* Allocate the enumeration context */
|
||||||
|
ApiStatus = NetApiBufferAllocate(sizeof(MEMBER_ENUM_CONTEXT), (PVOID*)&EnumContext);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* still a stub, current user is belonging to all groups */
|
/* Connect to the SAM Server */
|
||||||
|
Status = SamConnect((servername != NULL) ? &ServerName : 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;
|
||||||
|
}
|
||||||
|
|
||||||
*totalentries = 1;
|
/* Open the Builtin Domain */
|
||||||
*entriesread = 0;
|
Status = OpenBuiltinDomain(EnumContext->ServerHandle,
|
||||||
|
DOMAIN_LOOKUP,
|
||||||
|
&EnumContext->DomainHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
userNameLen = MAX_COMPUTERNAME_LENGTH + 1;
|
/* Open the alias account in the builtin domain */
|
||||||
GetUserNameW(userName,&userNameLen);
|
ApiStatus = OpenAliasByName(EnumContext->DomainHandle,
|
||||||
needlen = sizeof(LOCALGROUP_MEMBERS_INFO_3) +
|
&AliasName,
|
||||||
(userNameLen+2) * sizeof(WCHAR);
|
ALIAS_LIST_MEMBERS,
|
||||||
if (prefmaxlen != MAX_PREFERRED_LENGTH)
|
&EnumContext->AliasHandle);
|
||||||
len = min(prefmaxlen,needlen);
|
if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
|
||||||
else
|
{
|
||||||
len = needlen;
|
ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
NetApiBufferAllocate(len, (LPVOID *) bufptr);
|
if (EnumContext->AliasHandle == NULL)
|
||||||
if (len < needlen)
|
{
|
||||||
return ERROR_MORE_DATA;
|
if (EnumContext->DomainHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->DomainHandle);
|
||||||
|
|
||||||
ptr = (PLOCALGROUP_MEMBERS_INFO_3)*bufptr;
|
/* Open the Acount Domain */
|
||||||
ptr->lgrmi3_domainandname = (LPWSTR)(*bufptr+sizeof(LOCALGROUP_MEMBERS_INFO_3));
|
Status = OpenAccountDomain(EnumContext->ServerHandle,
|
||||||
lstrcpyW(ptr->lgrmi3_domainandname,userName);
|
(servername != NULL) ? &ServerName : NULL,
|
||||||
|
DOMAIN_LOOKUP,
|
||||||
|
&EnumContext->DomainHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
*entriesread = 1;
|
/* Open the alias account in the account domain */
|
||||||
|
ApiStatus = OpenAliasByName(EnumContext->DomainHandle,
|
||||||
|
&AliasName,
|
||||||
|
ALIAS_LIST_MEMBERS,
|
||||||
|
&EnumContext->AliasHandle);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
{
|
||||||
|
ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus);
|
||||||
|
if (ApiStatus == ERROR_NONE_MAPPED)
|
||||||
|
ApiStatus = NERR_GroupNotFound;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the member list */
|
||||||
|
Status = SamGetMembersInAlias(EnumContext->AliasHandle,
|
||||||
|
&EnumContext->Sids,
|
||||||
|
&EnumContext->Count);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamGetMemberInAlias failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EnumContext->Count == 0)
|
||||||
|
{
|
||||||
|
TRACE("No member found. We're done.\n");
|
||||||
|
ApiStatus = NERR_Success;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NERR_Success;
|
/* Build the member information buffer */
|
||||||
|
ApiStatus = BuildAliasMemberBuffer(EnumContext->Sids[EnumContext->Index],
|
||||||
|
level,
|
||||||
|
&Buffer);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
EnumContext->Index++;
|
||||||
|
(*entriesread)++;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
|
||||||
|
ApiStatus = ERROR_MORE_DATA;
|
||||||
|
|
||||||
|
if (EnumContext != NULL)
|
||||||
|
*totalentries = EnumContext->Count - EnumContext->Index;
|
||||||
|
|
||||||
|
if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
/* Release the enumeration context */
|
||||||
|
if (EnumContext != NULL)
|
||||||
|
{
|
||||||
|
if (EnumContext->AliasHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->AliasHandle);
|
||||||
|
|
||||||
|
if (EnumContext->DomainHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->DomainHandle);
|
||||||
|
|
||||||
|
if (EnumContext->ServerHandle != NULL)
|
||||||
|
SamCloseHandle(EnumContext->ServerHandle);
|
||||||
|
|
||||||
|
if (EnumContext->Sids != NULL)
|
||||||
|
SamFreeMemory(EnumContext->Sids);
|
||||||
|
|
||||||
|
NetApiBufferFree(EnumContext);
|
||||||
|
EnumContext = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetLocalGroupSetInfo (NETAPI32.@)
|
* NetLocalGroupSetInfo (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue