diff options
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/sid.cc')
-rw-r--r-- | security/sandbox/chromium/sandbox/win/src/sid.cc | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/sid.cc b/security/sandbox/chromium/sandbox/win/src/sid.cc new file mode 100644 index 0000000000..a97ca340ed --- /dev/null +++ b/security/sandbox/chromium/sandbox/win/src/sid.cc @@ -0,0 +1,163 @@ +// Copyright (c) 2006-2008 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 "sandbox/win/src/sid.h" + +#include <memory> + +#include <sddl.h> +#include <stdlib.h> + +#include "base/logging.h" +#include "base/rand_util.h" +#include "base/win/windows_version.h" +#include "sandbox/win/src/win_utils.h" + +namespace sandbox { + +namespace { + +DWORD WellKnownCapabilityToRid(WellKnownCapabilities capability) { + switch (capability) { + case kInternetClient: + return SECURITY_CAPABILITY_INTERNET_CLIENT; + case kInternetClientServer: + return SECURITY_CAPABILITY_INTERNET_CLIENT_SERVER; + case kPrivateNetworkClientServer: + return SECURITY_CAPABILITY_PRIVATE_NETWORK_CLIENT_SERVER; + case kPicturesLibrary: + return SECURITY_CAPABILITY_PICTURES_LIBRARY; + case kVideosLibrary: + return SECURITY_CAPABILITY_VIDEOS_LIBRARY; + case kMusicLibrary: + return SECURITY_CAPABILITY_MUSIC_LIBRARY; + case kDocumentsLibrary: + return SECURITY_CAPABILITY_DOCUMENTS_LIBRARY; + case kEnterpriseAuthentication: + return SECURITY_CAPABILITY_ENTERPRISE_AUTHENTICATION; + case kSharedUserCertificates: + return SECURITY_CAPABILITY_SHARED_USER_CERTIFICATES; + case kRemovableStorage: + return SECURITY_CAPABILITY_REMOVABLE_STORAGE; + case kAppointments: + return SECURITY_CAPABILITY_APPOINTMENTS; + case kContacts: + return SECURITY_CAPABILITY_CONTACTS; + default: + break; + } + return 0; +} + +} // namespace + +Sid::Sid() : sid_() {} + +Sid::Sid(PSID sid) : sid_() { + ::CopySid(SECURITY_MAX_SID_SIZE, sid_, sid); +} + +Sid::Sid(const SID* sid) : sid_() { + ::CopySid(SECURITY_MAX_SID_SIZE, sid_, const_cast<SID*>(sid)); +} + +Sid::Sid(WELL_KNOWN_SID_TYPE type) { + DWORD size_sid = SECURITY_MAX_SID_SIZE; + bool result = ::CreateWellKnownSid(type, nullptr, sid_, &size_sid); + DCHECK(result); + (void)result; +} + +Sid Sid::FromKnownCapability(WellKnownCapabilities capability) { + DWORD capability_rid = WellKnownCapabilityToRid(capability); + if (!capability_rid) + return Sid(); + SID_IDENTIFIER_AUTHORITY capability_authority = { + SECURITY_APP_PACKAGE_AUTHORITY}; + DWORD sub_authorities[] = {SECURITY_CAPABILITY_BASE_RID, capability_rid}; + return FromSubAuthorities(&capability_authority, 2, sub_authorities); +} + +Sid Sid::FromNamedCapability(const wchar_t* capability_name) { + RtlDeriveCapabilitySidsFromNameFunction derive_capability_sids = nullptr; + ResolveNTFunctionPtr("RtlDeriveCapabilitySidsFromName", + &derive_capability_sids); + RtlInitUnicodeStringFunction init_unicode_string = nullptr; + ResolveNTFunctionPtr("RtlInitUnicodeString", &init_unicode_string); + + if (!derive_capability_sids || !init_unicode_string) + return Sid(); + + if (!capability_name || ::wcslen(capability_name) == 0) + return Sid(); + + UNICODE_STRING name = {}; + init_unicode_string(&name, capability_name); + Sid capability_sid; + Sid group_sid; + + NTSTATUS status = + derive_capability_sids(&name, group_sid.sid_, capability_sid.sid_); + if (!NT_SUCCESS(status)) + return Sid(); + + return capability_sid; +} + +Sid Sid::FromSddlString(const wchar_t* sddl_sid) { + PSID converted_sid; + if (!::ConvertStringSidToSid(sddl_sid, &converted_sid)) + return Sid(); + + return Sid(converted_sid); +} + +Sid Sid::FromSubAuthorities(PSID_IDENTIFIER_AUTHORITY identifier_authority, + BYTE sub_authority_count, + PDWORD sub_authorities) { + Sid sid; + if (!::InitializeSid(sid.sid_, identifier_authority, sub_authority_count)) + return Sid(); + + for (DWORD index = 0; index < sub_authority_count; ++index) { + PDWORD sub_authority = GetSidSubAuthority(sid.sid_, index); + *sub_authority = sub_authorities[index]; + } + return sid; +} + +Sid Sid::AllRestrictedApplicationPackages() { + SID_IDENTIFIER_AUTHORITY package_authority = {SECURITY_APP_PACKAGE_AUTHORITY}; + DWORD sub_authorities[] = {SECURITY_APP_PACKAGE_BASE_RID, + SECURITY_BUILTIN_PACKAGE_ANY_RESTRICTED_PACKAGE}; + return FromSubAuthorities(&package_authority, 2, sub_authorities); +} + +Sid Sid::GenerateRandomSid() { + SID_IDENTIFIER_AUTHORITY package_authority = {SECURITY_NULL_SID_AUTHORITY}; + DWORD sub_authorities[4] = {}; + base::RandBytes(&sub_authorities, sizeof(sub_authorities)); + return FromSubAuthorities(&package_authority, _countof(sub_authorities), + sub_authorities); +} + +PSID Sid::GetPSID() const { + return const_cast<BYTE*>(sid_); +} + +bool Sid::IsValid() const { + return !!::IsValidSid(GetPSID()); +} + +// Converts the SID to an SDDL format string. +bool Sid::ToSddlString(std::wstring* sddl_string) const { + LPWSTR sid = nullptr; + if (!::ConvertSidToStringSid(GetPSID(), &sid)) + return false; + std::unique_ptr<void, LocalFreeDeleter> sid_ptr(sid); + *sddl_string = sid; + return true; +} + +} // namespace sandbox |