| // Copyright 2017 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 SMBPROVIDER_SMBPROVIDER_H_ |
| #define SMBPROVIDER_SMBPROVIDER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include <base/memory/weak_ptr.h> |
| #include <dbus_adaptors/org.chromium.SmbProvider.h> |
| |
| #include "smbprovider/proto.h" |
| #include "smbprovider/proto_bindings/directory_entry.pb.h" |
| #include "smbprovider/smbprovider_helper.h" |
| #include "smbprovider/temp_file_manager.h" |
| |
| using brillo::dbus_utils::AsyncEventSequencer; |
| |
| namespace smbprovider { |
| |
| class DirectoryEntryListProto; |
| class DirectoryIterator; |
| class MountManager; |
| class PostDepthFirstIterator; |
| class SambaInterface; |
| |
| // Implementation of smbprovider's DBus interface. Mostly routes stuff between |
| // DBus and samba_interface. |
| class SmbProvider : public org::chromium::SmbProviderAdaptor, |
| public org::chromium::SmbProviderInterface { |
| public: |
| SmbProvider(std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object, |
| std::unique_ptr<SambaInterface> samba_interface, |
| std::unique_ptr<MountManager> mount_manager, |
| size_t buffer_size); |
| |
| SmbProvider(std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object, |
| std::unique_ptr<SambaInterface> samba_interface, |
| std::unique_ptr<MountManager> mount_manager); |
| |
| // org::chromium::SmbProviderInterface: (see org.chromium.SmbProvider.xml). |
| void Mount(const ProtoBlob& options_blob, |
| int32_t* error_code, |
| int32_t* mount_id) override; |
| |
| int32_t Unmount(const ProtoBlob& options_blob) override; |
| |
| void ReadDirectory(const ProtoBlob& options_blob, |
| int32_t* error_code, |
| ProtoBlob* out_entries) override; |
| |
| void GetMetadataEntry(const ProtoBlob& options_blob, |
| int32_t* error_code, |
| ProtoBlob* out_entry) override; |
| |
| void OpenFile(const ProtoBlob& options_blob, |
| int32_t* error_code, |
| int32_t* file_id) override; |
| |
| int32_t CloseFile(const ProtoBlob& options_blob) override; |
| |
| int32_t DeleteEntry(const ProtoBlob& options_blob) override; |
| |
| void ReadFile(const ProtoBlob& options_blob, |
| int32_t* error_code, |
| dbus::FileDescriptor* temp_fd) override; |
| |
| int32_t CreateFile(const ProtoBlob& options_blob) override; |
| |
| int32_t Truncate(const ProtoBlob& options_blob) override; |
| |
| int32_t WriteFile(const ProtoBlob& options_blob, |
| const dbus::FileDescriptor& temp_fd) override; |
| |
| int32_t CreateDirectory(const ProtoBlob& options_blob) override; |
| |
| int32_t MoveEntry(const ProtoBlob& options_blob) override; |
| |
| int32_t CopyEntry(const ProtoBlob& options_blob) override; |
| |
| // Register DBus object and interfaces. |
| void RegisterAsync( |
| const AsyncEventSequencer::CompletionAction& completion_callback); |
| |
| private: |
| // Uses |options| to create the full path based on the mount id and entry path |
| // supplied in |options|. |full_path| will be unmodified on failure. |
| template <typename Proto> |
| bool GetFullPath(Proto* options, std::string* full_path) const; |
| |
| // Uses |options| to create the source and target paths based on the mount id, |
| // source path and target path supplied in |options|. |source_full_path| and |
| // |target_full_path| will be unmodified on failure. |
| template <typename Proto> |
| bool GetFullPaths(Proto* options, |
| std::string* source_full_path, |
| std::string* target_full_path) const; |
| |
| // Parses the raw contents of |blob| into |options| and validates that |
| // the required fields are all correctly set. |
| // |full_path| will contain the full path, including the mount root, based |
| // on the mount id and entry path supplied in |options|. |
| // On failure |error_code| will be populated and |options| and |full_path| |
| // are undefined. |
| template <typename Proto> |
| bool ParseOptionsAndPath(const ProtoBlob& blob, |
| Proto* options, |
| std::string* full_path, |
| int32_t* error_code); |
| |
| // Variation of ParseOptionsAndPath. |source_path| and |target_path| will |
| // contain full paths, including the mount root, based on the mount id and |
| // paths supplied in |options|. |
| template <typename Proto> |
| bool ParseOptionsAndPaths(const ProtoBlob& blob, |
| Proto* options, |
| std::string* source_path, |
| std::string* target_path, |
| int32_t* error_code); |
| |
| // Tests whether |mount_root| is a valid path to be mounted by attemping |
| // to open the directory. |
| bool CanMountPath(const std::string& mount_root, int32_t* error_code); |
| |
| // Helper method to get the type of an entry. Returns boolean indicating |
| // success. Sets is_directory to true for directory, and false for file. |
| // Fails when called on non-file, non-directory. |
| // On failure, returns false and sets |error_code|. |
| bool GetEntryType(const std::string& full_path, |
| int32_t* error_code, |
| bool* is_directory); |
| |
| // Helper method to close the directory with id |dir_id|. Logs an error if the |
| // directory fails to close. |
| void CloseDirectory(int32_t dir_id); |
| |
| // Removes |mount_id| from the |mount_manager_| object and sets |error_code| |
| // on failure. |
| bool RemoveMount(int32_t mount_id, int32_t* error_code); |
| |
| // Helper method to read a file with valid |options| and output the results |
| // into a |buffer|. This sets |error_code| on failure. |
| bool ReadFileIntoBuffer(const ReadFileOptionsProto& options, |
| int32_t* error_code, |
| std::vector<uint8_t>* buffer); |
| |
| // Helper method to write data from a |buffer| into a temporary file and |
| // outputs the resulting file descriptor into |temp_fd|. |options| is used for |
| // logging purposes. This sets |error_code| on failure. |
| bool WriteTempFile(const ReadFileOptionsProto& options, |
| const std::vector<uint8_t>& buffer, |
| int32_t* error_code, |
| dbus::FileDescriptor* temp_fd); |
| |
| // Helper method to write data from a |buffer| into a file specified by |
| // |file_id|. |options| is used for logging. Returns true on success, and sets |
| // |error_code| on failure. |
| template <typename Proto> |
| bool WriteFileFromBuffer(const Proto& options, |
| int32_t file_id, |
| const std::vector<uint8_t>& buffer, |
| int32_t* error_code); |
| |
| // Moves an entry at |source_path| to |target_path|. |options| is used for |
| // logging. Returns true on success. Sets |error| and returns false on |
| // failure. |
| bool MoveEntry(const MoveEntryOptionsProto& options, |
| const std::string& source_path, |
| const std::string& target_path, |
| int32_t* error); |
| |
| // Calls delete on the contents of |dir_path| via postorder traversal. |
| // RecursiveDelete exits and returns error if an entry cannot be deleted |
| // or there was a Samba error iterating over entries. |
| int32_t RecursiveDelete(const std::string& dir_path); |
| |
| // Calls delete on a DirectoryEntry. Returns the result from either DeleteFile |
| // or DeleteDirectory. |
| int32_t DeleteDirectoryEntry(const DirectoryEntry& entry); |
| |
| // Calls Unlink. |
| int32_t DeleteFile(const std::string& file_path); |
| |
| // Calls RemoveDirectory. |
| int32_t DeleteDirectory(const std::string& dir_path); |
| |
| // Helper method to construct a DirectoryIterator for a given |full_path|. |
| DirectoryIterator GetDirectoryIterator(const std::string& full_path); |
| |
| // Helper method to construct a PostDepthFirstIterator for a given |
| // |full_path|. |
| PostDepthFirstIterator GetPostOrderIterator(const std::string& full_path); |
| |
| // Opens a file located at |full_path| with permissions based on the protobuf. |
| // |file_id| is the file handle for the opened file, and error will be set on |
| // failure. |options| is used for permissions and logging. |
| // GetOpenFilePermissions must be overloaded to new protobufs using this |
| // method. Returns true on success. |
| template <typename Proto> |
| bool OpenFile(const Proto& options, |
| const std::string& full_path, |
| int32_t* error, |
| int32_t* file_id); |
| |
| // Closes a file with handle |file_id|. |options| is used for logging |
| // purposes. |error| is set on failure. Returns true on success. |
| template <typename Proto> |
| bool CloseFile(const Proto& options, int32_t file_id, int32_t* error); |
| |
| // Truncates a file with handle |file_id| to the desired |length| and closes |
| // the file whether or not the truncate was successful. |options| is used for |
| // logging purposes. |error| is set on failure. Returns true on success. |
| template <typename Proto> |
| bool TruncateAndCloseFile(const Proto& options, |
| int32_t file_id, |
| int64_t length, |
| int32_t* error); |
| |
| // Helper method to seek given a proto |options|. |
| // On failure |error_code| will be populated. |
| template <typename Proto> |
| bool Seek(const Proto& options, int32_t* error_code); |
| |
| // Creates the parent directories based on |options| if necessary. This call |
| // will return true if no directories need to be created. Returns true on |
| // success and sets |error_code| on failure. |
| bool CreateParentsIfNecessary(const CreateDirectoryOptionsProto& options, |
| int32_t* error_code); |
| |
| // Helper method to create nested directories in |paths|. |paths| must be a |
| // successive hierarchy of directories starting from the top-most parent. This |
| // will succeed even if all the directories in |paths| already exists. |
| // |options| is used for logging purposes. Returns true on success and sets |
| // |error_code| on failure. |
| bool CreateNestedDirectories(const CreateDirectoryOptionsProto& options, |
| const std::vector<std::string>& paths, |
| int32_t* error_code); |
| |
| // Helper method to create a single directory at |full_path|. |options| is |
| // used for logging purposes. If |ignore_existing| is true, this will ignore |
| // EEXIST errors. Returns true on success and sets |error_code| on failure. |
| template <typename Proto> |
| bool CreateSingleDirectory(const Proto& options, |
| const std::string& full_path, |
| bool ignore_existing, |
| int32_t* error_code); |
| |
| // Generates a vector of |parent_paths| from a directory path in |options|. |
| // The path must be prefixed with "/". |parent_paths| will include the mount |
| // root and will exclude the path in |options|. Passing in "/1/2/3" will |
| // generate ["smb://{mount}/1", "smb://{mount}/1/2"]. If the path has no |
| // parents aside from "/", no paths will be generated. Returns true on success |
| // and sets |error_code| on failure. |
| bool GenerateParentPaths(const CreateDirectoryOptionsProto& options, |
| int32_t* error_code, |
| std::vector<std::string>* parent_paths); |
| |
| // Creates a file at |full_path|. Sets |file_id| to fd of newly created file. |
| // Returns false and sets |error| on failure. |options| is used for |
| template <typename Proto> |
| bool CreateFile(const Proto& options, |
| const std::string& full_path, |
| int32_t* file_id, |
| int32_t* error); |
| |
| // Copies the entry at |source_path| to |target_path|. Returns true on |
| // success. Returns false and sets |error_code| on failure. |
| bool CopyEntry(const CopyEntryOptionsProto& options, |
| const std::string& source_path, |
| const std::string& target_path, |
| int32_t* error_code); |
| |
| // Copies the file at |source_path| to a created file at |target_path|. |
| // Returns true on success. Returns false and sets |error_code| on failure. |
| bool CopyFile(const CopyEntryOptionsProto& options, |
| const std::string& source_path, |
| const std::string& target_path, |
| int32_t* error_code); |
| |
| // Copies the data at open file |source_fd| to open file |target_fd|. Returns |
| // true on success. Returns false and sets |error_code| on failure. |
| bool CopyData(const CopyEntryOptionsProto& options, |
| int32_t source_fd, |
| int32_t target_fd, |
| int32_t* error_code); |
| |
| // Helper method that fills |buffer| by reading the file with handle |
| // |file_id|. Returns true and sets |bytes_read| on success. Returns false and |
| // sets |error_code| on failure. |options| is used for logging. |
| template <typename Proto> |
| bool ReadToBuffer(const Proto& options, |
| int32_t file_id, |
| std::vector<uint8_t>* buffer, |
| size_t* bytes_read, |
| int32_t* error_code); |
| |
| std::unique_ptr<SambaInterface> samba_interface_; |
| std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_; |
| std::unique_ptr<MountManager> mount_manager_; |
| TempFileManager temp_file_manager_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SmbProvider); |
| }; |
| |
| } // namespace smbprovider |
| |
| #endif // SMBPROVIDER_SMBPROVIDER_H_ |