blob: f03923ace77375b73458a070db2652e23f2120b8 [file] [log] [blame]
// 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 <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <dbus/authpolicy/dbus-constants.h>
#include "authpolicy/authpolicy_metrics.h"
#include "authpolicy/constants.h"
#include "authpolicy/path_service.h"
#include "bindings/authpolicy_containers.pb.h"
// Helper methods for Samba Active Directory authentication, machine (device)
// joining and policy fetching. Note: "Device" and "machine" can be used
// interchangably here.
namespace authpolicy {
class AuthPolicyMetrics;
class PathService;
class ProcessExecutor;
class SambaInterface {
public:
SambaInterface(AuthPolicyMetrics* metrics,
std::unique_ptr<PathService> path_service);
// Creates directories required by Samba code and loads configuration, if it
// exists. Also loads the debug flags file. Returns error
// - if a directory failed to create or
// - if |expect_config| is true and the config file fails to load.
ErrorType Initialize(bool expect_config);
// 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
// account information is returned in |account_info|.
ErrorType AuthenticateUser(const std::string& user_principal_name,
int password_fd,
protos::AccountInfo* account_info);
// Joins the local device with name |machine_name| to an Active Directory
// domain. A user principal name and password are required for authentication
// (see |AuthenticateUser| for details).
ErrorType JoinMachine(const std::string& machine_name,
const std::string& user_principal_name,
int password_fd);
// Downloads user policy from the Active Directory server and stores it in a
// serialized user policy protobuf string (see |CloudPolicySettings|).
// |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.
ErrorType FetchUserGpos(const std::string& account_id,
std::string* policy_blob);
// Downloads device policy from the Active Directory server and stores it in a
// serialized device policy protobuf string (see |ChromeDeviceSettingsProto|).
// The device must be joined to the Active Directory domain already (see
// |JoinMachine|). During join, a machine password is stored in a keytab file,
// which is used for authentication for policy fetch.
ErrorType FetchDeviceGpos(std::string* policy_blob);
private:
// Sets up minijail and executes |cmd|. |seccomp_path_key| specifies the path
// of the seccomp filter to use. |timer_type| is the UMA timer metric to
// report. Passing |TIMER_NONE| won't report anything.
bool SetupJailAndRun(ProcessExecutor* cmd,
Path seccomp_path_key,
TimerType timer_type) const;
// Sets up trace logging for kinit.
void SetupKinitTrace(ProcessExecutor* kinit_cmd) const;
// Prints out the trace log of kinit.
void OutputKinitTrace() const;
// Retrieves the name of the domain controller (DC) and the IP of the key
// distribution center (KDC). If the full server name is 'server.realm', the
// DC name is set to 'server'. The DC name is required for proper kerberized
// authentication. The KDC address is required to speed up network
// communication and get rid of waiting for the machine account propagation
// after Active Directory domain join.
ErrorType GetRealmInfo(protos::RealmInfo* realm_info) const;
// Retrieves the name of the workgroup. Since the workgroup is expected to
// change very rarely, this function earlies out and returns ERROR_NONE if the
// workgroup has already been fetched.
ErrorType EnsureWorkgroup();
// Writes the Samba configuration file.
ErrorType WriteSmbConf() const;
// Writes the Samba configuration file. If |workgroup_| is empty, the
// workgroup is queried from the server and the string is updated. Workgroups
// are only queried once a session, they are expected to change very rarely.
ErrorType EnsureWorkgroupAndWriteSmbConf();
// Writes the krb5 configuration file.
ErrorType WriteKrb5Conf(const std::string& realm,
const std::string& kdc_ip) const;
// Writes the file with configuration information.
ErrorType WriteConfiguration() const;
// Reads the file with configuration information.
ErrorType ReadConfiguration();
// Copies the machine keytab file to the state directory. The copy is owned by
// authpolicyd, so that authpolicyd_exec cannot modify it anymore.
ErrorType SecureMachineKeyTab() const;
// Calls net ads search with given |search_string| to retrieve account info.
ErrorType GetAccountInfo(const std::string& search_string,
protos::AccountInfo* account_info) const;
// Calls net ads gpo list to retrieve a list of GPOs. |user_or_machine_name|
// may be a user or machine sAMAccountName. (The machine sAMAccountName is the
// machine name postfixed with '$').
ErrorType GetGpoList(const std::string& user_or_machine_name,
PolicyScope scope,
protos::GpoList* gpo_list) const;
// Downloads user or device GPOs in the given |gpo_list|. |scope| determines
// a sub-folder where GPOs are downloaded to. It should match |scope| from
// |GetGpoList|.
ErrorType DownloadGpos(const protos::GpoList& gpo_list,
const std::string& domain_controller_name,
PolicyScope scope,
std::vector<base::FilePath>* gpo_file_paths) const;
// Parses GPOs and stores them in user/device policy protobufs.
ErrorType ParseGposIntoProtobuf(
const std::vector<base::FilePath>& gpo_file_paths,
const char* parser_cmd_string,
std::string* policy_blob) const;
// Resets internal state to an 'unenrolled' state by wiping configuration and
// user data.
void Reset();
// Maps the account id key ("a-" + user object GUID) to sAMAccountName.
std::unordered_map<std::string, std::string> user_id_name_map_;
std::unique_ptr<protos::ActiveDirectoryConfig> config_;
std::string workgroup_;
// Whether kinit calls may return false negatives and must be retried.
bool retry_machine_kinit_ = false;
// Debug flags.
bool disable_seccomp_filters_ = false;
bool log_seccomp_filters_ = false;
bool trace_kinit_ = false;
// UMA statistics, not owned.
AuthPolicyMetrics* metrics_;
// Lookup for file paths.
std::unique_ptr<PathService> paths_;
DISALLOW_COPY_AND_ASSIGN(SambaInterface);
};
} // namespace authpolicy
#endif // AUTHPOLICY_SAMBA_INTERFACE_H_