diff --git a/reactos/dll/win32/netapi32/local_group.c b/reactos/dll/win32/netapi32/local_group.c index 8fab6a1b104..6a8ee009b65 100644 --- a/reactos/dll/win32/netapi32/local_group.c +++ b/reactos/dll/win32/netapi32/local_group.c @@ -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); diff --git a/reactos/dll/win32/netapi32/misc.c b/reactos/dll/win32/netapi32/misc.c index 8a23176ec20..8f12992a206 100644 --- a/reactos/dll/win32/netapi32/misc.c +++ b/reactos/dll/win32/netapi32/misc.c @@ -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 */ diff --git a/reactos/dll/win32/netapi32/netapi32.h b/reactos/dll/win32/netapi32/netapi32.h index 8279d1effa8..1043833cf62 100644 --- a/reactos/dll/win32/netapi32/netapi32.h +++ b/reactos/dll/win32/netapi32/netapi32.h @@ -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 \ No newline at end of file diff --git a/reactos/dll/win32/netapi32/user.c b/reactos/dll/win32/netapi32/user.c index 47a738daf0e..f81c1cd0a41 100644 --- a/reactos/dll/win32/netapi32/user.c +++ b/reactos/dll/win32/netapi32/user.c @@ -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);