blob: c316ff7f18526e22fdb1abe521e4345a8eda8ac1 [file] [log] [blame]
// 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 <sddl.h>
#include <stdint.h>
#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<TOKEN_GROUPS> 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