[NETAPI32]

Add level 3 support to NetLocalGroupAddMembers and NetLocalGroupDelMembers.

svn path=/trunk/; revision=59195
This commit is contained in:
Eric Kohl 2013-06-09 09:40:24 +00:00
parent 740772014c
commit 7d25cfad37
4 changed files with 209 additions and 46 deletions

View file

@ -218,6 +218,115 @@ done:
}
static
NET_API_STATUS
BuildSidListFromDomainAndName(IN PUNICODE_STRING ServerName,
IN PLOCALGROUP_MEMBERS_INFO_3 buf,
IN ULONG EntryCount,
OUT PLOCALGROUP_MEMBERS_INFO_0 *MemberList)
{
OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE LsaHandle = NULL;
PUNICODE_STRING NamesArray = NULL;
ULONG i;
PLSA_REFERENCED_DOMAIN_LIST Domains = NULL;
PLSA_TRANSLATED_SID Sids = NULL;
PLOCALGROUP_MEMBERS_INFO_0 MemberBuffer = NULL;
NET_API_STATUS ApiStatus = NERR_Success;
NTSTATUS Status = STATUS_SUCCESS;
ApiStatus = NetApiBufferAllocate(sizeof(UNICODE_STRING) * EntryCount,
(LPVOID*)&NamesArray);
if (ApiStatus != NERR_Success)
{
goto done;
}
for (i = 0; i < EntryCount; i++)
{
RtlInitUnicodeString(&NamesArray[i],
buf[i].lgrmi3_domainandname);
}
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
0,
NULL);
Status = LsaOpenPolicy(ServerName,
(PLSA_OBJECT_ATTRIBUTES)&ObjectAttributes,
POLICY_EXECUTE,
&LsaHandle);
if (!NT_SUCCESS(Status))
{
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
Status = LsaLookupNames(LsaHandle,
EntryCount,
NamesArray,
&Domains,
&Sids);
if (!NT_SUCCESS(Status))
{
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
ApiStatus = NetApiBufferAllocate(sizeof(LOCALGROUP_MEMBERS_INFO_0) * EntryCount,
(LPVOID*)&MemberBuffer);
if (ApiStatus != NERR_Success)
{
goto done;
}
for (i = 0; i < EntryCount; i++)
{
ApiStatus = BuildSidFromSidAndRid(Domains->Domains[Sids[i].DomainIndex].Sid,
Sids[i].RelativeId,
&MemberBuffer[i].lgrmi0_sid);
if (ApiStatus != NERR_Success)
{
goto done;
}
}
done:
if (ApiStatus != NERR_Success)
{
if (MemberBuffer != NULL)
{
for (i = 0; i < EntryCount; i++)
{
if (MemberBuffer[i].lgrmi0_sid != NULL)
NetApiBufferFree(MemberBuffer[i].lgrmi0_sid);
}
NetApiBufferFree(MemberBuffer);
MemberBuffer = NULL;
}
}
if (Sids != NULL)
LsaFreeMemory(Sids);
if (Domains != NULL)
LsaFreeMemory(Domains);
if (LsaHandle != NULL)
LsaClose(LsaHandle);
if (NamesArray != NULL)
NetApiBufferFree(NamesArray);
*MemberList = MemberBuffer;
return ApiStatus;
}
/************************************************************
* NetLocalGroupAdd (NETAPI32.@)
*/
@ -433,6 +542,18 @@ NetLocalGroupAddMembers(
break;
case 3:
Status = BuildSidListFromDomainAndName((servername != NULL) ? &ServerName : NULL,
(PLOCALGROUP_MEMBERS_INFO_3)buf,
totalentries,
&MemberList);
if (!NT_SUCCESS(Status))
{
ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
break;
default:
ApiStatus = ERROR_INVALID_LEVEL;
goto done;
@ -517,6 +638,17 @@ NetLocalGroupAddMembers(
}
done:
if (level == 3 && MemberList != NULL)
{
for (i = 0; i < totalentries; i++)
{
if (MemberList[i].lgrmi0_sid != NULL)
NetApiBufferFree(MemberList[i].lgrmi0_sid);
}
NetApiBufferFree(MemberList);
}
if (AliasHandle != NULL)
SamCloseHandle(AliasHandle);
@ -707,6 +839,18 @@ NetLocalGroupDelMembers(
break;
case 3:
Status = BuildSidListFromDomainAndName((servername != NULL) ? &ServerName : NULL,
(PLOCALGROUP_MEMBERS_INFO_3)buf,
totalentries,
&MemberList);
if (!NT_SUCCESS(Status))
{
ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
break;
default:
ApiStatus = ERROR_INVALID_LEVEL;
goto done;
@ -791,6 +935,17 @@ NetLocalGroupDelMembers(
}
done:
if (level == 3 && MemberList != NULL)
{
for (i = 0; i < totalentries; i++)
{
if (MemberList[i].lgrmi0_sid != NULL)
NetApiBufferFree(MemberList[i].lgrmi0_sid);
}
NetApiBufferFree(MemberList);
}
if (AliasHandle != NULL)
SamCloseHandle(AliasHandle);

View file

@ -175,4 +175,47 @@ OpenBuiltinDomain(IN SAM_HANDLE ServerHandle,
return Status;
}
NET_API_STATUS
BuildSidFromSidAndRid(IN PSID SrcSid,
IN ULONG RelativeId,
OUT PSID *DestSid)
{
UCHAR RidCount;
PSID DstSid;
ULONG i;
ULONG DstSidSize;
PULONG p, q;
NET_API_STATUS ApiStatus = NERR_Success;
RidCount = *RtlSubAuthorityCountSid(SrcSid);
if (RidCount >= 8)
return ERROR_INVALID_PARAMETER;
DstSidSize = RtlLengthRequiredSid(RidCount + 1);
ApiStatus = NetApiBufferAllocate(DstSidSize,
&DstSid);
if (ApiStatus != NERR_Success)
return ApiStatus;
RtlInitializeSid(DstSid,
RtlIdentifierAuthoritySid(SrcSid),
RidCount + 1);
for (i = 0; i < (ULONG)RidCount; i++)
{
p = RtlSubAuthoritySid(SrcSid, i);
q = RtlSubAuthoritySid(DstSid, i);
*q = *p;
}
q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
*q = RelativeId;
*DestSid = DstSid;
return NERR_Success;
}
/* EOF */

View file

@ -52,4 +52,9 @@ OpenBuiltinDomain(IN SAM_HANDLE ServerHandle,
IN ULONG DesiredAccess,
OUT SAM_HANDLE *DomainHandle);
NET_API_STATUS
BuildSidFromSidAndRid(IN PSID SrcSid,
IN ULONG RelativeId,
OUT PSID *DestSid);
#endif

View file

@ -49,46 +49,6 @@ typedef struct _ENUM_CONTEXT
} ENUM_CONTEXT, *PENUM_CONTEXT;
static PSID
CreateSidFromSidAndRid(PSID SrcSid,
ULONG RelativeId)
{
UCHAR RidCount;
PSID DstSid;
ULONG i;
ULONG DstSidSize;
PULONG p, q;
RidCount = *RtlSubAuthorityCountSid(SrcSid);
if (RidCount >= 8)
return NULL;
DstSidSize = RtlLengthRequiredSid(RidCount + 1);
DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
0,
DstSidSize);
if (DstSid == NULL)
return NULL;
RtlInitializeSid(DstSid,
RtlIdentifierAuthoritySid(SrcSid),
RidCount + 1);
for (i = 0; i < (ULONG)RidCount; i++)
{
p = RtlSubAuthoritySid(SrcSid, i);
q = RtlSubAuthoritySid(DstSid, i);
*q = *p;
}
q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
*q = RelativeId;
return DstSid;
}
static
ULONG
GetAccountFlags(ULONG AccountControl)
@ -1728,12 +1688,12 @@ NetUserGetLocalGroups(LPCWSTR servername,
}
/* Build the User SID from the Account Domain SID and the users RID */
UserSid = CreateSidFromSidAndRid(AccountDomainSid,
RelativeIds[0]);
if (UserSid == NULL)
ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
RelativeIds[0],
&UserSid);
if (ApiStatus != NERR_Success)
{
ERR("CreateSidFromSidAndRid failed!\n");
ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
ERR("BuildSidFromSidAndRid failed!\n");
goto done;
}
@ -1881,7 +1841,7 @@ done:
SamFreeMemory(Use);
if (UserSid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid);
NetApiBufferFree(UserSid);
if (AccountDomainSid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);