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 7c885918269ac629c6b09ef18d8206d7378d0bee..0e7093935efad0d6aa1d5edb176fd3c583509915 100644 |
--- a/cloud_print/service/win/cloud_print_service.cc |
+++ b/cloud_print/service/win/cloud_print_service.cc |
@@ -19,13 +19,14 @@ |
#include "cloud_print/service/service_state.h" |
#include "cloud_print/service/service_switches.h" |
#include "cloud_print/service/win/chrome_launcher.h" |
+#include "cloud_print/service/win/local_security_policy.h" |
#include "cloud_print/service/win/resource.h" |
namespace { |
const wchar_t kServiceStateFileName[] = L"Service State"; |
-const wchar_t kUserToRunService[] = L"NT AUTHORITY\\LocalService"; |
+const wchar_t kUserToRunService[] = L"NT AUTHORITY\\SYSTEM"; |
Albert Bodenhamer
2012/08/14 20:38:18
I'm a bit nervous running as SYSTEM by default. A
Vitaly Buka (NO REVIEWS)
2012/08/14 20:58:51
For current user we need to ask password.
Probably
Vitaly Buka (NO REVIEWS)
2012/08/14 21:51:00
Removed default user.
On 2012/08/14 20:58:51, Vit
|
// The traits class for Windows Service. |
class ServiceHandleTraits { |
@@ -71,6 +72,10 @@ void InvalidUsage() { |
std::cout << "["; |
std::cout << " -" << kInstallSwitch; |
std::cout << " -" << kUserDataDirSwitch << "=DIRECTORY"; |
+ std::cout << "["; |
+ std::cout << " -" << kRunAsUser << "=USERNAME"; |
+ std::cout << " -" << kRunAsPassword << "=PASSWORD"; |
+ std::cout << "]"; |
std::cout << " [ -" << kQuietSwitch << " ]"; |
std::cout << "]"; |
std::cout << "]"; |
@@ -90,6 +95,9 @@ void InvalidUsage() { |
{ kUninstallSwitch, "Uninstalls service." }, |
{ kStartSwitch, "Starts service. May be combined with installation." }, |
{ kStopSwitch, "Stops service." }, |
+ { kRunAsUser, "Windows user to run the service in form DOMAIN\USERNAME. " |
+ "Default is LocalSystem. Current User is recommended." }, |
+ { kRunAsPassword, "Password for windows user to run the service" }, |
}; |
for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) { |
@@ -182,7 +190,7 @@ class CloudPrintServiceModule |
return S_OK; |
} |
- HRESULT InstallService() { |
+ HRESULT InstallService(const wchar_t* user, const wchar_t* password) { |
using namespace chrome_launcher_support; |
// TODO(vitalybuka): consider "lite" version if we don't want unregister |
@@ -192,8 +200,7 @@ class CloudPrintServiceModule |
return hr; |
if (GetChromePathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION).empty()) { |
- LOG(ERROR) << "Found no Chrome installed for all users."; |
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); |
+ LOG(WARNING) << "Found no Chrome installed for all users."; |
} |
hr = UpdateRegistryAppId(true); |
@@ -206,6 +213,19 @@ class CloudPrintServiceModule |
command_line.AppendSwitch(kServiceSwitch); |
command_line.AppendSwitchPath(kUserDataDirSwitch, user_data_dir_); |
+ LocalSecurityPolicy local_security_policy; |
+ if (local_security_policy.Open()) { |
+ if (!local_security_policy.IsPrivilegeSet(user, kSeServiceLogonRight)) { |
+ LOG(WARNING) << "Setting " << kSeServiceLogonRight << " for " << user; |
+ if (!local_security_policy.SetPrivilege(user, kSeServiceLogonRight)) { |
+ LOG(ERROR) << "Failed to set" << kSeServiceLogonRight; |
+ LOG(ERROR) << "Make sure you can run the service with this user."; |
+ } |
+ } |
+ } else { |
+ LOG(ERROR) << "Failed to open security policy."; |
+ } |
+ |
ServiceHandle scm; |
hr = OpenServiceManager(&scm); |
if (FAILED(hr)) |
@@ -216,7 +236,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, |
- kUserToRunService, NULL)); |
+ user, password)); |
if (!service.IsValid()) |
return HResultFromLastError(); |
@@ -282,15 +302,20 @@ class CloudPrintServiceModule |
return S_FALSE; |
} |
- HRESULT hr = ValidateUserDataDir(); |
- if (FAILED(hr)) |
- return hr; |
+ CommandLine::StringType run_as_user = |
+ command_line.GetSwitchValueNative(kRunAsUser); |
+ CommandLine::StringType run_as_password = |
+ command_line.GetSwitchValueNative(kRunAsPassword); |
+ if (run_as_user.empty()) |
+ run_as_user = kUserToRunService; |
+ |
+ HRESULT hr = ValidateUserDataDir(run_as_user.c_str()); |
hr = ProcessServiceState(command_line.HasSwitch(kQuietSwitch)); |
if (FAILED(hr)) |
return hr; |
- hr = InstallService(); |
+ hr = InstallService(run_as_user.c_str(), run_as_password.c_str()); |
if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) |
return StartService(); |
@@ -316,16 +341,16 @@ class CloudPrintServiceModule |
return S_FALSE; |
} |
- HRESULT ValidateUserDataDir() { |
+ HRESULT ValidateUserDataDir(const wchar_t* user) { |
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, |
+ HRESULT hr = WriteFileAsUser(temp_file, user, 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 << "\' has full access to \'" << |
user_data_dir_.value() << "\'."; |
} |
file_util::Delete(temp_file, false); |
@@ -343,6 +368,7 @@ class CloudPrintServiceModule |
service_state.FromString(contents); |
if (!quiet) { |
+ std::cout << "\n"; |
std::cout << file.value() << ":\n"; |
std::cout << contents << "\n"; |
} |