summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 22:22:43 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 22:22:43 +0000
commitaf071bdd612b54c8d76f85a0a50d4e0b0f96d227 (patch)
tree25dcf1298fac2a47356ef188c8236385db5b1999 /cloud_print
parentad5fb16613da3b87e9b271212616c6538494ba82 (diff)
downloadchromium_src-af071bdd612b54c8d76f85a0a50d4e0b0f96d227.zip
chromium_src-af071bdd612b54c8d76f85a0a50d4e0b0f96d227.tar.gz
chromium_src-af071bdd612b54c8d76f85a0a50d4e0b0f96d227.tar.bz2
Validation of write access to chrome profile.
BUG=125026 TEST=none Review URL: https://chromiumcodereview.appspot.com/10454109 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140110 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print')
-rw-r--r--cloud_print/service/win/cloud_print_service.cc84
1 files changed, 72 insertions, 12 deletions
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc
index 08ef93d..c0948c4 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,43 @@ 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 token;
+ ATL::CTokenGroups group;
+ group.Add(local_service, 0);
+
+ const ATL::CTokenGroups empty_group;
+ if (!thread_token.CreateRestrictedToken(&token, empty_group, group)) {
+ LOG(ERROR) << "Failed to create restricted token for " << user << ".";
+ return HResultFromLastError();
+ }
+
+ if (!token.Impersonate()) {
+ LOG(ERROR) << "Failed to impersonate " << user << ".";
+ return HResultFromLastError();
+ }
+
+ ATL::CAutoRevertImpersonation auto_revert(&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 +181,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 +201,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 +213,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 +279,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 +313,24 @@ 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)) {
+ LOG(ERROR) << "Failed to write user data. Make sure that account \'" <<
+ kUserToRunService << "\'has full access to \'" <<
+ user_data_dir_.value() << "\'.";
+ }
+ 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;
}
}
}