Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUEST Logon failure on Windows 10/MacOS with password protected shares disabled #186

Closed
courville opened this issue Sep 22, 2019 · 28 comments

Comments

@courville
Copy link

With https://gist.github.com/courville/a0e6fe1ce2f31c9adc52191216eed3e0 test script on Windows 10 SMB server with disabled password protected sharing, I get a SmbAuthException logon failure:

smbcli 2 smb://DESKTOP-TAUJ0SF/ "" GUEST ""
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2019-09-22 22:48:45 INFO  smbcli:105 - Enabling SMB2
2019-09-22 22:48:45 INFO  smbcli:125 - smbFile is a server
2019-09-22 22:48:46 WARN  smbcli:135 - Caught a SmbAuthException on listFiles
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.
	at jcifs.smb.SmbTransportImpl.checkStatus2(SmbTransportImpl.java:1430)
	at jcifs.smb.SmbTransportImpl.checkStatus(SmbTransportImpl.java:1572)
	at jcifs.smb.SmbTransportImpl.sendrecv(SmbTransportImpl.java:1027)
	at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1543)
	at jcifs.smb.SmbSessionImpl.sessionSetupSMB2(SmbSessionImpl.java:549)
	at jcifs.smb.SmbSessionImpl.sessionSetup(SmbSessionImpl.java:483)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:369)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:347)
	at jcifs.smb.SmbTreeImpl.treeConnect(SmbTreeImpl.java:611)
	at jcifs.smb.SmbTreeConnection.connectTree(SmbTreeConnection.java:614)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:568)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:489)
	at jcifs.smb.SmbEnumerationUtil.doShareEnum(SmbEnumerationUtil.java:145)
	at jcifs.smb.SmbEnumerationUtil.doEnum(SmbEnumerationUtil.java:218)
	at jcifs.smb.SmbEnumerationUtil.listFiles(SmbEnumerationUtil.java:279)
	at jcifs.smb.SmbFile.listFiles(SmbFile.java:1199)
	at smbcli.main(smbcli.java:133)

Here is the corresponding pcap wireshark trace:
win10-guest.pcap.zip

@mbechler
Copy link
Contributor

Could you provide a packet capture for a working client as well?

I'm not entriely sure what disabling the password protection means on windows from a technical standpoint, what the trace shows is that guest login (this means using wrong credentials) is rejected with LOGIN_FAILURE while anonymous login (no credentials) fails with ACCESS_DENIED (which can both mean no permissions as well as e.g. signing issues).

@courville
Copy link
Author

OK need to find a way to reproduce with windows.
Testing a working client ipad explorer to macos with guest account activated and shares enabled it works with following pcap: ipad-macos-ok.pcap.zip
I tested guest with jcifs-ng to macos with guest account activated and shares enabled it is nok with following pcap: jcifs-macos-nok.pcap.zip and following log:

smbcli 2 smb://IMARC/ "" GUEST ""
2019-09-29 12:50:03 INFO  smbcli:105 - Enabling SMB2
2019-09-29 12:50:09 INFO  smbcli:125 - smbFile is a server
2019-09-29 12:50:09 WARN  smbcli:135 - Caught a SmbAuthException on listFiles
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.
	at jcifs.smb.SmbTransportImpl.checkStatus2(SmbTransportImpl.java:1430)
	at jcifs.smb.SmbTransportImpl.checkStatus(SmbTransportImpl.java:1572)
	at jcifs.smb.SmbTransportImpl.sendrecv(SmbTransportImpl.java:1027)
	at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1543)
	at jcifs.smb.SmbSessionImpl.sessionSetupSMB2(SmbSessionImpl.java:549)
	at jcifs.smb.SmbSessionImpl.sessionSetup(SmbSessionImpl.java:483)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:369)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:347)
	at jcifs.smb.SmbTreeImpl.treeConnect(SmbTreeImpl.java:611)
	at jcifs.smb.SmbTreeConnection.connectTree(SmbTreeConnection.java:614)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:568)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:489)
	at jcifs.smb.SmbEnumerationUtil.doShareEnum(SmbEnumerationUtil.java:145)
	at jcifs.smb.SmbEnumerationUtil.doEnum(SmbEnumerationUtil.java:218)
	at jcifs.smb.SmbEnumerationUtil.listFiles(SmbEnumerationUtil.java:279)
	at jcifs.smb.SmbFile.listFiles(SmbFile.java:1199)
	at smbcli.main(smbcli.java:133)

@courville
Copy link
Author

Attached also is the log from macos to win10 working too (I should have provided this one earlier):
macos-win10-ok.pcap.zip

@mbechler
Copy link
Contributor

I can't see much difference between the macos ok and the jcifs nok.

  • MacOS sends a client hostname (you should be able to set that with jcifs.netbios.hostname)
  • jcifs sends a SPNEGO mechListMIC, you can try jcifs.smb.client.disableSpnegoIntegrity=false

@courville
Copy link
Author

courville commented Sep 29, 2019

(5th edit of the post)
OK now it works on win10 setting jcifs.smb.client.disableSpnegoIntegrity=false (it seems that nego is valid through time).

@courville
Copy link
Author

For MacOS I am using defaults read /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName as jcifs.netbios.hostname (in my case imarc) and it is still nok.

@mbechler
Copy link
Contributor

jcifs-macos-nok.pcap.zip seems to be missing the SMB traffic

@courville
Copy link
Author

jcifs-macos-nok.pcap.zip seems to be missing the SMB traffic

ok indeed I was capturing on en0 and it should have been lo since I am on the same machine, does this capture help: jcifsng-macos-guest-nok.pcap.zip ?

@courville courville changed the title GUEST Logon failure on Windows 10 with password protected shares disabled GUEST Logon failure on Windows 10/MacOS with password protected shares disabled Sep 29, 2019
@mbechler
Copy link
Contributor

mbechler commented Oct 5, 2019

Some observations:

  • the server sends the signing required during negotation, so we end up setting the signing required flag ourselves, this is likely wrong.
  • there are some other differences in what flags and ntlm info is sent based on that we don't try enable signing for GUEST login (as it will be skipped later anyways).
  • Have you also tried it from another system? There may be some additional checks for local connections.

Can you disable the server's signing requirement (https://support.apple.com/en-us/HT205926) and verify that it is signing related?

@courville
Copy link
Author

Thank you for analyzing the issue.
I disabled the packet signing on macOS server and I still get:

smbcli 2 smb://IMARC/ "" guest ""
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2019-10-05 10:59:53 INFO  smbcli:109 - Enabling SMB2
2019-10-05 10:59:59 INFO  smbcli:129 - smbFile is a server
2019-10-05 11:00:00 WARN  smbcli:139 - Caught a SmbAuthException on listFiles
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.
	at jcifs.smb.SmbTransportImpl.checkStatus2(SmbTransportImpl.java:1430)
	at jcifs.smb.SmbTransportImpl.checkStatus(SmbTransportImpl.java:1572)
	at jcifs.smb.SmbTransportImpl.sendrecv(SmbTransportImpl.java:1027)
	at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1543)
	at jcifs.smb.SmbSessionImpl.sessionSetupSMB2(SmbSessionImpl.java:549)
	at jcifs.smb.SmbSessionImpl.sessionSetup(SmbSessionImpl.java:483)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:369)
	at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:347)
	at jcifs.smb.SmbTreeImpl.treeConnect(SmbTreeImpl.java:611)
	at jcifs.smb.SmbTreeConnection.connectTree(SmbTreeConnection.java:614)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:568)
	at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:489)
	at jcifs.smb.SmbEnumerationUtil.doShareEnum(SmbEnumerationUtil.java:145)
	at jcifs.smb.SmbEnumerationUtil.doEnum(SmbEnumerationUtil.java:218)
	at jcifs.smb.SmbEnumerationUtil.listFiles(SmbEnumerationUtil.java:279)
	at jcifs.smb.SmbFile.listFiles(SmbFile.java:1199)
	at smbcli.main(smbcli.java:137)

with the following packet capture guest-macos-signing_off.pcap.zip

If it helps, I tried from a win10 host to connect to the macOS SMB2 server with packet signing disabled with guest account a no password and it works. Associated capture is there: guest-win10-packet_signing_off.pcap.zip

I also tried to log in from my app on a Android phone with jcifs-ng and it fails to rule out the local interface issue.

@mbechler
Copy link
Contributor

Sorry for all the delay. Unfortunately I don't see anything obvious, except that jcifs-ng is not requesting signing (as we do determine this beforehand). Is a connection with a regular user account to the system successful?
If so, we might try to change that behavior to be more in line with the other clients.

@courville
Copy link
Author

courville commented Oct 13, 2019

No problem for the delay, guest on macOS is the only last configuration problematic on my side in all the scenarii explored.
I confirm that connection with regular user account is successful.
If you need a pcap please let me know.
For the record client uses the following options:

prop.put("jcifs.smb.client.enableSMB2", "true");
prop.put("jcifs.smb.client.disableSMB1", "false");
prop.put("jcifs.traceResources", "true");
prop.put("jcifs.resolveOrder", "BCAST,LMHOSTS,DNS"); 
prop.put("jcifs.smb.client.ipcSigningEnforced", "false");
prop.put("jcifs.smb.client.disablePlainTextPasswords", "false");
prop.put("jcifs.smb.client.dfs.disabled", "true");
prop.put("jcifs.smb.client.disableSpnegoIntegrity", "false");

@zc2com
Copy link

zc2com commented Mar 14, 2020

I am experiencing the same issue. When the following Windows option is set:
Network and Sharing Center > Advanced Sharing Settings > All Networks > Password Protected Sharing > Turn Off password protected sharing
JCIFS-NG fails to connect to a share either throwing "SmbAuthException: Access is denied." with NtlmPasswordAuthenticator() or "SmbAuthException: Logon failure: unknown user name or bad password" with NtlmPasswordAuthenticator("", "GUEST", "")
Please advise.

@courville
Copy link
Author

I am experiencing the same issue. When the following Windows option is set:
Network and Sharing Center > Advanced Sharing Settings > All Networks > Password Protected Sharing > Turn Off password protected sharing
JCIFS-NG fails to connect to a share either throwing "SmbAuthException: Access is denied." with NtlmPasswordAuthenticator() or "SmbAuthException: Logon failure: unknown user name or bad password" with NtlmPasswordAuthenticator("", "GUEST", "")
Please advise.

If I recall correctly the following option made it work: prop.put("jcifs.smb.client.disableSpnegoIntegrity", "false");. At least this is why I have in my commit logs.

@zc2com
Copy link

zc2com commented Mar 14, 2020

courville,
Your original example I compile and run already includes the line prop.put("jcifs.smb.client.disableSpnegoIntegrity", "false");
However that does not help.
Does it work in your case? With the mentioned Windows SMB server' option "Turn Off password protected sharing"?

@mbechler
Copy link
Contributor

@zc2com please try: jcifs.smb.client.disableSpnegoIntegrity=true, it seems I originally misspoke.

courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue May 24, 2020
courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue May 24, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
@zc2com
Copy link

zc2com commented May 25, 2020

Hi Mortiz,
Thank you for returning back to this problem.
However, switching disableSpnegoIntegrity to true did not help.
Samba's smbclient works with the following command
smbclient //EEE/Upload -U GUEST
So, the windows machine is accessible as GUEST.
I am attaching my test code and the output dump.
issue186.tar.gz
It was started with the params: '2 smb://EEE/Upload' (Trying SMB1 does not change a thing.)
I would very appreciate your help.

zc2

courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue May 30, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue May 30, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue May 30, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
@zc2com
Copy link

zc2com commented Jun 1, 2020

I've saved a tcpdump with a successful login made by Samba and failed ones by jCIFS-NG. I noticed, that Samba sends the domain name WORKGROUP. I tried to simulate that by pushing the word WORKGROUP as a domain parameter to Type3Message() in NtlmContext.java:275
That did not help, the server still responses with 0xC000006d
The tcpdumps are attached:
tcpdump.tar.gz

Hope for help.

@zc2com
Copy link

zc2com commented Jun 2, 2020

I finally made it work. But not as "GUEST" and I had to modify the JCIFS-NG code. I believe, GUEST does not work because such account actually exists on the server machine and the password that JCIFS-NG supplies ("invalid") is, in fact, invalid. Samba client still successfully uses the account "GUEST", somehow providing the correct password (see the wireshark dump in my previous comment).
Actually, when Windows sharing is set to be passwordless, any garbage works as credentials. But! not an empty string. However, NtlmPasswordAuthenticator.isAnonymous() returns true only if the credentials are empty strings (or GUEST, but that does not work, so let's put that aside).
So, here's how to make an anonymous access work:

  1. Instead of creating the context by calling withGuestCrendentials() use withAnonymousCredentials()
  2. Modify the JCIFS-NG's method NtlmContext.makeAuthenticate()
    diff

@mbechler
Copy link
Contributor

mbechler commented Jun 6, 2020

To provide some context and a basis for discussion, there are two distict modes of authentication in SMB:

  • anonymous: Which is access with NO, i.e. empty credentials
  • guest: Which is access with WRONG credentials

That things get more difficult in guest mode when the target user exists makes sense (samba for example even has options to decide whether a wrong username is required or to accept just wrong passwords) and this may be hitting different checks and code paths.

So changing the guest username would avoid hitting that code path, I guess making the guest user configurable would at least allow a workaround until this is figured out fully.

However, as samba is still able to perform the login with the guest user I think something else is wrong here.

@mbechler
Copy link
Contributor

mbechler commented Jun 6, 2020

So digging into this further, it turns out that samba is really not performing guest authentication either, but the guest accounts password's just is the empty string. So it seems we either need to be compatible with that or change the guest acount username.

@zc2com
Copy link

zc2com commented Jun 7, 2020

samba is really not performing guest authentication either

What exactly is that "guest authentication"? Is not it just using the name GUEST and empty password? BTW, that actually works, after I changed the code to:

boolean anonymous = this.auth.isAnonymous();
boolean guest = this.auth.isGuest();
Type3Message msg3 = new Type3Message(
    this.transportContext,
    msg2,
    this.targetName,
    guest ? ""      : anonymous ? " " : this.auth.getPassword(),   // note it's empty  for guest
    guest ? null    : anonymous ? " " : this.auth.getUserDomain(),
    guest ? "GUEST" : anonymous ? " " : this.auth.getUsername(),
    this.workstation,
    this.ntlmsspFlags,
    true /*guest || !anonymous*/ );

From my experience, for the anonymous mode, the credentials could be anything but not empty string. But you are saying

anonymous: Which is access with NO, i.e. empty credentials

I guess that is the case when nonAnonymous==false and empty password so then you set lmResponse/ntResponse to null. Maybe that how it supposed to be according to the SMB spec, but that just does not work. To avoid that I set nonAnonymous to be always true.

@mbechler
Copy link
Contributor

mbechler commented Jun 7, 2020

Is not it just using the name GUEST and empty password?

No, guest authentication essentially is using whatever username or possibly password and the server deciding, credentials are wrong, but you are welcome anyways.
The issue here is exactly that it is not was is happending but a regular user authentication happens with the user that we (somewhat arbitrarily) use to achieve that.

We definitely can not mess with the anonymous authentication mode, this is widely used e.g. for IPC and functioning as it is supposed to.

@zc2com
Copy link

zc2com commented Jun 8, 2020

We definitely can not mess

Ok, I guess, I will use my workaround in my app until you find a proper solution. Please let me know if you need some testing.

mbechler added a commit that referenced this issue Jul 7, 2020
Also:
- adds a setting to permit silent fallback to guest authentication
- allow proper authentication with the username 'guest'
@mbechler
Copy link
Contributor

mbechler commented Jul 7, 2020

So, I went ahead and implemented a couple of things:

  • the username/password used for guest access can now be configured, the default username has been changed to jcifsguest, which should avoid hitting a valid user (i.e. guest)
  • logging in (regularly) with the username "guest" is now possible, if this is desired

In my tests this permits guest logins on win10 (and my other test targets) using withGuestCredentials()

I'm not quite sure whether it's better to have to have a username of "guest" (with empty password) or a more commonly non-existent username like "jcifsguest".
I guess both ways there could be cases in which that could fail, so it would be great if you could test this and check whether it works for you.

courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue Jul 7, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
@zc2com
Copy link

zc2com commented Jul 11, 2020

mbechler, thanks for the fix! I tested against a Windows 8.1 home . It works fine using withGuestCredentials() (I did not setup any default credentials). It gives me an "Access is denied" when I tried to use withAnonymousCredentials(). Here's a call stack:

jcifs.smb.SmbAuthException: Access is denied.
        at jcifs.smb.SmbTransportImpl.checkStatus2(SmbTransportImpl.java:1430)
        at jcifs.smb.SmbTransportImpl.checkStatus(SmbTransportImpl.java:1573)
        at jcifs.smb.SmbTransportImpl.sendrecv(SmbTransportImpl.java:1027)
        at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1544)
        at jcifs.smb.SmbSessionImpl.sessionSetupSMB2(SmbSessionImpl.java:549)
        at jcifs.smb.SmbSessionImpl.sessionSetup(SmbSessionImpl.java:483)
        at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:369)
        at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:347)
        at jcifs.smb.SmbTreeImpl.treeConnect(SmbTreeImpl.java:611)
        at jcifs.smb.SmbTreeConnection.connectTree(SmbTreeConnection.java:614)
        at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:568)
        at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:489)
        at jcifs.smb.SmbTreeConnection.connect(SmbTreeConnection.java:465)
        at jcifs.smb.SmbTreeConnection.connectWrapException(SmbTreeConnection.java:426)
        at jcifs.smb.SmbFile.ensureTreeConnected(SmbFile.java:558)
        at jcifs.smb.SmbEnumerationUtil.doEnum(SmbEnumerationUtil.java:221)
        at jcifs.smb.SmbEnumerationUtil.listFiles(SmbEnumerationUtil.java:279)
        at jcifs.smb.SmbFile.listFiles(SmbFile.java:1206)
        at com.ghostsq.jcifsngtest.smbcli.main(smbcli.java:156)

Do I guess right, the anonymous mode should not be used for a regular password-less access to shared folders?
It only need for IPC functioning, like you mentioned earlier, is that correct?

@mbechler
Copy link
Contributor

Yes, while in theory it could be used for file access, afaik this mode is only used for IPC with domain controllers.

courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue Sep 17, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue Sep 20, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
@courville
Copy link
Author

Guest login now works for me as well on win10. Thank you.
Please note that for being able to browse root of server shares I need to add this option: prop.put("jcifs.smb.client.ipcSigningEnforced", "false");

courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue Oct 19, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
courville added a commit to nova-video-player/aos-FileCoreLibrary that referenced this issue Oct 22, 2020
… solving WD MyCloud issues

See AgNO3/jcifs-ng#186 and AgNO3/jcifs-ng#226

Separate SMBv1 and SMBv2 world and do not mix options
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants