diff options
author | Steve French <sfrench@us.ibm.com> | 2011-05-26 14:38:54 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-26 14:38:54 -0400 |
commit | 6848b7334b24b47aa3d0e70342ff839ffa95d5fa (patch) | |
tree | 6e28dfc52d0625569293b02969416315af3046f6 /fs | |
parent | fa2989f4473413a86890066aa3a5676a53b541e4 (diff) |
[CIFS] When mandatory encryption on share, fail mount
When mandatory encryption is configured in samba server on a
share (smb.conf parameter "smb encrypt = mandatory") the
server will hang up the tcp session when we try to send
the first frame after the tree connect if it is not a
QueryFSUnixInfo, this causes cifs mount to hang (it must
be killed with ctl-c). Move the QueryFSUnixInfo call
earlier in the mount sequence, and check whether the SetFSUnixInfo
fails due to mandatory encryption so we can return a sensible
error (EACCES) on mount.
In a future patch (for 2.6.40) we will support mandatory
encryption.
CC: Stable <stable@kernel.org>
Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/connect.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2e7a79cd2b93..581654fb174d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2530,7 +2530,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
2530 | 2530 | ||
2531 | if (!CIFSSMBQFSUnixInfo(xid, tcon)) { | 2531 | if (!CIFSSMBQFSUnixInfo(xid, tcon)) { |
2532 | __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); | 2532 | __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); |
2533 | 2533 | cFYI(1, "unix caps which server supports %lld", cap); | |
2534 | /* check for reconnect case in which we do not | 2534 | /* check for reconnect case in which we do not |
2535 | want to change the mount behavior if we can avoid it */ | 2535 | want to change the mount behavior if we can avoid it */ |
2536 | if (vol_info == NULL) { | 2536 | if (vol_info == NULL) { |
@@ -2548,6 +2548,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
2548 | } | 2548 | } |
2549 | } | 2549 | } |
2550 | 2550 | ||
2551 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) | ||
2552 | cERROR(1, "per-share encryption not supported yet"); | ||
2553 | |||
2551 | cap &= CIFS_UNIX_CAP_MASK; | 2554 | cap &= CIFS_UNIX_CAP_MASK; |
2552 | if (vol_info && vol_info->no_psx_acl) | 2555 | if (vol_info && vol_info->no_psx_acl) |
2553 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; | 2556 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
@@ -2596,6 +2599,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
2596 | cFYI(1, "very large read cap"); | 2599 | cFYI(1, "very large read cap"); |
2597 | if (cap & CIFS_UNIX_LARGE_WRITE_CAP) | 2600 | if (cap & CIFS_UNIX_LARGE_WRITE_CAP) |
2598 | cFYI(1, "very large write cap"); | 2601 | cFYI(1, "very large write cap"); |
2602 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP) | ||
2603 | cFYI(1, "transport encryption cap"); | ||
2604 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) | ||
2605 | cFYI(1, "mandatory transport encryption cap"); | ||
2599 | #endif /* CIFS_DEBUG2 */ | 2606 | #endif /* CIFS_DEBUG2 */ |
2600 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | 2607 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { |
2601 | if (vol_info == NULL) { | 2608 | if (vol_info == NULL) { |
@@ -3022,20 +3029,26 @@ try_mount_again: | |||
3022 | goto remote_path_check; | 3029 | goto remote_path_check; |
3023 | } | 3030 | } |
3024 | 3031 | ||
3025 | /* do not care if following two calls succeed - informational */ | ||
3026 | if (!tcon->ipc) { | ||
3027 | CIFSSMBQFSDeviceInfo(xid, tcon); | ||
3028 | CIFSSMBQFSAttributeInfo(xid, tcon); | ||
3029 | } | ||
3030 | |||
3031 | /* tell server which Unix caps we support */ | 3032 | /* tell server which Unix caps we support */ |
3032 | if (tcon->ses->capabilities & CAP_UNIX) | 3033 | if (tcon->ses->capabilities & CAP_UNIX) { |
3033 | /* reset of caps checks mount to see if unix extensions | 3034 | /* reset of caps checks mount to see if unix extensions |
3034 | disabled for just this mount */ | 3035 | disabled for just this mount */ |
3035 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); | 3036 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); |
3036 | else | 3037 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && |
3038 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & | ||
3039 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { | ||
3040 | rc = -EACCES; | ||
3041 | goto mount_fail_check; | ||
3042 | } | ||
3043 | } else | ||
3037 | tcon->unix_ext = 0; /* server does not support them */ | 3044 | tcon->unix_ext = 0; /* server does not support them */ |
3038 | 3045 | ||
3046 | /* do not care if following two calls succeed - informational */ | ||
3047 | if (!tcon->ipc) { | ||
3048 | CIFSSMBQFSDeviceInfo(xid, tcon); | ||
3049 | CIFSSMBQFSAttributeInfo(xid, tcon); | ||
3050 | } | ||
3051 | |||
3039 | /* convert forward to back slashes in prepath here if needed */ | 3052 | /* convert forward to back slashes in prepath here if needed */ |
3040 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) | 3053 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) |
3041 | convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); | 3054 | convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); |