2014-03-14 20:03:11 +00:00
|
|
|
require "digest/md5"
|
2014-02-26 23:54:53 +00:00
|
|
|
require "json"
|
|
|
|
|
|
|
|
require "log4r"
|
|
|
|
|
|
|
|
require "vagrant/util/platform"
|
|
|
|
require "vagrant/util/powershell"
|
|
|
|
|
2017-12-21 00:26:27 +00:00
|
|
|
require_relative "errors"
|
|
|
|
|
2014-02-26 23:54:53 +00:00
|
|
|
module VagrantPlugins
|
|
|
|
module SyncedFolderSMB
|
|
|
|
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
2018-01-13 00:43:19 +00:00
|
|
|
|
|
|
|
# Maximum number of times to retry requesting username/password
|
|
|
|
CREDENTIAL_RETRY_MAX = 5
|
|
|
|
|
2014-02-26 23:54:53 +00:00
|
|
|
def initialize(*args)
|
|
|
|
super
|
|
|
|
|
|
|
|
@logger = Log4r::Logger.new("vagrant::synced_folders::smb")
|
|
|
|
end
|
|
|
|
|
|
|
|
def usable?(machine, raise_error=false)
|
2017-12-16 00:31:44 +00:00
|
|
|
# If the machine explicitly states SMB is not supported, then
|
|
|
|
# believe it
|
|
|
|
return false if !machine.config.smb.functional
|
|
|
|
return true if machine.env.host.capability?(:smb_installed) &&
|
|
|
|
machine.env.host.capability(:smb_installed)
|
|
|
|
return false if !raise_error
|
2017-12-21 00:26:27 +00:00
|
|
|
raise Errors::SMBNotSupported
|
2014-02-26 23:54:53 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def prepare(machine, folders, opts)
|
2014-03-06 16:49:41 +00:00
|
|
|
machine.ui.output(I18n.t("vagrant_sf_smb.preparing"))
|
|
|
|
|
2017-12-16 00:31:44 +00:00
|
|
|
smb_username = smb_password = nil
|
2014-02-26 23:54:53 +00:00
|
|
|
|
2014-03-06 16:49:41 +00:00
|
|
|
# If we need auth information, then ask the user.
|
2014-10-21 05:05:56 +00:00
|
|
|
have_auth = false
|
2014-03-06 16:49:41 +00:00
|
|
|
folders.each do |id, data|
|
2014-10-21 05:05:56 +00:00
|
|
|
if data[:smb_username] && data[:smb_password]
|
2017-12-16 00:31:44 +00:00
|
|
|
smb_username = data[:smb_username]
|
|
|
|
smb_password = data[:smb_password]
|
2014-10-21 05:05:56 +00:00
|
|
|
have_auth = true
|
2014-03-06 16:49:41 +00:00
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-21 05:05:56 +00:00
|
|
|
if !have_auth
|
2017-12-08 05:24:22 +00:00
|
|
|
machine.ui.detail(I18n.t("vagrant_sf_smb.warning_password") + "\n ")
|
2018-01-13 00:43:19 +00:00
|
|
|
retries = 0
|
|
|
|
while retries < CREDENTIAL_RETRY_MAX do
|
|
|
|
smb_username = machine.ui.ask("Username: ")
|
|
|
|
smb_password = machine.ui.ask("Password (will be hidden): ", echo: false)
|
|
|
|
auth_success = true
|
|
|
|
|
|
|
|
if machine.env.host.capability?(:smb_validate_password)
|
|
|
|
Vagrant::Util::CredentialScrubber.sensitive(smb_password)
|
|
|
|
auth_success = machine.env.host.capability(:smb_validate_password,
|
|
|
|
smb_username, smb_password)
|
2017-12-08 05:24:22 +00:00
|
|
|
end
|
|
|
|
|
2018-01-13 00:43:19 +00:00
|
|
|
break if auth_success
|
|
|
|
machine.ui.output(I18n.t("vagrant_sf_smb.incorrect_credentials") + "\n ")
|
|
|
|
retries += 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if retries >= CREDENTIAL_RETRY_MAX
|
|
|
|
raise Errors::CredentialsRequestError
|
2017-12-08 05:24:22 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Check if this host can start and SMB service
|
|
|
|
if machine.env.host.capability?(:smb_start)
|
|
|
|
machine.env.host.capability(:smb_start)
|
2014-03-06 16:49:41 +00:00
|
|
|
end
|
|
|
|
|
2014-02-26 23:54:53 +00:00
|
|
|
folders.each do |id, data|
|
2017-12-16 00:31:44 +00:00
|
|
|
data[:smb_username] ||= smb_username
|
|
|
|
data[:smb_password] ||= smb_password
|
|
|
|
|
|
|
|
# Register password as sensitive
|
2017-12-21 00:26:27 +00:00
|
|
|
Vagrant::Util::CredentialScrubber.sensitive(data[:smb_password])
|
2014-02-26 23:54:53 +00:00
|
|
|
end
|
2017-12-16 00:31:44 +00:00
|
|
|
|
|
|
|
machine.env.host.capability(:smb_prepare, machine, folders, opts)
|
2014-02-26 23:54:53 +00:00
|
|
|
end
|
|
|
|
|
2017-12-21 00:26:27 +00:00
|
|
|
def enable(machine, folders, opts)
|
2014-02-26 23:54:53 +00:00
|
|
|
machine.ui.output(I18n.t("vagrant_sf_smb.mounting"))
|
|
|
|
|
|
|
|
# Make sure that this machine knows this dance
|
|
|
|
if !machine.guest.capability?(:mount_smb_shared_folder)
|
|
|
|
raise Vagrant::Errors::GuestCapabilityNotFound,
|
|
|
|
cap: "mount_smb_shared_folder",
|
|
|
|
guest: machine.guest.name.to_s
|
|
|
|
end
|
|
|
|
|
2015-11-23 19:11:24 +00:00
|
|
|
# Setup if we have it
|
|
|
|
if machine.guest.capability?(:smb_install)
|
|
|
|
machine.guest.capability(:smb_install)
|
|
|
|
end
|
|
|
|
|
2014-02-26 23:54:53 +00:00
|
|
|
# Detect the host IP for this guest if one wasn't specified
|
|
|
|
# for every folder.
|
|
|
|
host_ip = nil
|
|
|
|
need_host_ip = false
|
|
|
|
folders.each do |id, data|
|
|
|
|
if !data[:smb_host]
|
|
|
|
need_host_ip = true
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if need_host_ip
|
2017-12-16 00:31:44 +00:00
|
|
|
candidate_ips = machine.env.host.capability(:configured_ip_addresses)
|
2014-02-26 23:54:53 +00:00
|
|
|
@logger.debug("Potential host IPs: #{candidate_ips.inspect}")
|
|
|
|
host_ip = machine.guest.capability(
|
|
|
|
:choose_addressable_ip_addr, candidate_ips)
|
|
|
|
if !host_ip
|
|
|
|
raise Errors::NoHostIPAddr
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# This is used for defaulting the owner/group
|
|
|
|
ssh_info = machine.ssh_info
|
|
|
|
|
|
|
|
folders.each do |id, data|
|
|
|
|
data[:smb_host] ||= host_ip
|
|
|
|
|
|
|
|
# Default the owner/group of the folder to the SSH user
|
|
|
|
data[:owner] ||= ssh_info[:username]
|
|
|
|
data[:group] ||= ssh_info[:username]
|
|
|
|
|
|
|
|
machine.ui.detail(I18n.t(
|
|
|
|
"vagrant_sf_smb.mounting_single",
|
|
|
|
host: data[:hostpath].to_s,
|
|
|
|
guest: data[:guestpath].to_s))
|
|
|
|
machine.guest.capability(
|
|
|
|
:mount_smb_shared_folder, data[:smb_id], data[:guestpath], data)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def cleanup(machine, opts)
|
2017-12-16 00:31:44 +00:00
|
|
|
if machine.env.host.capability?(:smb_cleanup)
|
|
|
|
machine.env.host.capability(:smb_cleanup, machine, opts)
|
2015-12-17 20:40:50 +00:00
|
|
|
end
|
2014-02-26 23:54:53 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|