diff options
Diffstat (limited to '')
-rw-r--r-- | fs/smb/client/smb2pdu.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 608ee05491e2..3ea688558e6c 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -409,14 +409,15 @@ skip_sess_setup: spin_unlock(&ses->ses_lock); if (!rc && - (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { + (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) && + server->ops->query_server_interfaces) { mutex_unlock(&ses->session_mutex); /* * query server network interfaces, in case they change */ xid = get_xid(); - rc = SMB3_request_interfaces(xid, tcon, false); + rc = server->ops->query_server_interfaces(xid, tcon, false); free_xid(xid); if (rc == -EOPNOTSUPP && ses->chan_count > 1) { @@ -731,7 +732,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, pneg_ctxt += sizeof(struct smb2_posix_neg_context); neg_context_count++; - if (server->compress_algorithm) { + if (server->compression.requested) { build_compression_ctxt((struct smb2_compression_capabilities_context *) pneg_ctxt); ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8); @@ -779,6 +780,9 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, struct smb2_compression_capabilities_context *ctxt) { unsigned int len = le16_to_cpu(ctxt->DataLength); + __le16 alg; + + server->compression.enabled = false; /* * Caller checked that DataLength remains within SMB boundary. We still @@ -789,15 +793,22 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, pr_warn_once("server sent bad compression cntxt\n"); return; } + if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) { - pr_warn_once("Invalid SMB3 compress algorithm count\n"); + pr_warn_once("invalid SMB3 compress algorithm count\n"); return; } - if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) { - pr_warn_once("unknown compression algorithm\n"); + + alg = ctxt->CompressionAlgorithms[0]; + + /* 'NONE' (0) compressor type is never negotiated */ + if (alg == 0 || le16_to_cpu(alg) > 3) { + pr_warn_once("invalid compression algorithm '%u'\n", alg); return; } - server->compress_algorithm = ctxt->CompressionAlgorithms[0]; + + server->compression.alg = alg; + server->compression.enabled = true; } static int decode_encrypt_ctx(struct TCP_Server_Info *server, @@ -1536,6 +1547,11 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data) &sess_data->buf0_type, CIFS_LOG_ERROR | CIFS_SESS_OP, &rsp_iov); cifs_small_buf_release(sess_data->iov[0].iov_base); + if (rc == 0) + sess_data->ses->expired_pwd = false; + else if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) + sess_data->ses->expired_pwd = true; + memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec)); return rc; @@ -2715,6 +2731,17 @@ add_query_id_context(struct kvec *iov, unsigned int *num_iovec) return 0; } +static void add_ea_context(struct cifs_open_parms *oparms, + struct kvec *rq_iov, unsigned int *num_iovs) +{ + struct kvec *iov = oparms->ea_cctx; + + if (iov && iov->iov_base && iov->iov_len) { + rq_iov[(*num_iovs)++] = *iov; + memset(iov, 0, sizeof(*iov)); + } +} + static int alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, const char *treename, const __le16 *path) @@ -3081,6 +3108,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, } add_query_id_context(iov, &n_iov); + add_ea_context(oparms, iov, &n_iov); if (n_iov > 2) { /* |