vagrant icon indicating copy to clipboard operation
vagrant copied to clipboard

2.2.10 broke SMB synced_folder in enterprise environments

Open braddeicide opened this issue 3 years ago • 22 comments

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

  1. Have an SMB synced_folder
  2. Be on a machine you only have access to with AD credentials
  3. Vagrant up
  4. 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.

braddeicide avatar Oct 09 '20 00:10 braddeicide

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

image

dlarubia avatar Oct 21 '20 14:10 dlarubia

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.

Sebjugate avatar Oct 22 '20 17:10 Sebjugate

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.

lopsided98 avatar Mar 02 '21 17:03 lopsided98

I'm experiencing this with 2.2.18.

mhalano avatar Sep 09 '21 11:09 mhalano

same here. 2.2.18

ashantyk avatar Sep 09 '21 12:09 ashantyk

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] where fqdn 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.

onpubcom avatar Sep 14 '21 03:09 onpubcom

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!

hegyre avatar Oct 04 '21 15:10 hegyre

Still facing this issue on 2.2.18

naresh97 avatar Nov 10 '21 13:11 naresh97

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 avatar Feb 21 '22 15:02 dlkj

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?

StefanD986 avatar May 18 '22 09:05 StefanD986

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 avatar May 19 '22 15:05 onpubcom

@onpubcom Would that be helpful? https://techgenix.com/managing-cached-credentials/

hegyre avatar Jul 04 '22 13:07 hegyre

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.

TBBle avatar Jul 06 '22 06:07 TBBle

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.

onpubcom avatar Aug 16 '22 17:08 onpubcom

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 ?

hegyre avatar Aug 16 '22 19:08 hegyre

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.

onpubcom avatar Aug 16 '22 19:08 onpubcom

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

hegyre avatar Aug 16 '22 19:08 hegyre

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.

Clonkex avatar Jul 06 '23 22:07 Clonkex

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

pingram3030 avatar Apr 03 '24 23:04 pingram3030

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 🤷

onpubcom avatar Apr 04 '24 00:04 onpubcom

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.

hegyre avatar Apr 04 '24 11:04 hegyre