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 | } |
