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. 4 5 #include "chromeos/dbus/session_manager_client.h" 6 7 #include <map> 8 9 #include "base/bind.h" 10 #include "base/callback.h" 11 #include "base/file_util.h" 12 #include "base/files/file_path.h" 13 #include "base/location.h" 14 #include "base/path_service.h" 15 #include "base/strings/string_util.h" 16 #include "base/threading/worker_pool.h" 17 #include "chromeos/chromeos_paths.h" 18 #include "chromeos/dbus/blocking_method_caller.h" 19 #include "chromeos/dbus/cryptohome_client.h" 20 #include "dbus/bus.h" 21 #include "dbus/message.h" 22 #include "dbus/object_path.h" 23 #include "dbus/object_proxy.h" 24 #include "third_party/cros_system_api/dbus/service_constants.h" 25 26 namespace chromeos { 27 28 // The SessionManagerClient implementation used in production. 29 class SessionManagerClientImpl : public SessionManagerClient { 30 public: 31 SessionManagerClientImpl() 32 : session_manager_proxy_(NULL), 33 weak_ptr_factory_(this) {} 34 35 virtual ~SessionManagerClientImpl() { 36 } 37 38 // SessionManagerClient overrides: 39 virtual void AddObserver(Observer* observer) OVERRIDE { 40 observers_.AddObserver(observer); 41 } 42 43 virtual void RemoveObserver(Observer* observer) OVERRIDE { 44 observers_.RemoveObserver(observer); 45 } 46 47 virtual bool HasObserver(Observer* observer) OVERRIDE { 48 return observers_.HasObserver(observer); 49 } 50 51 virtual void EmitLoginPromptReady() OVERRIDE { 52 SimpleMethodCallToSessionManager( 53 login_manager::kSessionManagerEmitLoginPromptReady); 54 } 55 56 virtual void EmitLoginPromptVisible() OVERRIDE { 57 SimpleMethodCallToSessionManager( 58 login_manager::kSessionManagerEmitLoginPromptVisible); 59 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled()); 60 } 61 62 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE { 63 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 64 login_manager::kSessionManagerRestartJob); 65 dbus::MessageWriter writer(&method_call); 66 writer.AppendInt32(pid); 67 writer.AppendString(command_line); 68 session_manager_proxy_->CallMethod( 69 &method_call, 70 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 71 base::Bind(&SessionManagerClientImpl::OnRestartJob, 72 weak_ptr_factory_.GetWeakPtr())); 73 } 74 75 virtual void StartSession(const std::string& user_email) OVERRIDE { 76 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 77 login_manager::kSessionManagerStartSession); 78 dbus::MessageWriter writer(&method_call); 79 writer.AppendString(user_email); 80 writer.AppendString(""); // Unique ID is deprecated 81 session_manager_proxy_->CallMethod( 82 &method_call, 83 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 84 base::Bind(&SessionManagerClientImpl::OnStartSession, 85 weak_ptr_factory_.GetWeakPtr())); 86 } 87 88 virtual void StopSession() OVERRIDE { 89 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 90 login_manager::kSessionManagerStopSession); 91 dbus::MessageWriter writer(&method_call); 92 writer.AppendString(""); // Unique ID is deprecated 93 session_manager_proxy_->CallMethod( 94 &method_call, 95 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 96 base::Bind(&SessionManagerClientImpl::OnStopSession, 97 weak_ptr_factory_.GetWeakPtr())); 98 } 99 100 virtual void StartDeviceWipe() OVERRIDE { 101 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 102 login_manager::kSessionManagerStartDeviceWipe); 103 session_manager_proxy_->CallMethod( 104 &method_call, 105 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 106 base::Bind(&SessionManagerClientImpl::OnDeviceWipe, 107 weak_ptr_factory_.GetWeakPtr())); 108 } 109 110 virtual void RequestLockScreen() OVERRIDE { 111 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen); 112 } 113 114 virtual void NotifyLockScreenShown() OVERRIDE { 115 SimpleMethodCallToSessionManager( 116 login_manager::kSessionManagerHandleLockScreenShown); 117 } 118 119 virtual void NotifyLockScreenDismissed() OVERRIDE { 120 SimpleMethodCallToSessionManager( 121 login_manager::kSessionManagerHandleLockScreenDismissed); 122 } 123 124 virtual void RetrieveActiveSessions( 125 const ActiveSessionsCallback& callback) OVERRIDE { 126 dbus::MethodCall method_call( 127 login_manager::kSessionManagerInterface, 128 login_manager::kSessionManagerRetrieveActiveSessions); 129 130 session_manager_proxy_->CallMethod( 131 &method_call, 132 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 133 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions, 134 weak_ptr_factory_.GetWeakPtr(), 135 login_manager::kSessionManagerRetrieveActiveSessions, 136 callback)); 137 } 138 139 virtual void RetrieveDevicePolicy( 140 const RetrievePolicyCallback& callback) OVERRIDE { 141 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 142 login_manager::kSessionManagerRetrievePolicy); 143 session_manager_proxy_->CallMethod( 144 &method_call, 145 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 146 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy, 147 weak_ptr_factory_.GetWeakPtr(), 148 login_manager::kSessionManagerRetrievePolicy, 149 callback)); 150 } 151 152 virtual void RetrievePolicyForUser( 153 const std::string& username, 154 const RetrievePolicyCallback& callback) OVERRIDE { 155 CallRetrievePolicyByUsername( 156 login_manager::kSessionManagerRetrievePolicyForUser, 157 username, 158 callback); 159 } 160 161 virtual std::string BlockingRetrievePolicyForUser( 162 const std::string& username) OVERRIDE { 163 dbus::MethodCall method_call( 164 login_manager::kSessionManagerInterface, 165 login_manager::kSessionManagerRetrievePolicyForUser); 166 dbus::MessageWriter writer(&method_call); 167 writer.AppendString(username); 168 scoped_ptr<dbus::Response> response = 169 blocking_method_caller_->CallMethodAndBlock(&method_call); 170 std::string policy; 171 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser, 172 response.get(), 173 &policy); 174 return policy; 175 } 176 177 virtual void RetrieveDeviceLocalAccountPolicy( 178 const std::string& account_name, 179 const RetrievePolicyCallback& callback) OVERRIDE { 180 CallRetrievePolicyByUsername( 181 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy, 182 account_name, 183 callback); 184 } 185 186 virtual void StoreDevicePolicy(const std::string& policy_blob, 187 const StorePolicyCallback& callback) OVERRIDE { 188 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 189 login_manager::kSessionManagerStorePolicy); 190 dbus::MessageWriter writer(&method_call); 191 // static_cast does not work due to signedness. 192 writer.AppendArrayOfBytes( 193 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size()); 194 session_manager_proxy_->CallMethod( 195 &method_call, 196 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 197 base::Bind(&SessionManagerClientImpl::OnStorePolicy, 198 weak_ptr_factory_.GetWeakPtr(), 199 login_manager::kSessionManagerStorePolicy, 200 callback)); 201 } 202 203 virtual void StorePolicyForUser( 204 const std::string& username, 205 const std::string& policy_blob, 206 const std::string& ignored_policy_key, 207 const StorePolicyCallback& callback) OVERRIDE { 208 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, 209 username, 210 policy_blob, 211 callback); 212 } 213 214 virtual void StoreDeviceLocalAccountPolicy( 215 const std::string& account_name, 216 const std::string& policy_blob, 217 const StorePolicyCallback& callback) OVERRIDE { 218 CallStorePolicyByUsername( 219 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy, 220 account_name, 221 policy_blob, 222 callback); 223 } 224 225 virtual void SetFlagsForUser(const std::string& username, 226 const std::vector<std::string>& flags) OVERRIDE { 227 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 228 login_manager::kSessionManagerSetFlagsForUser); 229 dbus::MessageWriter writer(&method_call); 230 writer.AppendString(username); 231 writer.AppendArrayOfStrings(flags); 232 session_manager_proxy_->CallMethod( 233 &method_call, 234 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 235 dbus::ObjectProxy::EmptyResponseCallback()); 236 } 237 238 protected: 239 virtual void Init(dbus::Bus* bus) OVERRIDE { 240 session_manager_proxy_ = bus->GetObjectProxy( 241 login_manager::kSessionManagerServiceName, 242 dbus::ObjectPath(login_manager::kSessionManagerServicePath)); 243 blocking_method_caller_.reset( 244 new BlockingMethodCaller(bus, session_manager_proxy_)); 245 246 // Signals emitted on Chromium's interface. Many of these ought to be 247 // method calls instead. 248 session_manager_proxy_->ConnectToSignal( 249 chromium::kChromiumInterface, 250 chromium::kOwnerKeySetSignal, 251 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived, 252 weak_ptr_factory_.GetWeakPtr()), 253 base::Bind(&SessionManagerClientImpl::SignalConnected, 254 weak_ptr_factory_.GetWeakPtr())); 255 session_manager_proxy_->ConnectToSignal( 256 chromium::kChromiumInterface, 257 chromium::kPropertyChangeCompleteSignal, 258 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived, 259 weak_ptr_factory_.GetWeakPtr()), 260 base::Bind(&SessionManagerClientImpl::SignalConnected, 261 weak_ptr_factory_.GetWeakPtr())); 262 session_manager_proxy_->ConnectToSignal( 263 chromium::kChromiumInterface, 264 chromium::kLockScreenSignal, 265 base::Bind(&SessionManagerClientImpl::ScreenLockReceived, 266 weak_ptr_factory_.GetWeakPtr()), 267 base::Bind(&SessionManagerClientImpl::SignalConnected, 268 weak_ptr_factory_.GetWeakPtr())); 269 session_manager_proxy_->ConnectToSignal( 270 chromium::kChromiumInterface, 271 chromium::kLivenessRequestedSignal, 272 base::Bind(&SessionManagerClientImpl::LivenessRequestedReceived, 273 weak_ptr_factory_.GetWeakPtr()), 274 base::Bind(&SessionManagerClientImpl::SignalConnected, 275 weak_ptr_factory_.GetWeakPtr())); 276 277 // Signals emitted on the session manager's interface. 278 session_manager_proxy_->ConnectToSignal( 279 login_manager::kSessionManagerInterface, 280 login_manager::kScreenIsLockedSignal, 281 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived, 282 weak_ptr_factory_.GetWeakPtr()), 283 base::Bind(&SessionManagerClientImpl::SignalConnected, 284 weak_ptr_factory_.GetWeakPtr())); 285 session_manager_proxy_->ConnectToSignal( 286 login_manager::kSessionManagerInterface, 287 login_manager::kScreenIsUnlockedSignal, 288 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived, 289 weak_ptr_factory_.GetWeakPtr()), 290 base::Bind(&SessionManagerClientImpl::SignalConnected, 291 weak_ptr_factory_.GetWeakPtr())); 292 } 293 294 private: 295 // Makes a method call to the session manager with no arguments and no 296 // response. 297 void SimpleMethodCallToSessionManager(const std::string& method_name) { 298 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 299 method_name); 300 session_manager_proxy_->CallMethod( 301 &method_call, 302 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 303 dbus::ObjectProxy::EmptyResponseCallback()); 304 } 305 306 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser. 307 void CallRetrievePolicyByUsername(const std::string& method_name, 308 const std::string& username, 309 const RetrievePolicyCallback& callback) { 310 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 311 method_name); 312 dbus::MessageWriter writer(&method_call); 313 writer.AppendString(username); 314 session_manager_proxy_->CallMethod( 315 &method_call, 316 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 317 base::Bind( 318 &SessionManagerClientImpl::OnRetrievePolicy, 319 weak_ptr_factory_.GetWeakPtr(), 320 method_name, 321 callback)); 322 } 323 324 void CallStorePolicyByUsername(const std::string& method_name, 325 const std::string& username, 326 const std::string& policy_blob, 327 const StorePolicyCallback& callback) { 328 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 329 method_name); 330 dbus::MessageWriter writer(&method_call); 331 writer.AppendString(username); 332 // static_cast does not work due to signedness. 333 writer.AppendArrayOfBytes( 334 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size()); 335 session_manager_proxy_->CallMethod( 336 &method_call, 337 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 338 base::Bind( 339 &SessionManagerClientImpl::OnStorePolicy, 340 weak_ptr_factory_.GetWeakPtr(), 341 method_name, 342 callback)); 343 } 344 345 // Called when kSessionManagerRestartJob method is complete. 346 void OnRestartJob(dbus::Response* response) { 347 LOG_IF(ERROR, !response) 348 << "Failed to call " 349 << login_manager::kSessionManagerRestartJob; 350 } 351 352 // Called when kSessionManagerStartSession method is complete. 353 void OnStartSession(dbus::Response* response) { 354 LOG_IF(ERROR, !response) 355 << "Failed to call " 356 << login_manager::kSessionManagerStartSession; 357 } 358 359 // Called when kSessionManagerStopSession method is complete. 360 void OnStopSession(dbus::Response* response) { 361 LOG_IF(ERROR, !response) 362 << "Failed to call " 363 << login_manager::kSessionManagerStopSession; 364 } 365 366 // Called when kSessionManagerStopSession method is complete. 367 void OnDeviceWipe(dbus::Response* response) { 368 LOG_IF(ERROR, !response) 369 << "Failed to call " 370 << login_manager::kSessionManagerStartDeviceWipe; 371 } 372 373 // Called when kSessionManagerRetrieveActiveSessions method is complete. 374 void OnRetrieveActiveSessions(const std::string& method_name, 375 const ActiveSessionsCallback& callback, 376 dbus::Response* response) { 377 ActiveSessionsMap sessions; 378 bool success = false; 379 if (!response) { 380 LOG(ERROR) << "Failed to call " << method_name; 381 callback.Run(sessions, success); 382 return; 383 } 384 385 dbus::MessageReader reader(response); 386 dbus::MessageReader array_reader(NULL); 387 388 if (!reader.PopArray(&array_reader)) { 389 LOG(ERROR) << method_name << " response is incorrect: " 390 << response->ToString(); 391 } else { 392 while (array_reader.HasMoreData()) { 393 dbus::MessageReader dict_entry_reader(NULL); 394 std::string key; 395 std::string value; 396 if (!array_reader.PopDictEntry(&dict_entry_reader) || 397 !dict_entry_reader.PopString(&key) || 398 !dict_entry_reader.PopString(&value)) { 399 LOG(ERROR) << method_name << " response is incorrect: " 400 << response->ToString(); 401 } else { 402 sessions[key] = value; 403 } 404 } 405 success = true; 406 } 407 callback.Run(sessions, success); 408 } 409 410 void ExtractString(const std::string& method_name, 411 dbus::Response* response, 412 std::string* extracted) { 413 if (!response) { 414 LOG(ERROR) << "Failed to call " << method_name; 415 return; 416 } 417 dbus::MessageReader reader(response); 418 uint8* values = NULL; 419 size_t length = 0; 420 if (!reader.PopArrayOfBytes(&values, &length)) { 421 LOG(ERROR) << "Invalid response: " << response->ToString(); 422 return; 423 } 424 // static_cast does not work due to signedness. 425 extracted->assign(reinterpret_cast<char*>(values), length); 426 } 427 428 // Called when kSessionManagerRetrievePolicy or 429 // kSessionManagerRetrievePolicyForUser method is complete. 430 void OnRetrievePolicy(const std::string& method_name, 431 const RetrievePolicyCallback& callback, 432 dbus::Response* response) { 433 std::string serialized_proto; 434 ExtractString(method_name, response, &serialized_proto); 435 callback.Run(serialized_proto); 436 } 437 438 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser 439 // method is complete. 440 void OnStorePolicy(const std::string& method_name, 441 const StorePolicyCallback& callback, 442 dbus::Response* response) { 443 bool success = false; 444 if (!response) { 445 LOG(ERROR) << "Failed to call " << method_name; 446 } else { 447 dbus::MessageReader reader(response); 448 if (!reader.PopBool(&success)) 449 LOG(ERROR) << "Invalid response: " << response->ToString(); 450 } 451 callback.Run(success); 452 } 453 454 // Called when the owner key set signal is received. 455 void OwnerKeySetReceived(dbus::Signal* signal) { 456 dbus::MessageReader reader(signal); 457 std::string result_string; 458 if (!reader.PopString(&result_string)) { 459 LOG(ERROR) << "Invalid signal: " << signal->ToString(); 460 return; 461 } 462 const bool success = StartsWithASCII(result_string, "success", false); 463 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success)); 464 } 465 466 // Called when the property change complete signal is received. 467 void PropertyChangeCompleteReceived(dbus::Signal* signal) { 468 dbus::MessageReader reader(signal); 469 std::string result_string; 470 if (!reader.PopString(&result_string)) { 471 LOG(ERROR) << "Invalid signal: " << signal->ToString(); 472 return; 473 } 474 const bool success = StartsWithASCII(result_string, "success", false); 475 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success)); 476 } 477 478 void ScreenLockReceived(dbus::Signal* signal) { 479 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); 480 } 481 482 void LivenessRequestedReceived(dbus::Signal* signal) { 483 SimpleMethodCallToSessionManager( 484 login_manager::kSessionManagerHandleLivenessConfirmed); 485 } 486 487 void ScreenIsLockedReceived(dbus::Signal* signal) { 488 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); 489 } 490 491 void ScreenIsUnlockedReceived(dbus::Signal* signal) { 492 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); 493 } 494 495 // Called when the object is connected to the signal. 496 void SignalConnected(const std::string& interface_name, 497 const std::string& signal_name, 498 bool success) { 499 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name; 500 } 501 502 dbus::ObjectProxy* session_manager_proxy_; 503 scoped_ptr<BlockingMethodCaller> blocking_method_caller_; 504 ObserverList<Observer> observers_; 505 506 // Note: This should remain the last member so it'll be destroyed and 507 // invalidate its weak pointers before any other members are destroyed. 508 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_; 509 510 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl); 511 }; 512 513 // The SessionManagerClient implementation used on Linux desktop, 514 // which does nothing. 515 class SessionManagerClientStubImpl : public SessionManagerClient { 516 public: 517 SessionManagerClientStubImpl() {} 518 virtual ~SessionManagerClientStubImpl() {} 519 520 // SessionManagerClient overrides 521 virtual void Init(dbus::Bus* bus) OVERRIDE { 522 // Make sure that there are no keys left over from a previous browser run. 523 base::FilePath user_policy_key_dir; 524 if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS, 525 &user_policy_key_dir)) { 526 base::WorkerPool::PostTask( 527 FROM_HERE, 528 base::Bind(base::IgnoreResult(&base::DeleteFile), 529 user_policy_key_dir, true), 530 false); 531 } 532 } 533 534 virtual void AddObserver(Observer* observer) OVERRIDE { 535 observers_.AddObserver(observer); 536 } 537 virtual void RemoveObserver(Observer* observer) OVERRIDE { 538 observers_.RemoveObserver(observer); 539 } 540 virtual bool HasObserver(Observer* observer) OVERRIDE { 541 return observers_.HasObserver(observer); 542 } 543 virtual void EmitLoginPromptReady() OVERRIDE {} 544 virtual void EmitLoginPromptVisible() OVERRIDE {} 545 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} 546 virtual void StartSession(const std::string& user_email) OVERRIDE {} 547 virtual void StopSession() OVERRIDE {} 548 virtual void StartDeviceWipe() OVERRIDE {} 549 virtual void RequestLockScreen() OVERRIDE { 550 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); 551 } 552 virtual void NotifyLockScreenShown() OVERRIDE { 553 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); 554 } 555 virtual void NotifyLockScreenDismissed() OVERRIDE { 556 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); 557 } 558 virtual void RetrieveActiveSessions( 559 const ActiveSessionsCallback& callback) OVERRIDE {} 560 virtual void RetrieveDevicePolicy( 561 const RetrievePolicyCallback& callback) OVERRIDE { 562 callback.Run(device_policy_); 563 } 564 virtual void RetrievePolicyForUser( 565 const std::string& username, 566 const RetrievePolicyCallback& callback) OVERRIDE { 567 callback.Run(user_policies_[username]); 568 } 569 virtual std::string BlockingRetrievePolicyForUser( 570 const std::string& username) OVERRIDE { 571 return user_policies_[username]; 572 } 573 virtual void RetrieveDeviceLocalAccountPolicy( 574 const std::string& account_name, 575 const RetrievePolicyCallback& callback) OVERRIDE { 576 callback.Run(user_policies_[account_name]); 577 } 578 virtual void StoreDevicePolicy(const std::string& policy_blob, 579 const StorePolicyCallback& callback) OVERRIDE { 580 device_policy_ = policy_blob; 581 callback.Run(true); 582 } 583 virtual void StorePolicyForUser( 584 const std::string& username, 585 const std::string& policy_blob, 586 const std::string& policy_key, 587 const StorePolicyCallback& callback) OVERRIDE { 588 if (policy_key.empty()) { 589 user_policies_[username] = policy_blob; 590 callback.Run(true); 591 return; 592 } 593 // The session manager writes the user policy key to a well-known 594 // location. Do the same with the stub impl, so that user policy works and 595 // can be tested on desktop builds. 596 // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get 597 // the policy key directly, after moving the policy protobufs to a top-level 598 // directory. The |policy_key| argument to this method can then be removed. 599 // http://crbug.com/240269 600 base::FilePath key_path; 601 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) { 602 callback.Run(false); 603 return; 604 } 605 const std::string sanitized = 606 CryptohomeClient::GetStubSanitizedUsername(username); 607 key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub"); 608 // Assume that the key write is successful. 609 user_policies_[username] = policy_blob; 610 base::WorkerPool::PostTaskAndReply( 611 FROM_HERE, 612 base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground, 613 key_path, policy_key), 614 base::Bind(callback, true), 615 false); 616 } 617 virtual void StoreDeviceLocalAccountPolicy( 618 const std::string& account_name, 619 const std::string& policy_blob, 620 const StorePolicyCallback& callback) OVERRIDE { 621 user_policies_[account_name] = policy_blob; 622 callback.Run(true); 623 } 624 virtual void SetFlagsForUser(const std::string& username, 625 const std::vector<std::string>& flags) OVERRIDE { 626 } 627 628 static void StoreFileInBackground(const base::FilePath& path, 629 const std::string& data) { 630 const int size = static_cast<int>(data.size()); 631 if (!base::CreateDirectory(path.DirName()) || 632 file_util::WriteFile(path, data.data(), size) != size) { 633 LOG(WARNING) << "Failed to write policy key to " << path.value(); 634 } 635 } 636 637 private: 638 ObserverList<Observer> observers_; 639 std::string device_policy_; 640 std::map<std::string, std::string> user_policies_; 641 642 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); 643 }; 644 645 SessionManagerClient::SessionManagerClient() { 646 } 647 648 SessionManagerClient::~SessionManagerClient() { 649 } 650 651 SessionManagerClient* SessionManagerClient::Create( 652 DBusClientImplementationType type) { 653 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 654 return new SessionManagerClientImpl(); 655 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 656 return new SessionManagerClientStubImpl(); 657 } 658 659 } // namespace chromeos 660