[linux-cifs-client] [PATCH] allow NTLM plaintext password
authentication.
Bart Oldeman
bartoldeman at users.sourceforge.net
Sun Mar 30 19:27:13 GMT 2008
Hi,
the following patch allows plaintext password authentication with NTLM, as
implemented by some servers (see also
http://lists.samba.org/archive/linux-cifs-client/2007-November/002373.html
)
/proc/fs/cifs/SecurityFlags needs to be or'ed with 0x20, or else plain
text passwords are rejected.
Referenced: cli_session_setup_plaintext() in Samba's source/libsmb/cliconnect.c
On a related note: in sess.c for NTMLv2 there is the following code:
====
if (first_time) /* should this be moved into common code
with similar ntlmv2 path? */
/*
cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
response BB FIXME, v2_sess_key); */
/* copy session key */
/* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
bcc_ptr += LM2_SESS_KEY_SIZE; */
memcpy(bcc_ptr, (char *)v2_sess_key,
sizeof(struct ntlmv2_resp));
bcc_ptr += sizeof(struct ntlmv2_resp);
====
which looks suspect to me since "if (first_time)" applies to
the unindented memcpy(bcc_ptr,...) and bcc_ptr is updated unconditionally.
Bart
Signed-off-by: Bart Oldeman <bartoldeman at users.sourceforge.net>
diff -urp -X linux-2.6/Documentation/dontdiff linux-2.6/fs/cifs.orig/cifssmb.c linux-2.6/fs/cifs/cifssmb.c
--- linux-2.6/fs/cifs.orig/cifssmb.c 2008-03-30 14:35:58.000000000 -0400
+++ linux-2.6/fs/cifs/cifssmb.c 2008-03-30 15:15:15.000000000 -0400
@@ -565,13 +565,6 @@ CIFSSMBNegotiate(unsigned int xid, struc
if ((server->secMode & SECMODE_USER) == 0)
cFYI(1, ("share mode security"));
- if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
-#endif /* CIFS_WEAK_PW_HASH */
- cERROR(1, ("Server requests plain text password"
- " but client support disabled"));
-
if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
server->secType = NTLMv2;
else if (secFlags & CIFSSEC_MAY_NTLM)
@@ -582,10 +575,6 @@ CIFSSMBNegotiate(unsigned int xid, struc
server->secType = Kerberos;
else if (secFlags & CIFSSEC_MAY_LANMAN)
server->secType = LANMAN;
-/* #ifdef CONFIG_CIFS_EXPERIMENTAL
- else if (secFlags & CIFSSEC_MAY_PLNTXT)
- server->secType = ??
-#endif */
else {
rc = -EOPNOTSUPP;
cERROR(1, ("Invalid security type"));
@@ -593,6 +582,17 @@ CIFSSMBNegotiate(unsigned int xid, struc
}
/* else ... any others ...? */
+ if ((server->secMode & SECMODE_PW_ENCRYPT) == 0) {
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+ if ((secFlags & CIFSSEC_MAY_PLNTXT)) {
+ if (server->secType == NTLM)
+ server->secType = PLAINTXT;
+ } else
+#endif /* CIFS_WEAK_PW_HASH */
+ cERROR(1, ("Server requests plain text password"
+ " but client support disabled"));
+ }
+
/* one byte, so no need to convert this or EncryptionKeyLen from
little endian */
server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
diff -urp -X linux-2.6/Documentation/dontdiff linux-2.6/fs/cifs.orig/sess.c linux-2.6/fs/cifs/sess.c
--- linux-2.6/fs/cifs.orig/sess.c 2008-02-01 16:25:43.000000000 -0500
+++ linux-2.6/fs/cifs/sess.c 2008-03-30 15:08:55.000000000 -0400
@@ -364,7 +364,7 @@ CIFS_SessSetup(unsigned int xid, struct
return -EOPNOTSUPP;
#endif
wct = 10; /* lanman 2 style sessionsetup */
- } else if ((type == NTLM) || (type == NTLMv2)) {
+ } else if ((type == NTLM) || (type == NTLMv2) || (type == PLAINTXT)) {
/* For NTLMv2 failures eventually may need to retry NTLM */
wct = 13; /* old style NTLM sessionsetup */
} else /* same size: negotiate or auth, NTLMSSP or extended security */
@@ -432,6 +432,36 @@ CIFS_SessSetup(unsigned int xid, struct
cFYI(1, ("Negotiating LANMAN setting up strings"));
/* Unicode not allowed for LANMAN dialects */
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+ } else if (type == PLAINTXT) {
+ int bytes_ret;
+
+ pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
+ if (ses->capabilities & CAP_UNICODE) {
+ /* unicode strings must be word aligned */
+ if (iov[0].iov_len % 2) {
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
+ ses->password, 128, nls_cp);
+ bytes_ret = 2 * (bytes_ret + 1);
+ bcc_ptr += bytes_ret;
+ pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+ pSMB->req_no_secext.CaseSensitivePasswordLength =
+ cpu_to_le16(bytes_ret);
+ unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
+ } else {
+ /* Password cannot be longer than 128 characters */
+ bytes_ret = strnlen(ses->password, 128);
+ memcpy(bcc_ptr, ses->password, bytes_ret);
+ /* account for null termination */
+ bcc_ptr[bytes_ret++] = 0;
+ bcc_ptr += bytes_ret;
+ pSMB->req_no_secext.CaseInsensitivePasswordLength =
+ cpu_to_le16(bytes_ret);
+ pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
+ ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+ }
#endif
} else if (type == NTLM) {
char ntlm_session_key[CIFS_SESS_KEY_SIZE];
More information about the linux-cifs-client
mailing list