summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/win/src/sid.cc
blob: a97ca340ed37f4356a2aeacb5c6bf8b6cc9593ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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