1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sandbox/win/src/app_container.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/win/startup_information.h"
13 #include "sandbox/win/src/internal_types.h"
17 // Converts the passed in sid string to a PSID that must be relased with
19 PSID
ConvertSid(const string16
& sid
) {
21 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
27 T
BindFunction(const char* name
) {
28 HMODULE module
= GetModuleHandle(sandbox::kKerneldllName
);
29 void* function
= GetProcAddress(module
, name
);
31 module
= GetModuleHandle(sandbox::kKernelBasedllName
);
32 function
= GetProcAddress(module
, name
);
34 return reinterpret_cast<T
>(function
);
41 AppContainerAttributes::AppContainerAttributes() {
42 memset(&capabilities_
, 0, sizeof(capabilities_
));
45 AppContainerAttributes::~AppContainerAttributes() {
46 for (size_t i
= 0; i
< attributes_
.size(); i
++)
47 LocalFree(attributes_
[i
].Sid
);
48 LocalFree(capabilities_
.AppContainerSid
);
51 ResultCode
AppContainerAttributes::SetAppContainer(
52 const string16
& app_container_sid
,
53 const std::vector
<string16
>& capabilities
) {
54 DCHECK(!capabilities_
.AppContainerSid
);
55 DCHECK(attributes_
.empty());
56 capabilities_
.AppContainerSid
= ConvertSid(app_container_sid
);
57 if (!capabilities_
.AppContainerSid
)
58 return SBOX_ERROR_INVALID_APP_CONTAINER
;
60 for (size_t i
= 0; i
< capabilities
.size(); i
++) {
61 SID_AND_ATTRIBUTES sid_and_attributes
;
62 sid_and_attributes
.Sid
= ConvertSid(capabilities
[i
]);
63 if (!sid_and_attributes
.Sid
)
64 return SBOX_ERROR_INVALID_CAPABILITY
;
66 sid_and_attributes
.Attributes
= SE_GROUP_ENABLED
;
67 attributes_
.push_back(sid_and_attributes
);
70 if (capabilities
.size()) {
71 capabilities_
.CapabilityCount
= static_cast<DWORD
>(capabilities
.size());
72 capabilities_
.Capabilities
= &attributes_
[0];
77 ResultCode
AppContainerAttributes::ShareForStartup(
78 base::win::StartupInformation
* startup_information
) const {
79 // The only thing we support so far is an AppContainer.
80 if (!capabilities_
.AppContainerSid
)
81 return SBOX_ERROR_INVALID_APP_CONTAINER
;
83 if (!startup_information
->UpdateProcThreadAttribute(
84 PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES
,
85 const_cast<SECURITY_CAPABILITIES
*>(&capabilities_
),
86 sizeof(capabilities_
))) {
87 DPLOG(ERROR
) << "Failed UpdateProcThreadAttribute";
88 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER
;
93 bool AppContainerAttributes::HasAppContainer() const {
94 return (capabilities_
.AppContainerSid
!= NULL
);
97 ResultCode
CreateAppContainer(const string16
& sid
, const string16
& name
) {
99 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
100 return SBOX_ERROR_INVALID_APP_CONTAINER
;
102 typedef HRESULT (WINAPI
* AppContainerRegisterSidPtr
)(PSID sid
,
104 LPCWSTR display_name
);
105 static AppContainerRegisterSidPtr AppContainerRegisterSid
= NULL
;
107 if (!AppContainerRegisterSid
) {
108 AppContainerRegisterSid
=
109 BindFunction
<AppContainerRegisterSidPtr
>("AppContainerRegisterSid");
112 ResultCode operation_result
= SBOX_ERROR_GENERIC
;
113 if (AppContainerRegisterSid
) {
114 HRESULT rv
= AppContainerRegisterSid(local_sid
, name
.c_str(), name
.c_str());
116 operation_result
= SBOX_ALL_OK
;
118 DLOG(ERROR
) << "AppContainerRegisterSid error:" << std::hex
<< rv
;
120 LocalFree(local_sid
);
121 return operation_result
;
124 ResultCode
DeleteAppContainer(const string16
& sid
) {
126 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
127 return SBOX_ERROR_INVALID_APP_CONTAINER
;
129 typedef HRESULT (WINAPI
* AppContainerUnregisterSidPtr
)(PSID sid
);
130 static AppContainerUnregisterSidPtr AppContainerUnregisterSid
= NULL
;
132 if (!AppContainerUnregisterSid
) {
133 AppContainerUnregisterSid
=
134 BindFunction
<AppContainerUnregisterSidPtr
>("AppContainerUnregisterSid");
137 ResultCode operation_result
= SBOX_ERROR_GENERIC
;
138 if (AppContainerUnregisterSid
) {
139 HRESULT rv
= AppContainerUnregisterSid(local_sid
);
141 operation_result
= SBOX_ALL_OK
;
143 DLOG(ERROR
) << "AppContainerUnregisterSid error:" << std::hex
<< rv
;
145 LocalFree(local_sid
);
146 return operation_result
;
149 string16
LookupAppContainer(const string16
& sid
) {
151 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
154 typedef HRESULT (WINAPI
* AppContainerLookupMonikerPtr
)(PSID sid
,
156 typedef BOOLEAN (WINAPI
* AppContainerFreeMemoryPtr
)(void* ptr
);
158 static AppContainerLookupMonikerPtr AppContainerLookupMoniker
= NULL
;
159 static AppContainerFreeMemoryPtr AppContainerFreeMemory
= NULL
;
161 if (!AppContainerLookupMoniker
|| !AppContainerFreeMemory
) {
162 AppContainerLookupMoniker
=
163 BindFunction
<AppContainerLookupMonikerPtr
>("AppContainerLookupMoniker");
164 AppContainerFreeMemory
=
165 BindFunction
<AppContainerFreeMemoryPtr
>("AppContainerFreeMemory");
168 if (!AppContainerLookupMoniker
|| !AppContainerFreeMemory
)
171 wchar_t* buffer
= NULL
;
172 HRESULT rv
= AppContainerLookupMoniker(local_sid
, &buffer
);
176 string16
name(buffer
);
177 if (!AppContainerFreeMemory(buffer
))
182 } // namespace sandbox