| OLD | NEW |
| 1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "login_manager/session_manager_service.h" | 5 #include "login_manager/session_manager_service.h" |
| 6 | 6 |
| 7 #include <dbus/dbus-glib-lowlevel.h> | 7 #include <dbus/dbus-glib-lowlevel.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <glib.h> | 9 #include <glib.h> |
| 10 #include <grp.h> | 10 #include <grp.h> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 G_TYPE_NONE, // return type | 199 G_TYPE_NONE, // return type |
| 200 2, // num params | 200 2, // num params |
| 201 G_TYPE_STRING, // state ("started" or "stopped") | 201 G_TYPE_STRING, // state ("started" or "stopped") |
| 202 G_TYPE_STRING); // current user | 202 G_TYPE_STRING); // current user |
| 203 | 203 |
| 204 if (!store_->LoadOrCreate()) | 204 if (!store_->LoadOrCreate()) |
| 205 LOG(ERROR) << "Could not load existing settings. Continuing anyway..."; | 205 LOG(ERROR) << "Could not load existing settings. Continuing anyway..."; |
| 206 return Reset(); | 206 return Reset(); |
| 207 } | 207 } |
| 208 | 208 |
| 209 bool SessionManagerService::Register( |
| 210 const chromeos::dbus::BusConnection &connection) { |
| 211 if (!chromeos::dbus::AbstractDbusService::Register(connection)) |
| 212 return false; |
| 213 const std::string filter = |
| 214 StringPrintf("type='method_call', interface='%s'", service_interface()); |
| 215 DBusConnection* conn = |
| 216 ::dbus_g_connection_get_connection(connection.g_connection()); |
| 217 CHECK(conn); |
| 218 DBusError error; |
| 219 ::dbus_error_init(&error); |
| 220 ::dbus_bus_add_match(conn, filter.c_str(), &error); |
| 221 if (::dbus_error_is_set(&error)) { |
| 222 LOG(WARNING) << "Failed to add match to bus: " << error.name << ", message=" |
| 223 << (error.message ? error.message : "unknown error"); |
| 224 return false; |
| 225 } |
| 226 if (!::dbus_connection_add_filter(conn, |
| 227 &SessionManagerService::FilterMessage, |
| 228 this, |
| 229 NULL)) { |
| 230 LOG(WARNING) << "Failed to add filter to connection"; |
| 231 return false; |
| 232 } |
| 233 return true; |
| 234 } |
| 235 |
| 209 bool SessionManagerService::Reset() { | 236 bool SessionManagerService::Reset() { |
| 210 if (session_manager_) | 237 if (session_manager_) |
| 211 g_object_unref(session_manager_); | 238 g_object_unref(session_manager_); |
| 212 session_manager_ = | 239 session_manager_ = |
| 213 reinterpret_cast<gobject::SessionManager*>( | 240 reinterpret_cast<gobject::SessionManager*>( |
| 214 g_object_new(gobject::session_manager_get_type(), NULL)); | 241 g_object_new(gobject::session_manager_get_type(), NULL)); |
| 215 | 242 |
| 216 // Allow references to this instance. | 243 // Allow references to this instance. |
| 217 session_manager_->service = this; | 244 session_manager_->service = this; |
| 218 | 245 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 exit(1); // Run() is not supposed to return. | 332 exit(1); // Run() is not supposed to return. |
| 306 } | 333 } |
| 307 g_child_watch_add_full(G_PRIORITY_HIGH_IDLE, | 334 g_child_watch_add_full(G_PRIORITY_HIGH_IDLE, |
| 308 pid, | 335 pid, |
| 309 HandleChildExit, | 336 HandleChildExit, |
| 310 this, | 337 this, |
| 311 NULL); | 338 NULL); |
| 312 return pid; | 339 return pid; |
| 313 } | 340 } |
| 314 | 341 |
| 342 bool SessionManagerService::IsKnownChild(int pid) { |
| 343 return std::find(child_pids_.begin(), child_pids_.end(), pid) != |
| 344 child_pids_.end(); |
| 345 } |
| 346 |
| 315 void SessionManagerService::AllowGracefulExit() { | 347 void SessionManagerService::AllowGracefulExit() { |
| 316 shutting_down_ = true; | 348 shutting_down_ = true; |
| 317 if (exit_on_child_done_) { | 349 if (exit_on_child_done_) { |
| 318 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, | 350 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, |
| 319 ServiceShutdown, | 351 ServiceShutdown, |
| 320 this, | 352 this, |
| 321 NULL); | 353 NULL); |
| 322 } | 354 } |
| 323 } | 355 } |
| 324 | 356 |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 if (at == string::npos) | 833 if (at == string::npos) |
| 802 return false; | 834 return false; |
| 803 | 835 |
| 804 // it has more than one @. | 836 // it has more than one @. |
| 805 if (email_address.find(kEmailSeparator, at+1) != string::npos) | 837 if (email_address.find(kEmailSeparator, at+1) != string::npos) |
| 806 return false; | 838 return false; |
| 807 | 839 |
| 808 return true; | 840 return true; |
| 809 } | 841 } |
| 810 | 842 |
| 843 // static |
| 844 DBusHandlerResult SessionManagerService::FilterMessage(DBusConnection* conn, |
| 845 DBusMessage* message, |
| 846 void* data) { |
| 847 SessionManagerService* service = static_cast<SessionManagerService*>(data); |
| 848 if (::dbus_message_is_method_call(message, |
| 849 service->service_interface(), |
| 850 kSessionManagerRestartJob)) { |
| 851 const char* sender = ::dbus_message_get_sender(message); |
| 852 if (!sender) { |
| 853 LOG(ERROR) << "Call to RestartJob has no sender"; |
| 854 return DBUS_HANDLER_RESULT_HANDLED; |
| 855 } |
| 856 LOG(INFO) << "Received RestartJob from " << sender; |
| 857 DBusMessage* get_pid = |
| 858 ::dbus_message_new_method_call("org.freedesktop.DBus", |
| 859 "/org/freedesktop/DBus", |
| 860 "org.freedesktop.DBus", |
| 861 "GetConnectionUnixProcessID"); |
| 862 CHECK(get_pid); |
| 863 ::dbus_message_append_args(get_pid, |
| 864 DBUS_TYPE_STRING, &sender, |
| 865 DBUS_TYPE_INVALID); |
| 866 DBusMessage* got_pid = |
| 867 ::dbus_connection_send_with_reply_and_block(conn, get_pid, -1, NULL); |
| 868 ::dbus_message_unref(get_pid); |
| 869 if (!got_pid) { |
| 870 LOG(ERROR) << "Could not look up sender of RestartJob"; |
| 871 return DBUS_HANDLER_RESULT_HANDLED; |
| 872 } |
| 873 uint32 pid; |
| 874 if (!::dbus_message_get_args(got_pid, NULL, |
| 875 DBUS_TYPE_UINT32, &pid, |
| 876 DBUS_TYPE_INVALID)) { |
| 877 ::dbus_message_unref(got_pid); |
| 878 LOG(ERROR) << "Could not extract pid of sender of RestartJob"; |
| 879 return DBUS_HANDLER_RESULT_HANDLED; |
| 880 } |
| 881 ::dbus_message_unref(got_pid); |
| 882 if (!service->IsKnownChild(pid)) { |
| 883 LOG(WARNING) << "Sender of RestartJob is no child of mine!"; |
| 884 return DBUS_HANDLER_RESULT_HANDLED; |
| 885 } |
| 886 } |
| 887 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 888 } |
| 889 |
| 811 void SessionManagerService::SetupHandlers() { | 890 void SessionManagerService::SetupHandlers() { |
| 812 // I have to ignore SIGUSR1, because Xorg sends it to this process when it's | 891 // I have to ignore SIGUSR1, because Xorg sends it to this process when it's |
| 813 // got no clients and is ready for new ones. If we don't ignore it, we die. | 892 // got no clients and is ready for new ones. If we don't ignore it, we die. |
| 814 struct sigaction action; | 893 struct sigaction action; |
| 815 memset(&action, 0, sizeof(action)); | 894 memset(&action, 0, sizeof(action)); |
| 816 action.sa_handler = SIG_IGN; | 895 action.sa_handler = SIG_IGN; |
| 817 CHECK(sigaction(SIGUSR1, &action, NULL) == 0); | 896 CHECK(sigaction(SIGUSR1, &action, NULL) == 0); |
| 818 | 897 |
| 819 action.sa_handler = SessionManagerService::do_nothing; | 898 action.sa_handler = SessionManagerService::do_nothing; |
| 820 CHECK(sigaction(SIGALRM, &action, NULL) == 0); | 899 CHECK(sigaction(SIGALRM, &action, NULL) == 0); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 | 1077 |
| 999 gboolean SessionManagerService::GetPropertyHelper(const std::string& name, | 1078 gboolean SessionManagerService::GetPropertyHelper(const std::string& name, |
| 1000 std::string* OUT_value, | 1079 std::string* OUT_value, |
| 1001 std::string* OUT_signature, | 1080 std::string* OUT_signature, |
| 1002 GError** error) { | 1081 GError** error) { |
| 1003 std::string encoded; | 1082 std::string encoded; |
| 1004 if (!store_->Get(name, OUT_value, &encoded)) { | 1083 if (!store_->Get(name, OUT_value, &encoded)) { |
| 1005 std::string error_string = | 1084 std::string error_string = |
| 1006 base::StringPrintf("The requested property %s is unknown.", | 1085 base::StringPrintf("The requested property %s is unknown.", |
| 1007 name.c_str()); | 1086 name.c_str()); |
| 1008 LOG(INFO) << error_string; | |
| 1009 SetGError(error, | 1087 SetGError(error, |
| 1010 CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY, | 1088 CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY, |
| 1011 error_string.c_str()); | 1089 error_string.c_str()); |
| 1012 return FALSE; | 1090 return FALSE; |
| 1013 } | 1091 } |
| 1014 if (!base::Base64Decode(encoded, OUT_signature)) { | 1092 if (!base::Base64Decode(encoded, OUT_signature)) { |
| 1015 SetGError(error, | 1093 SetGError(error, |
| 1016 CHROMEOS_LOGIN_ERROR_DECODE_FAIL, | 1094 CHROMEOS_LOGIN_ERROR_DECODE_FAIL, |
| 1017 "Signature could not be decoded."); | 1095 "Signature could not be decoded."); |
| 1018 return FALSE; | 1096 return FALSE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1035 arg_list.push_back(args[i_arg]); | 1113 arg_list.push_back(args[i_arg]); |
| 1036 } | 1114 } |
| 1037 } | 1115 } |
| 1038 if (arg_list.size()) { | 1116 if (arg_list.size()) { |
| 1039 arg_lists.push_back(arg_list); | 1117 arg_lists.push_back(arg_list); |
| 1040 } | 1118 } |
| 1041 return arg_lists; | 1119 return arg_lists; |
| 1042 } | 1120 } |
| 1043 | 1121 |
| 1044 } // namespace login_manager | 1122 } // namespace login_manager |
| OLD | NEW |