提交 6848b733 编写于 作者: S Steve French

[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: NPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: NSteve French <sfrench@us.ibm.com>
上级 fa2989f4
...@@ -2530,7 +2530,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2530,7 +2530,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
if (!CIFSSMBQFSUnixInfo(xid, tcon)) { if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
cFYI(1, "unix caps which server supports %lld", cap);
/* check for reconnect case in which we do not /* check for reconnect case in which we do not
want to change the mount behavior if we can avoid it */ want to change the mount behavior if we can avoid it */
if (vol_info == NULL) { if (vol_info == NULL) {
...@@ -2548,6 +2548,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2548,6 +2548,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
} }
} }
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
cERROR(1, "per-share encryption not supported yet");
cap &= CIFS_UNIX_CAP_MASK; cap &= CIFS_UNIX_CAP_MASK;
if (vol_info && vol_info->no_psx_acl) if (vol_info && vol_info->no_psx_acl)
cap &= ~CIFS_UNIX_POSIX_ACL_CAP; cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
...@@ -2596,6 +2599,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2596,6 +2599,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
cFYI(1, "very large read cap"); cFYI(1, "very large read cap");
if (cap & CIFS_UNIX_LARGE_WRITE_CAP) if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
cFYI(1, "very large write cap"); cFYI(1, "very large write cap");
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
cFYI(1, "transport encryption cap");
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
cFYI(1, "mandatory transport encryption cap");
#endif /* CIFS_DEBUG2 */ #endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
if (vol_info == NULL) { if (vol_info == NULL) {
...@@ -3022,20 +3029,26 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -3022,20 +3029,26 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
goto remote_path_check; goto remote_path_check;
} }
/* do not care if following two calls succeed - informational */
if (!tcon->ipc) {
CIFSSMBQFSDeviceInfo(xid, tcon);
CIFSSMBQFSAttributeInfo(xid, tcon);
}
/* tell server which Unix caps we support */ /* tell server which Unix caps we support */
if (tcon->ses->capabilities & CAP_UNIX) if (tcon->ses->capabilities & CAP_UNIX) {
/* reset of caps checks mount to see if unix extensions /* reset of caps checks mount to see if unix extensions
disabled for just this mount */ disabled for just this mount */
reset_cifs_unix_caps(xid, tcon, sb, volume_info); reset_cifs_unix_caps(xid, tcon, sb, volume_info);
else if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
(le64_to_cpu(tcon->fsUnixInfo.Capability) &
CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
rc = -EACCES;
goto mount_fail_check;
}
} else
tcon->unix_ext = 0; /* server does not support them */ tcon->unix_ext = 0; /* server does not support them */
/* do not care if following two calls succeed - informational */
if (!tcon->ipc) {
CIFSSMBQFSDeviceInfo(xid, tcon);
CIFSSMBQFSAttributeInfo(xid, tcon);
}
/* convert forward to back slashes in prepath here if needed */ /* convert forward to back slashes in prepath here if needed */
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册