authpolicy: Implement daemon and D-Bus interface with Samba stub
Provides complete D-Bus interface with two new methods to refresh
user and device policy. Separates main/daemon from D-Bus interface
implementation and adds Samba interface stub to be implemented in a
subsequent CL. The D-Bus methods will be called by Chrome to
authenticate, join a device to a AD domain and fetch policy.
Code requires the CL below to compile.
BUG=chromium:653509
TEST=Emerges. Daemon runs, but just stub code so far.
CQ-DEPEND=CL:403068
Change-Id: Ic5eb4621f1c21fccc26e7e3f656b6751fdceba96
Reviewed-on: https://chromium-review.googlesource.com/403872
Commit-Ready: Lutz Justen <ljusten@chromium.org>
Tested-by: Lutz Justen <ljusten@chromium.org>
Tested-by: Roman Sorokin <rsorokin@chromium.org>
Reviewed-by: Lutz Justen <ljusten@chromium.org>
Reviewed-by: Roman Sorokin <rsorokin@chromium.org>
diff --git a/authpolicy/authpolicy.cc b/authpolicy/authpolicy.cc
index ce6f5c1..627f0e1 100644
--- a/authpolicy/authpolicy.cc
+++ b/authpolicy/authpolicy.cc
@@ -2,108 +2,215 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <base/logging.h>
-#include <brillo/daemons/dbus_daemon.h>
-#include <brillo/dbus/async_event_sequencer.h>
+#include "authpolicy/authpolicy.h"
+
+#include <utility>
+#include <vector>
+
+#include <base/strings/stringprintf.h>
+#include <bindings/chrome_device_policy.pb.h>
+#include <bindings/device_management_backend.pb.h>
+#include <brillo/dbus/dbus_method_invoker.h>
#include <chromeos/dbus/service_constants.h>
-#include <install_attributes/libinstallattributes.h>
-#include "authpolicy/org.chromium.AuthPolicy.h"
+#include "authpolicy/errors.h"
+#include "authpolicy/policy/preg_policy_encoder.h"
+#include "authpolicy/policy/proto/cloud_policy.pb.h"
+#include "authpolicy/samba_interface.h"
-using brillo::dbus_utils::AsyncEventSequencer;
+namespace em = enterprise_management;
-namespace org {
-namespace chromium {
+using brillo::dbus_utils::ExtractMethodCallResults;
+
namespace authpolicy {
-const char kObjectServicePath[] = "/org/chromium/AuthPolicy/ObjectManager";
+AuthPolicy::AuthPolicy(
+ brillo::dbus_utils::ExportedObjectManager* object_manager)
+ : org::chromium::AuthPolicyAdaptor(this),
+ dbus_object_(object_manager, object_manager->GetBus(),
+ org::chromium::AuthPolicyAdaptor::GetObjectPath()),
+ session_manager_proxy_(nullptr),
+ weak_ptr_factory_(this) {}
-class Domain : public org::chromium::AuthPolicyInterface {
- public:
- explicit Domain(brillo::dbus_utils::ExportedObjectManager* object_manager)
- : dbus_object_{new brillo::dbus_utils::DBusObject{
- object_manager, object_manager->GetBus(),
- org::chromium::AuthPolicyAdaptor::GetObjectPath()}} {
- }
+void AuthPolicy::RegisterAsync(
+ const AsyncEventSequencer::CompletionAction& completion_callback) {
+ RegisterWithDBusObject(&dbus_object_);
+ dbus_object_.RegisterAsync(completion_callback);
+ session_manager_proxy_ = dbus_object_.GetBus()->GetObjectProxy(
+ login_manager::kSessionManagerServiceName,
+ dbus::ObjectPath(login_manager::kSessionManagerServicePath));
+ DCHECK(session_manager_proxy_);
+}
- ~Domain() override = default;
- bool AuthenticateUser(
- brillo::ErrorPtr* error,
- const std::string& in_user_principal_name,
- const dbus::FileDescriptor& in_password_fd,
- int32_t* out_code,
- std::string* account_id) override {
+bool AuthPolicy::AuthenticateUser(brillo::ErrorPtr* error,
+ const std::string& in_user_principal_name,
+ const dbus::FileDescriptor& in_password_fd,
+ int32_t* out_error_code,
+ std::string* out_account_id) {
+ LOG(INFO) << "Received 'AuthenticateUser' request";
+ *out_error_code = 0;
+
+ // Call samba to authenticate user and get account id.
+ const char* error_code;
+ if (!samba_.AuthenticateUser(in_user_principal_name, in_password_fd.value(),
+ out_account_id, &error_code)) {
+ brillo::Error::AddToPrintf(error, FROM_HERE, errors::kDomain,
+ error_code, "Failed to authenticate user.");
return false;
}
- bool JoinADDomain(
- brillo::ErrorPtr* error,
- const std::string& in_machine_name,
- const std::string& in_user_principal_name,
- const dbus::FileDescriptor& in_password_fd,
- int32_t* out_code) override {
+ LOG(INFO) << "AuthenticateUser succeeded";
+ return true;
+}
+
+bool AuthPolicy::JoinADDomain(brillo::ErrorPtr* error,
+ const std::string& in_machine_name,
+ const std::string& in_user_principal_name,
+ const dbus::FileDescriptor& in_password_fd,
+ int32_t* out_error_code) {
+ LOG(INFO) << "Received 'JoinADDomain' request";
+ *out_error_code = 0;
+
+ // Call samba to join machine to the AD domain.
+ const char* error_code;
+ if (!samba_.JoinMachine(in_machine_name, in_user_principal_name,
+ in_password_fd.value(), &error_code)) {
+ brillo::Error::AddToPrintf(error, FROM_HERE, errors::kDomain,
+ error_code, "Failed to join AD domain.");
return false;
}
- void RegisterAsync(
- const AsyncEventSequencer::CompletionAction& completion_callback) {
- scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
- dbus_adaptor_.RegisterWithDBusObject(dbus_object_.get());
- dbus_object_->RegisterAsync(
- sequencer->GetHandler("Failed exporting Domain.", true));
- sequencer->OnAllTasksCompletedCall({completion_callback});
+ LOG(INFO) << "JoinADDomain succeeded";
+ return true;
+}
+
+void AuthPolicy::RefreshUserPolicy(PolicyResponseCallback response,
+ const std::string& in_account_id) {
+ LOG(INFO) << "Received 'RefreshUserPolicy' request";
+
+ // Fetch GPOs for the current user.
+ const char* error_code;
+ std::vector<base::FilePath> gpo_file_paths;
+ if (!samba_.FetchUserGpos(in_account_id, &gpo_file_paths, &error_code)) {
+ response->ReplyWithError(FROM_HERE, errors::kDomain, error_code,
+ "Failed to fetch user policy.");
+ return;
}
- private:
- org::chromium::AuthPolicyAdaptor dbus_adaptor_{this};
- std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_;
-};
-
-class Daemon : public brillo::DBusServiceDaemon {
- public:
- Daemon() : DBusServiceDaemon(::authpolicy::kAuthPolicyInterface,
- kObjectServicePath) {
+ // Load GPOs into policy.
+ em::CloudPolicySettings policy;
+ if (!policy::ParsePRegFilesIntoUserPolicy(gpo_file_paths, &policy,
+ &error_code)) {
+ response->ReplyWithError(FROM_HERE, errors::kDomain, error_code,
+ "Failed to parse user policy preg files.");
+ return;
}
- protected:
- void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
- domain_.reset(new Domain(object_manager_.get()));
- domain_->RegisterAsync(
- sequencer->GetHandler("Domain.RegisterAsync() failed.", true));
+ LOG(INFO) << "User policy fetch and parsing succeeded";
+
+ // Send policy to Session Manager.
+ StoreUserPolicy(in_account_id, policy, std::move(response));
+}
+
+void AuthPolicy::RefreshDevicePolicy(PolicyResponseCallback response) {
+ LOG(INFO) << "Received 'RefreshDevicePolicy' request";
+
+ // Fetch GPOs for the device.
+ const char* error_code;
+ std::vector<base::FilePath> gpo_file_paths;
+ if (!samba_.FetchDeviceGpos(&gpo_file_paths, &error_code)) {
+ response->ReplyWithError(FROM_HERE, errors::kDomain, error_code,
+ "Failed to refresh device policy");
+ return;
}
- void OnShutdown(int* return_code) override {
- DBusServiceDaemon::OnShutdown(return_code);
- domain_.reset();
+ // Load GPOs into policy.
+ em::ChromeDeviceSettingsProto policy;
+ if (!policy::ParsePRegFilesIntoDevicePolicy(gpo_file_paths, &policy,
+ &error_code)) {
+ response->ReplyWithError(FROM_HERE, errors::kDomain, error_code,
+ "Failed to parse device policy preg files.");
+ return;
}
- private:
- std::unique_ptr<Domain> domain_;
+ LOG(INFO) << "Device policy fetch and parsing succeeded";
- DISALLOW_COPY_AND_ASSIGN(Daemon);
-};
+ // Send policy to Session Manager.
+ StoreDevicePolicy(policy, std::move(response));
+}
+
+void AuthPolicy::StoreUserPolicy(const std::string& account_id,
+ const em::CloudPolicySettings& policy,
+ PolicyResponseCallback callback) {
+ em::PolicyFetchResponse policy_response;
+ // Note: No signature required here, AD policy is unsigned!
+ if (!policy.SerializeToString(policy_response.mutable_policy_data())) {
+ callback->ReplyWithError(FROM_HERE, errors::kDomain,
+ errors::kStorePolicyFailed,
+ "Failed to serialize user policy protobuf.");
+ return;
+ }
+
+ StorePolicy(policy_response.SerializeAsString(), &account_id,
+ std::move(callback));
+}
+
+void AuthPolicy::StoreDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
+ PolicyResponseCallback callback) {
+ em::PolicyFetchResponse policy_response;
+ // Note: No signature required here, AD policy is unsigned!
+ if (!policy.SerializeToString(policy_response.mutable_policy_data())) {
+ callback->ReplyWithError(FROM_HERE, errors::kDomain,
+ errors::kStorePolicyFailed,
+ "Failed to serialize device policy protobuf.");
+ return;
+ }
+ StorePolicy(policy_response.SerializeAsString(), nullptr,
+ std::move(callback));
+}
+
+void AuthPolicy::StorePolicy(const std::string& policy_blob,
+ const std::string* account_id,
+ PolicyResponseCallback callback) {
+ const char* const method =
+ account_id ? login_manager::kSessionManagerStoreUnsignedPolicyForUser
+ : login_manager::kSessionManagerStoreUnsignedPolicy;
+
+ LOG(INFO) << "Calling Session Manager D-Bus method " << method;
+ dbus::MethodCall method_call(login_manager::kSessionManagerInterface, method);
+ dbus::MessageWriter writer(&method_call);
+ if (account_id) writer.AppendString(*account_id);
+ writer.AppendArrayOfBytes(
+ reinterpret_cast<const uint8_t*>(policy_blob.data()), policy_blob.size());
+ session_manager_proxy_->CallMethod(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&AuthPolicy::OnPolicyStored, weak_ptr_factory_.GetWeakPtr(),
+ method, base::Passed(&callback)));
+}
+
+void AuthPolicy::OnPolicyStored(const char* method,
+ PolicyResponseCallback callback,
+ dbus::Response* response) {
+ brillo::ErrorPtr error;
+ bool done = false;
+ std::string msg;
+ if (!response) {
+ msg = base::StringPrintf("Call to %s failed. No response.", method);
+ } else if (!ExtractMethodCallResults(response, &error, &done)) {
+ msg = base::StringPrintf("Call to %s failed. %s",
+ method, error ? error->GetMessage().c_str() : "Unknown error.");
+ } else if (!done) {
+ msg = base::StringPrintf("Call to %s failed. Call returned false.", method);
+ }
+
+ if (!msg.empty()) {
+ LOG(ERROR) << msg;
+ callback->ReplyWithError(FROM_HERE, errors::kDomain,
+ errors::kStorePolicyFailed, msg);
+ } else {
+ LOG(INFO) << "Call to " << method << " succeeded.";
+ callback->Return(0);
+ }
+}
} // namespace authpolicy
-} // namespace chromium
-} // namespace org
-
-int main() {
- // Safety check to ensure that authpolicyd cannot run after the device has
- // been locked to a mode other than enterprise_ad. (The lifetime management
- // of authpolicyd happens through upstart, this check only serves as a second
- // line of defense.)
- InstallAttributesReader install_attributes_reader;
- if (install_attributes_reader.IsLocked()) {
- const std::string& mode =
- install_attributes_reader.GetAttribute(
- InstallAttributesReader::kAttrMode);
- if (mode != InstallAttributesReader::kDeviceModeEnterpriseAD) {
- LOG(ERROR) << "OOBE completed but device not in AD management mode.";
- // Exit with "success" to prevent respawn by upstart.
- exit(0);
- }
- }
-
- org::chromium::authpolicy::Daemon daemon;
- return daemon.Run();
-}
diff --git a/authpolicy/authpolicy.gyp b/authpolicy/authpolicy.gyp
index 60b5505..7054de8 100644
--- a/authpolicy/authpolicy.gyp
+++ b/authpolicy/authpolicy.gyp
@@ -40,6 +40,7 @@
},
'sources': [
'authpolicy.cc',
+ 'authpolicy_main.cc',
'dbus_bindings/org.chromium.AuthPolicy.xml',
'errors.cc',
'policy/device_policy_encoder.cc',
@@ -58,7 +59,6 @@
'-linstallattributes-<(libbase_ver)',
]
},
-
}
]
}
diff --git a/authpolicy/authpolicy.h b/authpolicy/authpolicy.h
new file mode 100644
index 0000000..185bc21
--- /dev/null
+++ b/authpolicy/authpolicy.h
@@ -0,0 +1,86 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AUTHPOLICY_AUTHPOLICY_H_
+#define AUTHPOLICY_AUTHPOLICY_H_
+
+#include <memory>
+#include <string>
+
+#include <brillo/dbus/async_event_sequencer.h>
+#include <dbus/object_proxy.h>
+
+#include "authpolicy/org.chromium.AuthPolicy.h"
+#include "authpolicy/samba_interface.h"
+
+using brillo::dbus_utils::AsyncEventSequencer;
+
+namespace enterprise_management {
+class CloudPolicySettings;
+class ChromeDeviceSettingsProto;
+}
+
+namespace authpolicy {
+
+class AuthPolicy : public org::chromium::AuthPolicyAdaptor,
+ public org::chromium::AuthPolicyInterface {
+ public:
+ using PolicyResponseCallback =
+ std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>>;
+
+ explicit AuthPolicy(
+ brillo::dbus_utils::ExportedObjectManager* object_manager);
+ ~AuthPolicy() override = default;
+
+ // Register the D-Bus object and interfaces.
+ void RegisterAsync(
+ const AsyncEventSequencer::CompletionAction& completion_callback);
+
+ // org::chromium::AuthPolicyInterface: (see org.chromium.AuthPolicy.xml)
+ bool AuthenticateUser(brillo::ErrorPtr* error,
+ const std::string& in_user_principal_name,
+ const dbus::FileDescriptor& in_password_fd,
+ int32_t* out_error_code,
+ std::string* out_account_id) override;
+ bool JoinADDomain(brillo::ErrorPtr* error, const std::string& in_machine_name,
+ const std::string& in_user_principal_name,
+ const dbus::FileDescriptor& in_password_fd,
+ int32_t* out_error_code) override;
+ void RefreshUserPolicy(PolicyResponseCallback response,
+ const std::string& in_account_id) override;
+ void RefreshDevicePolicy(PolicyResponseCallback response) override;
+
+ private:
+ // Sends the user policy blob to SessionManager.
+ void StoreUserPolicy(const std::string& account_id,
+ const enterprise_management::CloudPolicySettings& policy,
+ PolicyResponseCallback callback);
+
+ // Sends the device policy blob to SessionManager.
+ void StoreDevicePolicy(
+ const enterprise_management::ChromeDeviceSettingsProto& policy,
+ PolicyResponseCallback callback);
+
+ // Sends policy to SessionManager. Assumes |policy_blob| contains user policy
+ // if account_id is not nullptr, otherwise assumes it's device policy.
+ void StorePolicy(const std::string& policy_blob,
+ const std::string* account_id,
+ PolicyResponseCallback callback);
+
+ // Response callback from SessionManager, logs the result and calls callback.
+ void OnPolicyStored(const char* method, PolicyResponseCallback callback,
+ dbus::Response* response);
+
+ SambaInterface samba_;
+
+ brillo::dbus_utils::DBusObject dbus_object_;
+ dbus::ObjectProxy* session_manager_proxy_;
+ base::WeakPtrFactory<AuthPolicy> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AuthPolicy);
+};
+
+} // namespace authpolicy
+
+#endif // AUTHPOLICY_AUTHPOLICY_H_
diff --git a/authpolicy/authpolicy_main.cc b/authpolicy/authpolicy_main.cc
new file mode 100644
index 0000000..087051b
--- /dev/null
+++ b/authpolicy/authpolicy_main.cc
@@ -0,0 +1,73 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include <brillo/syslog_logging.h>
+#include <brillo/daemons/dbus_daemon.h>
+#include <chromeos/dbus/service_constants.h>
+#include <install_attributes/libinstallattributes.h>
+
+#include "authpolicy/authpolicy.h"
+
+namespace {
+
+const char kObjectServicePath[] = "/org/chromium/AuthPolicy/ObjectManager";
+
+} // namespace
+
+namespace authpolicy {
+
+class Daemon : public brillo::DBusServiceDaemon {
+ public:
+ Daemon() : DBusServiceDaemon(kAuthPolicyServiceName, kObjectServicePath) {}
+
+ protected:
+ void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
+ auth_policy_.reset(new AuthPolicy(object_manager_.get()));
+ auth_policy_->RegisterAsync(
+ sequencer->GetHandler("AuthPolicy.RegisterAsync() failed.", true));
+ }
+
+ void OnShutdown(int* return_code) override {
+ DBusServiceDaemon::OnShutdown(return_code);
+ auth_policy_.reset();
+ }
+
+ private:
+ std::unique_ptr<AuthPolicy> auth_policy_;
+
+ DISALLOW_COPY_AND_ASSIGN(Daemon);
+};
+
+} // namespace authpolicy
+
+int main(int argc, const char* const* argv) {
+ brillo::OpenLog("authpolicyd", true);
+ brillo::InitLog(brillo::kLogToSyslog);
+
+ // Safety check to ensure that authpolicyd cannot run after the device has
+ // been locked to a mode other than enterprise_ad. (The lifetime management
+ // of authpolicyd happens through upstart, this check only serves as a second
+ // line of defense.)
+ InstallAttributesReader install_attributes_reader;
+ if (install_attributes_reader.IsLocked()) {
+ const std::string& mode =
+ install_attributes_reader.GetAttribute(
+ InstallAttributesReader::kAttrMode);
+ if (mode != InstallAttributesReader::kDeviceModeEnterpriseAD) {
+ LOG(ERROR) << "OOBE completed but device not in AD management mode.";
+ // Exit with "success" to prevent respawn by upstart.
+ exit(0);
+ }
+ }
+
+ // Run daemon
+ LOG(INFO) << "authpolicyd starting";
+ authpolicy::Daemon daemon;
+ int res = daemon.Run();
+ LOG(INFO) << "authpolicyd stopping with exit code " << res;
+
+ return res;
+}
diff --git a/authpolicy/dbus_bindings/org.chromium.AuthPolicy.xml b/authpolicy/dbus_bindings/org.chromium.AuthPolicy.xml
index 660b88d..fb664ad 100644
--- a/authpolicy/dbus_bindings/org.chromium.AuthPolicy.xml
+++ b/authpolicy/dbus_bindings/org.chromium.AuthPolicy.xml
@@ -3,19 +3,64 @@
<node name="/org/chromium/AuthPolicy"
xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.chromium.AuthPolicy">
+ <!--
+ AuthenticateUser:
+ @user_principal_name: user@workgroup.domain.
+ @password_fd: File descriptor of the user's password.
+ @error_code: Returned error code, 0 means success.
+ @account_id: Returned unique account id of the user.
+
+ Authenticates the user with an Active Directory domain.
+ -->
<method name="AuthenticateUser">
<arg name="user_principal_name" type="s" direction="in"/>
<arg name="password_fd" type="h" direction="in"/>
- <arg name="code" type="i" direction="out"/>
+ <arg name="error_code" type="i" direction="out"/>
<arg name="account_id" type="s" direction="out" />
<annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
</method>
+
+ <!--
+ JoinADDomain:
+ @machine_name: Netbios name of the machine (aka device) to join.
+ @user_principal_name: user@workgroup.domain, used for authentication.
+ @password_fd: File descriptor of the user's password.
+ @error_code: Returned error code, 0 means success.
+
+ Joins the given machine with an Active Directory domain.
+ -->
<method name="JoinADDomain">
<arg name="machine_name" type="s" direction="in"/>
<arg name="user_principal_name" type="s" direction="in"/>
<arg name="password_fd" type="h" direction="in"/>
- <arg name="code" type="i" direction="out"/>
+ <arg name="error_code" type="i" direction="out"/>
<annotation name="org.chromium.DBus.Method.Kind" value="normal"/>
</method>
+
+ <!--
+ RefreshUserPolicy:
+ @account_id: Unique account id of the user to fetch policy for.
+ @error_code: Returned error code, 0 means success.
+
+ Retrieves user policy for the currently authenticated user and sends it
+ to Session Manager. Must be authenticated, see |AuthenticateUser|.
+ -->
+ <method name="RefreshUserPolicy">
+ <arg name="account_id" type="s" direction="in" />
+ <arg name="error_code" type="i" direction="out"/>
+ <annotation name="org.chromium.DBus.Method.Kind" value="async"/>
+ </method>
+
+ <!--
+ RefreshDevicePolicy:
+ @error_code: Returned error code, 0 means success.
+
+ Retrieves device policy and sends it to Session Manager. Must be joined
+ to an Active Directory domain, see |JoinADDomain|.
+ -->
+ <method name="RefreshDevicePolicy">
+ <arg name="error_code" type="i" direction="out"/>
+ <annotation name="org.chromium.DBus.Method.Kind" value="async"/>
+ </method>
</interface>
</node>
diff --git a/authpolicy/errors.cc b/authpolicy/errors.cc
index 22a392a..c9aa767 100644
--- a/authpolicy/errors.cc
+++ b/authpolicy/errors.cc
@@ -6,13 +6,30 @@
namespace errors {
-const char kAuthPolicy[] = "authpolicyd";
-const char kPreg[] = "preg_error";
-const char kAuth[] = "auth_error";
-const char kJoin[] = "join_error";
-const char kFetch[]= "fetch_error";
-const char kDownload[]= "download_error";
-const char kCmd[] = "cmd_error";
+const char kDomain[] = "authpolicyd";
+
+const char kCreateDirFailed[] = "create_dir_failed";
+const char kDownloadGpoFailed[] = "download_gpo_failed";
+const char kKInitFailed[] = "kinit_failed";
+const char kNetAdsGpoListFailed[] = "net_ads_gpo_list_failed";
+const char kNetAdsInfoFailed[] = "net_ads_info_failed";
+const char kNetAdsJoinFailed[] = "net_ads_join_failed";
+const char kNetAdsSearchFailed[] = "net_ads_search_failed";
+const char kNotLoggedIn[] = "not_logged_in";
+const char kParseGpoFailed[] = "parse_gpo_failed";
+const char kParseGpoPathFailed[] = "parse_gpo_path_failed";
+const char kParseNetAdsInfoFailed[] = "parse_net_ads_info_failed";
+const char kParseNetAdsSearchFailed[] = "parse_net_ads_search_failed";
+const char kParseSmbConfFailed[] = "parse_smb_conf_failed";
+const char kParseUPNFailed[] = "parse_upn_failed";
+const char kPregFileNotFound[] = "preg_file_not_found";
+const char kPregParseError[] = "preg_parse_error";
+const char kPregReadError[] = "preg_error";
+const char kPregTooBig[] = "preg_too_big";
+const char kReadSmbConfFailed[] = "read_smb_conf_failed";
+const char kSmbClientFailed[] = "smd_client_failed";
+const char kStorePolicyFailed[] = "store_policy_failed";
+const char kWriteSmbConfFailed[] = "write_smb_conf_failed";
} // namespace errors
diff --git a/authpolicy/errors.h b/authpolicy/errors.h
index edf4ef1..17a2b03 100644
--- a/authpolicy/errors.h
+++ b/authpolicy/errors.h
@@ -8,15 +8,32 @@
namespace errors {
// Brillo error domain, see brillo::Error.
-extern const char kAuthPolicy[];
+extern const char kDomain[];
// Brillo error codes, see brillo::Error.
-extern const char kPreg[]; // PReg parser error.
-extern const char kAuth[]; // Error authenticating.
-extern const char kJoin[]; // Error joining the AD domain.
-extern const char kFetch[]; // Error fetching policy.
-extern const char kDownload[]; // Error downloading GPO.
-extern const char kCmd[]; // Error executing a command.
+extern const char kCreateDirFailed[]; // Failed to create a directory.
+extern const char kDownloadGpoFailed[]; // Failed to download GPO.
+extern const char kKInitFailed[]; // Error authenticating.
+extern const char kNetAdsGpoListFailed[]; // Getting GPO list failed.
+extern const char kNetAdsInfoFailed[]; // Getting DC name failed.
+extern const char kNetAdsJoinFailed[]; // Joining machine to AD failed.
+extern const char kNetAdsSearchFailed[]; // Getting account id failed.
+extern const char kNotLoggedIn[]; // Can't fetch GPOs, not logged in.
+extern const char kParseGpoFailed[]; // Can't parse gpo list result.
+extern const char kParseGpoPathFailed[]; // Failed to parse GPO filesyspath.
+extern const char kParseNetAdsInfoFailed[]; // Can't parse DC name info.
+extern const char
+ kParseNetAdsSearchFailed[]; // Can't parse account id info.
+extern const char kParseSmbConfFailed[]; // Failed to parse samba conf file.
+extern const char kParseUPNFailed[]; // Can't parse user principal name.
+extern const char kPregFileNotFound[]; // Preg file path does not exist.
+extern const char kPregParseError[]; // Failed to parse a preg file.
+extern const char kPregReadError[]; // Failed to load a preg file.
+extern const char kPregTooBig[]; // Preg file was too big.
+extern const char kReadSmbConfFailed[]; // Failed to read samba conf file.
+extern const char kSmbClientFailed[]; // Downloading GPOs failed.
+extern const char kStorePolicyFailed[]; // Can't send to Session Manager.
+extern const char kWriteSmbConfFailed[]; // Failed to write samba conf file.
} // namespace errors
diff --git a/authpolicy/etc/dbus-1/org.chromium.AuthPolicy.conf b/authpolicy/etc/dbus-1/org.chromium.AuthPolicy.conf
index 2273031..e7fcf7d 100644
--- a/authpolicy/etc/dbus-1/org.chromium.AuthPolicy.conf
+++ b/authpolicy/etc/dbus-1/org.chromium.AuthPolicy.conf
@@ -18,5 +18,11 @@
<allow send_destination="org.chromium.AuthPolicy"
send_interface="org.chromium.AuthPolicy"
send_member="JoinADDomain"/>
+ <allow send_destination="org.chromium.AuthPolicy"
+ send_interface="org.chromium.AuthPolicy"
+ send_member="RefreshUserPolicy"/>
+ <allow send_destination="org.chromium.AuthPolicy"
+ send_interface="org.chromium.AuthPolicy"
+ send_member="RefreshDevicePolicy"/>
</policy>
</busconfig>
diff --git a/authpolicy/policy/policy_encoder_helper.cc b/authpolicy/policy/policy_encoder_helper.cc
index 639c6e2..a6d5c9a 100644
--- a/authpolicy/policy/policy_encoder_helper.cc
+++ b/authpolicy/policy/policy_encoder_helper.cc
@@ -44,18 +44,16 @@
namespace helper {
bool LoadPRegFile(const base::FilePath& preg_file,
- brillo::ErrorPtr* error,
- RegistryDict* dict) {
- // Report the error if the preg file does not exist.
+ RegistryDict* out_dict,
+ const char** out_error_code) {
if (!base::PathExists(preg_file)) {
- brillo::Error::AddToPrintf(error, FROM_HERE, errors::kAuthPolicy,
- errors::kPreg, "PReg file doesn't exist: %s",
- preg_file.value().c_str());
+ LOG(ERROR) << "PReg file " << preg_file.value() << " does not exist";
+ *out_error_code = errors::kPregFileNotFound;
return false;
}
- // Load the file.
- return preg_parser::ReadFile(preg_file, kRegistryKey, dict, error);
+ return preg_parser::ReadFile(preg_file, kRegistryKey, out_dict,
+ out_error_code);
}
bool GetAsBoolean(const base::Value* value, bool* bool_value) {
diff --git a/authpolicy/policy/policy_encoder_helper.h b/authpolicy/policy/policy_encoder_helper.h
index 0a73d42..e8192fb 100644
--- a/authpolicy/policy/policy_encoder_helper.h
+++ b/authpolicy/policy/policy_encoder_helper.h
@@ -8,7 +8,6 @@
#include <string>
#include "base/values.h"
-#include "brillo/errors/error.h"
namespace base {
class FilePath;
@@ -22,8 +21,8 @@
// Checks a PReg file for existence and loads it into |dict|.
bool LoadPRegFile(const base::FilePath& preg_file,
- brillo::ErrorPtr* error,
- RegistryDict* dict);
+ RegistryDict* out_dict,
+ const char** out_error_code);
// Similar to base::Value::GetAsBoolean(), but in addition it converts int
// values of 0 or 1 to bool. Returns true on success and stores the output in
diff --git a/authpolicy/policy/preg_parser.cc b/authpolicy/policy/preg_parser.cc
index 6a137b9..722a684 100644
--- a/authpolicy/policy/preg_parser.cc
+++ b/authpolicy/policy/preg_parser.cc
@@ -248,20 +248,18 @@
bool ReadFile(const base::FilePath& file_path,
const base::string16& root,
RegistryDict* dict,
- brillo::ErrorPtr* error) {
+ const char** out_error_code) {
base::MemoryMappedFile mapped_file;
if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) {
- PLOG(ERROR) << "Failed to map ";
- brillo::Error::AddToPrintf(error, FROM_HERE, errors::kAuthPolicy,
- errors::kPreg, "Failed to map PReg file %s",
- file_path.value().c_str());
+ PLOG(ERROR) << "Failed to map " << file_path.value();
+ *out_error_code = errors::kPregReadError;
return false;
}
if (mapped_file.length() > kMaxPRegFileSize) {
- brillo::Error::AddToPrintf(error, FROM_HERE, errors::kAuthPolicy,
- errors::kPreg, "PReg file %s too large: %zu",
- file_path.value().c_str(), mapped_file.length());
+ LOG(ERROR) << "PReg file " << file_path.value() << " too large: "
+ << mapped_file.length();
+ *out_error_code = errors::kPregTooBig;
return false;
}
@@ -269,9 +267,8 @@
const int kHeaderSize = arraysize(kPRegFileHeader);
if (mapped_file.length() < kHeaderSize ||
memcmp(kPRegFileHeader, mapped_file.data(), kHeaderSize) != 0) {
- brillo::Error::AddToPrintf(error, FROM_HERE, errors::kAuthPolicy,
- errors::kPreg, "Bad PReg file %s",
- file_path.value().c_str());
+ LOG(ERROR) << "Bad policy file " << file_path.value();
+ *out_error_code = errors::kPregParseError;
return false;
}
@@ -333,10 +330,10 @@
HandleRecord(key_name.substr(root.size()), value, type, data, dict);
}
- brillo::Error::AddToPrintf(
- error, FROM_HERE, errors::kAuthPolicy, errors::kPreg,
- "Error parsing %s at offset %zu", file_path.value().c_str(),
- reinterpret_cast<const uint8_t*>(cursor - 1) - mapped_file.data());
+ LOG(ERROR) << "Error parsing " << file_path.value() << " at offset "
+ << reinterpret_cast<const uint8_t*>(cursor - 1) -
+ mapped_file.data();
+ *out_error_code = errors::kPregParseError;
return false;
}
diff --git a/authpolicy/policy/preg_parser.h b/authpolicy/policy/preg_parser.h
index 4be5e6b..528ac74 100644
--- a/authpolicy/policy/preg_parser.h
+++ b/authpolicy/policy/preg_parser.h
@@ -14,7 +14,6 @@
#define AUTHPOLICY_POLICY_PREG_PARSER_H_
#include "base/strings/string16.h"
-#include "brillo/errors/error.h"
namespace base {
class FilePath;
@@ -32,7 +31,7 @@
bool ReadFile(const base::FilePath& file_path,
const base::string16& root,
RegistryDict* dict,
- brillo::ErrorPtr* error);
+ const char** out_error_code);
} // namespace preg_parser
} // namespace policy
diff --git a/authpolicy/policy/preg_policy_encoder.cc b/authpolicy/policy/preg_policy_encoder.cc
index 928ac91..e5c6a9c 100644
--- a/authpolicy/policy/preg_policy_encoder.cc
+++ b/authpolicy/policy/preg_policy_encoder.cc
@@ -11,7 +11,6 @@
#include "authpolicy/policy/device_policy_encoder.h"
#include "authpolicy/policy/policy_encoder_helper.h"
-#include "authpolicy/policy/proto/cloud_policy.pb.h"
#include "authpolicy/policy/registry_dict.h"
#include "authpolicy/policy/user_policy_encoder.h"
@@ -26,15 +25,15 @@
namespace policy {
bool ParsePRegFilesIntoUserPolicy(const std::vector<base::FilePath>& preg_files,
- brillo::ErrorPtr* error,
- em::CloudPolicySettings* policy) {
+ em::CloudPolicySettings* policy,
+ const char** out_error_code) {
DCHECK(policy);
RegistryDict merged_mandatory_dict;
RegistryDict merged_recommended_dict;
for (const base::FilePath& preg_file : preg_files) {
RegistryDict mandatory_dict;
- if (!helper::LoadPRegFile(preg_file, error, &mandatory_dict))
+ if (!helper::LoadPRegFile(preg_file, &mandatory_dict, out_error_code))
return false;
// Recommended policies are stored in their own registry key. This can be
@@ -65,13 +64,13 @@
bool ParsePRegFilesIntoDevicePolicy(
const std::vector<base::FilePath>& preg_files,
- brillo::ErrorPtr* error,
- em::ChromeDeviceSettingsProto* policy) {
+ em::ChromeDeviceSettingsProto* policy,
+ const char** out_error_code) {
DCHECK(policy);
RegistryDict policy_dict;
for (const base::FilePath& preg_file : preg_files) {
- if (!helper::LoadPRegFile(preg_file, error, &policy_dict))
+ if (!helper::LoadPRegFile(preg_file, &policy_dict, out_error_code))
return false;
}
diff --git a/authpolicy/policy/preg_policy_encoder.h b/authpolicy/policy/preg_policy_encoder.h
index 75ba0a7..6f7c0a4 100644
--- a/authpolicy/policy/preg_policy_encoder.h
+++ b/authpolicy/policy/preg_policy_encoder.h
@@ -31,8 +31,8 @@
// even though f3 has the higher index.
bool ParsePRegFilesIntoUserPolicy(
const std::vector<base::FilePath>& preg_files,
- brillo::ErrorPtr* error,
- enterprise_management::CloudPolicySettings* policy);
+ enterprise_management::CloudPolicySettings* policy,
+ const char** out_error_code);
// Loads the given set of |preg_files| and encodes all device policies into the
// given |policy| blob. If multiple files f1,...,fN are passed in, policies
@@ -40,8 +40,8 @@
// - Policies in fn overwrite policies in fm if n > m.
bool ParsePRegFilesIntoDevicePolicy(
const std::vector<base::FilePath>& preg_files,
- brillo::ErrorPtr* error,
- enterprise_management::ChromeDeviceSettingsProto* policy);
+ enterprise_management::ChromeDeviceSettingsProto* policy,
+ const char** out_error_code);
} // namespace policy
diff --git a/authpolicy/samba_interface.h b/authpolicy/samba_interface.h
new file mode 100644
index 0000000..fb9ce2b
--- /dev/null
+++ b/authpolicy/samba_interface.h
@@ -0,0 +1,69 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AUTHPOLICY_SAMBA_INTERFACE_H_
+#define AUTHPOLICY_SAMBA_INTERFACE_H_
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "base/files/file_path.h"
+
+// Helper methods for samba AD authentication, machine (device) joining and
+// policy fetching. Note: "Device" and "machine" can be used interchangably
+// here.
+
+namespace authpolicy {
+
+class SambaInterface {
+ public:
+ // STUB CODE, TO BE FILLED.
+
+ // Calls kinit to get a Kerberos ticket-granting-ticket (TGT) for the given
+ // |user_principal_name| (format: user_name@workgroup.domain). If a TGT
+ // already exists, it is renewed. The password must be readable from the pipe
+ // referenced by the file descriptor |password_fd|. On success, the user's
+ // object GUID is returned in |out_account_id|. The GUID uniquely identifies
+ // the user's account.
+ bool AuthenticateUser(const std::string& user_principal_name, int password_fd,
+ std::string* out_account_id,
+ const char** out_error_code) {
+ return false;
+ }
+
+ // Joins the local device with name |machine_name| to an AD domain. A user
+ // principal name and password are required for authentication (see
+ // |AuthenticateUser| for details).
+ bool JoinMachine(const std::string& machine_name,
+ const std::string& user_principal_name, int password_fd,
+ const char** out_error_code) {
+ return false;
+ }
+
+ // Downloads user policy files from the AD server. |account_id| is the unique
+ // user GUID returned from |AuthenticateUser|. The user's Kerberos
+ // authentication ticket must still be valid. If this operation fails, call
+ // |AuthenticateUser| and try again. User policy is given as Registry.pol
+ // (preg) files, a binary format encoding policy data.
+ bool FetchUserGpos(const std::string& account_id,
+ std::vector<base::FilePath>* out_gpo_file_paths,
+ const char** out_error_code) {
+ return false;
+ }
+
+ // Downloads device policy files from the AD server. The device must be joined
+ // to the AD domain already (see |JoinMachine|). During join, a machine
+ // password is stored in a keytab file, which is used for authentication for
+ // policy fetch. Device policy is given as Registry.pol (preg) files, a binary
+ // format encoding policy data.
+ bool FetchDeviceGpos(std::vector<base::FilePath>* out_gpo_file_paths,
+ const char** out_error_code) {
+ return false;
+ }
+};
+
+} // namespace authpolicy
+
+#endif // AUTHPOLICY_SAMBA_INTERFACE_H_