vagrant
vagrant copied to clipboard
2.2.10 broke SMB synced_folder in enterprise environments
Vagrant version
2.2.10
Host operating system
Windows 10
Guest operating system
Linux
Expected behavior
When using an authenticated SMB synced_folder Vagrant up continues after entering the correct credentials when prompted
Actual behavior
Vagrant up fails as authentication always fails
Steps to reproduce
- Have an SMB synced_folder
- Be on a machine you only have access to with AD credentials
- Vagrant up
- Enter correct AD credentials when prompted
References
https://github.com/hashicorp/vagrant/commit/c2df34298f27fc41d90320256945979ddcdd7cc0
I suspect by passing machine, local authentication is being requested which we don't have. In 2.2.9 AD credentials succeed. In 2.2.10 we ctrl-c the prompt and ssh into the machine manually mounting the local /vagrant share works with AD creds.
I don't currently have a dev env to test removing machine from that call.
Same here. I'm using 2.2.10 too, but i'm not in enterprise environment and the guests that I tried were Ubuntu 18.04LTS and Windows server 2019. When I set the variables in Vagrantfile the machines go up normally, but I cant access the folders equally
We are having this issue as well with version 2.2.10. It seems that Vagrant's initial credential check wants DOMAIN\user or user@domain, but when vagrant tries to mount the share on the guest OS (CentOS 6), the credentials that were provided earlier get mangled and authentication fails. Windows event log showed failed authentication as using domain SAMBA despite the username already including the domain.
We've tried various arrangements, DOMAIN\user, user@domain, [email protected], user, etc. including quoting the username string. There doesn't seem to be a variant that satisfies both vagrant's initial credential check and the guest OS's needs for mounting the share.
2.2.9 allows us to enter credentials as simply the username. Vagrant does not seem to immediately validate those credentials, as I can enter known incorrect values. So that may be why it works in 2.2.9. My suspicion is that 2.2.10 added some preliminary validation of the credentials, and that validation doesn't match what the guest OS needs when trying to mount the share.
I don't think the change proposed in #11989 will fix this issue (unless there are multiple issues here). I experimented with it a bit and passing -contextType Domain
seems to just make the script always fail no matter what credentials are given.
As others have said, check_credentials.ps1
is expecting DOMAIN\user
, and it validates the credentials correctly if given that format (using ContextType::Machine
). I believe the correct fix would be to split the user@DOMAIN
string into its user and domain components and pass them in the correct format to check_credentials.ps1
.
I'm experiencing this with 2.2.18.
same here. 2.2.18
So on my end I was able to fix this issue by patching Vagrant's check_credentials.ps1
script (full path for my install is: C:\HashiCorp\Vagrant\embedded\gems\2.2.19\gems\vagrant-2.2.19\plugins\hosts\windows\scripts\check_credentials.ps1
) by changing the following section from:
$DSContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain,
$env:COMPUTERNAME
)
if ( $DSContext.ValidateCredentials( $username, $password ) ) {
exit 0
}
To:
$DSContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain,
$env:USERDOMAIN
)
if ( $DSContext.ValidateCredentials( $username, $password ) ) {
exit 0
}
Note the only difference above is that we're constructing the PrincipalContext
object with the current domain name via the $env:USERDOMAIN
environment variable instead of the computer name $env:COMPUTERNAME
environment var.
This appears to make it so that when I enter my username in the form of user[@domain]
when prompted, the $DSContext.ValidateCredentials( $username, $password )
check now works as expected when the ContextType
the script is checking against is [System.DirectoryServices.AccountManagement.ContextType]::Domain
.
More info for this specific API can be found here:
Doc says the following for the above PrincipalContext
object in regards to the second name
constructor param:
The name of the domain or server for Domain context types
Couple other things I noticed in testing my patch above:
- Requires you to be able to contact your domain controllers since it does look like it's a "live" credential check. So if you're not connected directly to your corporate network when starting up vagrant, make sure you're on VPN so that when vagrant checks your SMB credentials, it can contact your AD controllers to verify your username/password
- Patch also works when username is entered like
user[@fqdn]
wherefqdn
is your fully-qualified/DNS AD domain name, i.e.:[email protected]
vs. entering in the shorter name for your domain, like:user@domain
Let me know if this works for other folks on this thread, thanks!
PS: Without the above patch applied, when I entered my username in the form of domain\user
the credentials check would work on the Windows side, but then when the SMB/CIFS mount command would be attempted inside the Linux guest VM, then the mount would fail with a permission denied error. This is because it seems like the script that generates the mount
command fails to parse out the domain
string in this case, because it's looking for it in the form of user@domain
. So a potential alternate fix for this bug would be to patch the script that generates the guest mount
command to also accept SMB username in the form of domain\user
.
I had the same issue, and I tested your workaround @onpubcom but this forces me to enable the VPN (so I did not tested entirely your solution). On vagrant 2.2.9, which was the last working version before this issue happened, that worked well without the VPN (probably using Windows domain cached credentials).
So I went to some files and dropped / reverted some lines of code:
C:\HashiCorp\Vagrant\embedded\gems\2.2.18\gems\vagrant-2.2.18\plugins\hosts\windows\scripts\check_credentials.ps1 Revert this commit: https://github.com/hashicorp/vagrant/pull/12428/files#diff-bd06477b1f03fce48a72b47419172c8634d05ef148982f9f0b3f4e8efd490382
C:\HashiCorp\Vagrant\embedded\gems\2.2.18\gems\vagrant-2.2.18\templates\locales\synced_folder_smb.yml
Remove lines 13 and 14 (invalid credentials
part) (Maybe not needed)
From https://github.com/soapy1/vagrant/commit/c2df34298f27fc41d90320256945979ddcdd7cc0#diff-ba2e76f88b2d746bad0e0dfc36c7f3db9518524d1cb1bf51511822cb49f819f7 :
C:\HashiCorp\Vagrant\embedded\gems\2.2.18\gems\vagrant-2.2.18\plugins\synced_folders\smb\synced_folder.rb
Remove "machine,
" line 69 (Maybe not needed)
C:\HashiCorp\Vagrant\embedded\gems\2.2.18\gems\vagrant-2.2.18\plugins\hosts\windows\plugin.rb Remove
host_capability("windows", "smb_validate_password") do
require_relative "cap/smb"
Cap::SMB
end
That last one (plus possible ones above which might not be needed) did the trick!
Still facing this issue on 2.2.18
Also experiencing the same issue with domain credentials on 2.2.19.
@onpubcom workaround is working for me but I'd appreciate a fix that works offline.
Almost 2 years later this bug is still there and its essentially a blocker for windows guest VMs. @soapy1 When can we expect a fix for this?
Also experiencing the same issue with domain credentials on 2.2.19.
@onpubcom workaround is working for me but I'd appreciate a fix that works offline.
@dlkj If you or anyone else in this thread knows of some way to check the cached/offline AD credential store via PowerShell, then it should be possible to do what you're requesting, but so far in my (admittedly brief) research I haven't found a way to do that. If anyone has any pointers on how to make my patch work offline, then I'd be happy to try and revise it and then submit it as a PR from there.
@onpubcom Would that be helpful? https://techgenix.com/managing-cached-credentials/
I hit this issue as well in 2.2.19, and the workaround in https://github.com/hashicorp/vagrant/issues/11945#issuecomment-918763938 turned out to be insufficient in my environment.
I ended up with the following block:
$DSContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain,
$env:USERDNSDOMAIN
)
if ( $DSContext.ValidateCredentials( $username, $password, [System.DirectoryServices.AccountManagement.ContextOptions]::Negotiate ) ) {
exit 0
}
The two changes are using $env:USERDNSDOMAIN
(although I'm not sure that was necessary, the workaround's $env:USERDOMAIN
would probably work too), and adding [System.DirectoryServices.AccountManagement.ContextOptions]::Negotiate
to the ValidateCredentials
call.
The latter change (inspired by this blog post from 2015, so it's not new) wasn't needed when I ran the same script under PowerShell 7; so I suspect the default in .NET Core is different from .NET Framework. I also suspect this is needed because the default in .NET Framework was something like NTLM, which is now held to be insecure and has been disabled by my employer.
I only tested this with a username in the form [email protected]
, and $env:USERDNSNAME
is CORP.EMPLOYER.LOCAL
.
Edit: I tried with the other username form [email protected]
, and that passed the credential check script, but failed when mounting inside the Linux VM I was building. Not sure if this is a linux/CIFS issue, an issue with the way the mount command is built, or only works due to something Windows does that Linux/CIFS does not and so it isn't expected to work.
I think in a proper fix, the $env:COMPUTERNAME
that both workarounds are replacing should be the domain value extracted from the username if present with @
or \\
separator, since that's what's actually done on the in-VM side, as noted at the end of https://github.com/hashicorp/vagrant/issues/11945#issuecomment-918763938.
So my sense of this issue as it stands now is that it's not currently possible to use the Windows cached credentials store to validate existing credentials @hegyre @TBBle , even if we were to use the module described here https://techgenix.com/managing-cached-credentials/, correct me if I'm wrong though.
I've browsed the various core PowerShell/.NET API docs, and I didn't see anywhere there either which offers checking of cached AD credentials.
So a person really does need a network connection to their domain controllers in order to validate their login credentials when using my patch, it seems. I would argue this is still better than the currently still broken (last I checked) domain validation logic in the core Vagrant releases.
How would you feel about merging my patch in to an upcoming release @hegyre ? I'd be happy to create a PR at some point soon if you agree with my assessment here, lmk.
Hey @onpubcom , Well, honestly I would personnally not be very happy to connect to the VPN each time I run vagrant (and also because that disconnects me from other things since all the traffic would go to the VPN, and I cannot change that).
That worked great with 2.2.9, why we couldn't simply revert to what it was with 2.2.9 ?
Fair enough @hegyre. Though I would argue that most people who have their machines connected to an AD are likely doing it because of their job or on a work computer, so in that case most folks would either be connected directly to their corporate network or VPN already when starting up their VMs via Vagrant, though I of course agree that this is the least desirable option if we can somehow still check local/cached credentials in a completely offline way.
I think at some point I'll test 2.2.9 on my domain connected machine to see if the logic in that version still works as expected on newer versions of Windows etc. Is there an older revision hash for that powershell script file in this repo that we could also look at to compare what the logic looks like in 2.2.9 vs. the current powershell logic for this flow? If you don't have that handy somewhere, I can try to dig it up sometime soon since that could also give some clues as to have broke in 2.2.10 and newer releases. Will circle back sometime soon, thanks.
If I remember well (when my colleague tested my workaround above), by just removing that in C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-2.3.7\plugins\hosts\windows should make it works again:
host_capability("windows", "smb_validate_password") do
require_relative "cap/smb"
Cap::SMB
end
Is it possible to get this prioritised? It's straight-up broken, and seems an easy fix. I can maybe try to do a pull request at some point, although I'm not familiar with Ruby at all and I've never looked at Vagrant's internals.
At least I can confirm onpubcom's workaround works for me (although I found the file at C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-2.3.6\plugins\hosts\windows\scripts
in my version).
Currently I have no choice but to include instructions on how to modify your Vagrant installation (!) in the readme for running on Windows, which is... less than ideal.
fixing the domain check to use $env:USERDOMAIN
is the most logical fix IMO as the current use of COMPUTERNAME
is using your remote credentials to authenticate to the local host, which is analogous to using your local machine creds when authenticating to a remote server.
If a user with a domain joined computer needs to use their domain credentials, then they absolutely need to ensure they are on a network which can contact the DC; this is a user, not a vagrant, problem.
I am +1 to altering check_credentials.ps1
to ensure that domain authentication is made against the domain controller as the current local machine target is broken.
Vagrant: 2.4.1
Agreed, there's no way I found to check against any kind of cached AD credential from Powershell that I'm aware of (last I checked), so the patch I previously suggested is likely the only viable fix for this 🤷
As of today my machine is now connected to the domain but with Azure AD, so when I go to the computer management, it's still seen as "Workgroup" but I'm really AAD-joined. Dunno if this thing plays a role here. Anyway if you need some testers I'm avail.