aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-01-14 00:34:58 -0500
committerSteve French <sfrench@us.ibm.com>2006-01-14 00:34:58 -0500
commiteeac8047fcf4c659eb15f2e27a0ef4aeba64157f (patch)
tree91b1e32bb9f2d6f9e9a122bd5e737df40701ab11 /fs/cifs
parent84153973a29dfb3f3d9fe2fe75c2cd613a3cdf27 (diff)
[CIFS] Fix CIFS to recognize share mode security
Fix Samba bugzilla bug 3301 In share mode encrypted password must be sent on tree connection (in our case only the NTLM password is sent, not the older LANMAN one). Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/cifsacl.h6
-rw-r--r--fs/cifs/cifssmb.c20
-rw-r--r--fs/cifs/connect.c27
4 files changed, 41 insertions, 15 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index c7995c96f069..d335015473a5 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -3,7 +3,8 @@ Version 1.40
3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
4of readpages by eliminating one extra memcpy. Allow update of file size 4of readpages by eliminating one extra memcpy. Allow update of file size
5from remote server even if file is open for write as long as mount is 5from remote server even if file is open for write as long as mount is
6directio. 6directio. Recognize share mode security and send NTLM encrypted password
7on tree connect if share mode negotiated.
7 8
8Version 1.39 9Version 1.39
9------------ 10------------
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index d152ff50ea8c..d0776ac2b804 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -26,13 +26,13 @@ struct cifs_sid {
26 __u8 revision; /* revision level */ 26 __u8 revision; /* revision level */
27 __u8 num_subauths; 27 __u8 num_subauths;
28 __u8 authority[6]; 28 __u8 authority[6];
29 __u8 sub_auth[4]; 29 __u32 sub_auth[4];
30 /* next sub_auth if any ... */ 30 /* next sub_auth if any ... */
31} __attribute__((packed)); 31} __attribute__((packed));
32 32
33/* everyone */ 33/* everyone */
34const cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 34extern const struct cifs_sid sid_everyone;
35/* group users */ 35/* group users */
36const cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 36extern const struct cifs_sid sid_user;
37 37
38#endif /* _CIFSACL_H */ 38#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index ca0f573e9791..7a4e936d726c 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -37,6 +37,7 @@
37#include "cifsproto.h" 37#include "cifsproto.h"
38#include "cifs_unicode.h" 38#include "cifs_unicode.h"
39#include "cifs_debug.h" 39#include "cifs_debug.h"
40#include "cifsacl.h"
40 41
41#ifdef CONFIG_CIFS_POSIX 42#ifdef CONFIG_CIFS_POSIX
42static struct { 43static struct {
@@ -372,8 +373,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
372 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 373 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
373 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 374 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
374 if (rc == 0) { 375 if (rc == 0) {
375 server->secMode = pSMBr->SecurityMode; 376 server->secMode = pSMBr->SecurityMode;
376 server->secType = NTLM; /* BB override default for 377 if((server->secMode & SECMODE_USER) == 0)
378 cFYI(1,("share mode security"));
379 server->secType = NTLM; /* BB override default for
377 NTLMv2 or kerberos v5 */ 380 NTLMv2 or kerberos v5 */
378 /* one byte - no need to convert this or EncryptionKeyLen 381 /* one byte - no need to convert this or EncryptionKeyLen
379 from little endian */ 382 from little endian */
@@ -383,7 +386,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
383 min(le32_to_cpu(pSMBr->MaxBufferSize), 386 min(le32_to_cpu(pSMBr->MaxBufferSize),
384 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 387 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
385 server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); 388 server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
386 cFYI(0, ("Max buf = %d ", ses->server->maxBuf)); 389 cFYI(0, ("Max buf = %d", ses->server->maxBuf));
387 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 390 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
388 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 391 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
389 server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); 392 server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);
@@ -411,8 +414,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
411 (server->server_GUID, 414 (server->server_GUID,
412 pSMBr->u.extended_response. 415 pSMBr->u.extended_response.
413 GUID, 16) != 0) { 416 GUID, 16) != 0) {
414 cFYI(1, 417 cFYI(1, ("server UID changed"));
415 ("UID of server does not match previous connection to same ip address"));
416 memcpy(server-> 418 memcpy(server->
417 server_GUID, 419 server_GUID,
418 pSMBr->u. 420 pSMBr->u.
@@ -2494,8 +2496,14 @@ GetExtAttrOut:
2494 2496
2495#endif /* CONFIG_POSIX */ 2497#endif /* CONFIG_POSIX */
2496 2498
2499
2500/* security id for everyone */
2501const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
2502/* group users */
2503const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
2504
2497/* Convert CIFS ACL to POSIX form */ 2505/* Convert CIFS ACL to POSIX form */
2498static int parse_sec_desc(struct sec_desc * psec_desc, int acl_len) 2506static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
2499{ 2507{
2500 return 0; 2508 return 0;
2501} 2509}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 1817d5313a8a..88f60aa52058 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1795,7 +1795,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1795 cifs_sb->mnt_gid = volume_info.linux_gid; 1795 cifs_sb->mnt_gid = volume_info.linux_gid;
1796 cifs_sb->mnt_file_mode = volume_info.file_mode; 1796 cifs_sb->mnt_file_mode = volume_info.file_mode;
1797 cifs_sb->mnt_dir_mode = volume_info.dir_mode; 1797 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1798 cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 1798 cFYI(1,("file mode: 0x%x dir mode: 0x%x",
1799 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1799 1800
1800 if(volume_info.noperm) 1801 if(volume_info.noperm)
1801 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 1802 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -1972,7 +1973,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1972 __u32 capabilities; 1973 __u32 capabilities;
1973 __u16 count; 1974 __u16 count;
1974 1975
1975 cFYI(1, ("In sesssetup ")); 1976 cFYI(1, ("In sesssetup"));
1976 if(ses == NULL) 1977 if(ses == NULL)
1977 return -EINVAL; 1978 return -EINVAL;
1978 user = ses->userName; 1979 user = ses->userName;
@@ -3248,9 +3249,26 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3248 3249
3249 pSMB->AndXCommand = 0xFF; 3250 pSMB->AndXCommand = 0xFF;
3250 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 3251 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3251 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3252 bcc_ptr = &pSMB->Password[0]; 3252 bcc_ptr = &pSMB->Password[0];
3253 bcc_ptr++; /* skip password */ 3253 if((ses->server->secMode) & SECMODE_USER) {
3254 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3255 bcc_ptr++; /* skip password */
3256 } else {
3257 pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
3258 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3259 specified as required (when that support is added to
3260 the vfs in the future) as only NTLM or the much
3261 weaker LANMAN (which we do not send) is accepted
3262 by Samba (not sure whether other servers allow
3263 NTLMv2 password here) */
3264 SMBNTencrypt(ses->password,
3265 ses->server->cryptKey,
3266 bcc_ptr);
3267
3268 bcc_ptr += CIFS_SESSION_KEY_SIZE;
3269 *bcc_ptr = 0;
3270 bcc_ptr++; /* align */
3271 }
3254 3272
3255 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3273 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3256 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3274 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -3268,7 +3286,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3268 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ 3286 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
3269 bcc_ptr += 2; /* skip trailing null */ 3287 bcc_ptr += 2; /* skip trailing null */
3270 } else { /* ASCII */ 3288 } else { /* ASCII */
3271
3272 strcpy(bcc_ptr, tree); 3289 strcpy(bcc_ptr, tree);
3273 bcc_ptr += strlen(tree) + 1; 3290 bcc_ptr += strlen(tree) + 1;
3274 } 3291 }