diff options
-rw-r--r-- | fs/cifs/CHANGES | 3 | ||||
-rw-r--r-- | fs/cifs/cifsacl.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 20 | ||||
-rw-r--r-- | fs/cifs/connect.c | 27 |
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 | |||
3 | Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance | 3 | Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance |
4 | of readpages by eliminating one extra memcpy. Allow update of file size | 4 | of readpages by eliminating one extra memcpy. Allow update of file size |
5 | from remote server even if file is open for write as long as mount is | 5 | from remote server even if file is open for write as long as mount is |
6 | directio. | 6 | directio. Recognize share mode security and send NTLM encrypted password |
7 | on tree connect if share mode negotiated. | ||
7 | 8 | ||
8 | Version 1.39 | 9 | Version 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 */ |
34 | const cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | 34 | extern const struct cifs_sid sid_everyone; |
35 | /* group users */ | 35 | /* group users */ |
36 | const cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | 36 | extern 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 |
42 | static struct { | 43 | static 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 */ | ||
2501 | const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | ||
2502 | /* group users */ | ||
2503 | const 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 */ |
2498 | static int parse_sec_desc(struct sec_desc * psec_desc, int acl_len) | 2506 | static 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 | } |