// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "remoting/host/win/security_descriptor.h" #include #include #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" namespace remoting { ScopedSd ConvertSddlToSd(const std::string& sddl) { PSECURITY_DESCRIPTOR raw_sd = nullptr; ULONG length = 0; if (!ConvertStringSecurityDescriptorToSecurityDescriptor( base::UTF8ToUTF16(sddl).c_str(), SDDL_REVISION_1, &raw_sd, &length)) { return ScopedSd(); } ScopedSd sd(length); memcpy(sd.get(), raw_sd, length); LocalFree(raw_sd); return sd; } // Converts a SID into a text string. std::string ConvertSidToString(SID* sid) { base::char16* c_sid_string = nullptr; if (!ConvertSidToStringSid(sid, &c_sid_string)) return std::string(); base::string16 sid_string(c_sid_string); LocalFree(c_sid_string); return base::UTF16ToUTF8(sid_string); } // Returns the logon SID of a token. Returns nullptr if the token does not // specify a logon SID or in case of an error. ScopedSid GetLogonSid(HANDLE token) { DWORD length = 0; if (GetTokenInformation(token, TokenGroups, nullptr, 0, &length) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return ScopedSid(); } TypedBuffer groups(length); if (!GetTokenInformation(token, TokenGroups, groups.get(), length, &length)) return ScopedSid(); for (uint32_t i = 0; i < groups->GroupCount; ++i) { if ((groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { length = GetLengthSid(groups->Groups[i].Sid); ScopedSid logon_sid(length); if (!CopySid(length, logon_sid.get(), groups->Groups[i].Sid)) return ScopedSid(); return logon_sid; } } return ScopedSid(); } bool MakeScopedAbsoluteSd(const ScopedSd& relative_sd, ScopedSd* absolute_sd, ScopedAcl* dacl, ScopedSid* group, ScopedSid* owner, ScopedAcl* sacl) { // Get buffer sizes. DWORD absolute_sd_size = 0; DWORD dacl_size = 0; DWORD group_size = 0; DWORD owner_size = 0; DWORD sacl_size = 0; if (MakeAbsoluteSD(relative_sd.get(), nullptr, &absolute_sd_size, nullptr, &dacl_size, nullptr, &sacl_size, nullptr, &owner_size, nullptr, &group_size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return false; } // Allocate buffers. ScopedSd local_absolute_sd(absolute_sd_size); ScopedAcl local_dacl(dacl_size); ScopedSid local_group(group_size); ScopedSid local_owner(owner_size); ScopedAcl local_sacl(sacl_size); // Do the conversion. if (!MakeAbsoluteSD(relative_sd.get(), local_absolute_sd.get(), &absolute_sd_size, local_dacl.get(), &dacl_size, local_sacl.get(), &sacl_size, local_owner.get(), &owner_size, local_group.get(), &group_size)) { return false; } absolute_sd->Swap(local_absolute_sd); dacl->Swap(local_dacl); group->Swap(local_group); owner->Swap(local_owner); sacl->Swap(local_sacl); return true; } } // namespace remoting