Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: cloud_print/service/win/cloud_print_service.cc

Issue 10454109: Validation of write access to chrome profile. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cloud_print/service/win/cloud_print_service.cc
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc
index 08ef93d5bc461021ccb48c77115fdba90407757a..0b6efea29f8867be5322b8bb089299fd3520d1cf 100644
--- a/cloud_print/service/win/cloud_print_service.cc
+++ b/cloud_print/service/win/cloud_print_service.cc
@@ -4,6 +4,7 @@
#include "cloud_print/service/win/cloud_print_service.h"
+#include <atlsecurity.h>
#include <iomanip>
#include <iostream>
@@ -23,6 +24,8 @@ namespace {
const wchar_t kServiceStateFileName[] = L"Service State";
+const wchar_t kUserToRunService[] = L"NT AUTHORITY\\LocalService";
+
// The traits class for Windows Service.
class ServiceHandleTraits {
public:
@@ -124,6 +127,44 @@ std::string GetOption(const std::string& name, const std::string& default,
return tmp;
}
+HRESULT WriteFileAsUser(const FilePath& path, const wchar_t* user,
+ const char* data, int size) {
+ ATL::CAccessToken thread_token;
+ if (!thread_token.OpenThreadToken(TOKEN_DUPLICATE | TOKEN_IMPERSONATE)) {
+ LOG(ERROR) << "Failed to open thread token.";
+ return HResultFromLastError();
+ }
+
+ ATL::CSid local_service;
+ if (!local_service.LoadAccount(user)) {
+ LOG(ERROR) << "Failed create SID.";
+ return HResultFromLastError();
+ }
+
+ ATL::CAccessToken restricted_token;
+ ATL::CTokenGroups restrict_group;
+ restrict_group.Add(local_service, 0);
+
+ if (!thread_token.CreateRestrictedToken(&restricted_token,
+ ATL::CTokenGroups(),
gene 2012/06/01 17:39:33 put 2 past params to the same line, check alignmen
Vitaly Buka (NO REVIEWS) 2012/06/01 18:02:55 Done.
+ restrict_group)) {
+ LOG(ERROR) << "Failed to create restricted token for " << user << ".";
+ return HResultFromLastError();
+ }
+
+ if (!restricted_token.Impersonate()) {
+ LOG(ERROR) << "Failed to impersonate " << user << ".";
+ return HResultFromLastError();
+ }
+
+ ATL::CAutoRevertImpersonation auto_revert(&restricted_token);
+ if (file_util::WriteFile(path, data, size) != size) {
+ LOG(ERROR) << "Failed to write file " << path.value() << ".";
+ return HResultFromLastError();
+ }
+ return S_OK;
+}
+
} // namespace
class CloudPrintServiceModule
@@ -141,7 +182,7 @@ class CloudPrintServiceModule
return S_OK;
}
- HRESULT InstallService(const FilePath& user_data_dir) {
+ HRESULT InstallService() {
// TODO(vitalybuka): consider "lite" version if we don't want unregister
// printers here.
HRESULT hr = UninstallService();
@@ -161,7 +202,7 @@ class CloudPrintServiceModule
CHECK(PathService::Get(base::FILE_EXE, &service_path));
CommandLine command_line(service_path);
command_line.AppendSwitch(kServiceSwitch);
- command_line.AppendSwitchPath(kUserDataDirSwitch, user_data_dir);
+ command_line.AppendSwitchPath(kUserDataDirSwitch, user_data_dir_);
ServiceHandle scm;
hr = OpenServiceManager(&scm);
@@ -173,7 +214,7 @@ class CloudPrintServiceModule
scm, m_szServiceName, m_szServiceName, SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
command_line.GetCommandLineString().c_str(), NULL, NULL, NULL,
- L"NT AUTHORITY\\LocalService", NULL));
+ kUserToRunService, NULL));
if (!service.IsValid())
return HResultFromLastError();
@@ -239,12 +280,15 @@ class CloudPrintServiceModule
return S_FALSE;
}
- HRESULT hr = ProcessServiceState(user_data_dir_,
- command_line.HasSwitch(kQuietSwitch));
+ HRESULT hr = ValidateUserDataDir();
if (FAILED(hr))
return hr;
- hr = InstallService(user_data_dir_);
+ hr = ProcessServiceState(command_line.HasSwitch(kQuietSwitch));
+ if (FAILED(hr))
+ return hr;
+
+ hr = InstallService();
if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch))
return StartService();
@@ -270,8 +314,23 @@ class CloudPrintServiceModule
return S_FALSE;
}
- HRESULT ProcessServiceState(const FilePath& user_data_dir, bool quiet) {
- FilePath file = user_data_dir.Append(kServiceStateFileName);
+ HRESULT ValidateUserDataDir() {
+ FilePath temp_file;
+ const char some_data[] = "1234";
+ if (!file_util::CreateTemporaryFileInDir(user_data_dir_, &temp_file))
+ return E_FAIL;
+ HRESULT hr = WriteFileAsUser(temp_file, kUserToRunService, some_data,
+ sizeof(some_data));
+ if (FAILED(hr)) {
+ std::cout << "Check if user " << kUserToRunService;
+ std::cout << " has write access to " << user_data_dir_.value() << ".\n";
gene 2012/06/01 17:39:33 ".\n" -> " has failed.\n"
Vitaly Buka (NO REVIEWS) 2012/06/01 18:02:55 Done.
+ }
+ file_util::Delete(temp_file, false);
+ return hr;
+ }
+
+ HRESULT ProcessServiceState(bool quiet) {
+ FilePath file = user_data_dir_.Append(kServiceStateFileName);
for (;;) {
std::string contents;
@@ -315,10 +374,11 @@ class CloudPrintServiceModule
if (is_valid) {
std::string new_contents = service_state.ToString();
if (new_contents != contents) {
- if (file_util::WriteFile(file, new_contents.c_str(),
- new_contents.size()) <= 0) {
- return HResultFromLastError();
- }
+ HRESULT hr = WriteFileAsUser(file, kUserToRunService,
+ new_contents.c_str(),
+ new_contents.size());
+ if (FAILED(hr))
+ return hr;
}
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698