Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cifs: switch servers depending on binding state

Currently a lot of the code to initialize a connection & session uses
the cifs_ses as input. But depending on if we are opening a new session
or a new channel we need to use different server pointers.

Add a "binding" flag in cifs_ses and a helper function that returns
the server ptr a session should use (only in the sess establishment
code path).

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Aurelien Aptel and committed by
Steve French
f6a6bf7c f780bd3f

+33 -21
+1 -1
fs/cifs/cifs_spnego.c
··· 98 98 struct key * 99 99 cifs_get_spnego_key(struct cifs_ses *sesInfo) 100 100 { 101 - struct TCP_Server_Info *server = sesInfo->server; 101 + struct TCP_Server_Info *server = cifs_ses_server(sesInfo); 102 102 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr; 103 103 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr; 104 104 char *description, *dp;
+10
fs/cifs/cifsglob.h
··· 994 994 bool sign; /* is signing required? */ 995 995 bool need_reconnect:1; /* connection reset, uid now invalid */ 996 996 bool domainAuto:1; 997 + bool binding:1; /* are we binding the session? */ 997 998 __u16 session_flags; 998 999 __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; 999 1000 __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; ··· 1021 1020 size_t chan_max; 1022 1021 atomic_t chan_seq; /* round robin state */ 1023 1022 }; 1023 + 1024 + static inline 1025 + struct TCP_Server_Info *cifs_ses_server(struct cifs_ses *ses) 1026 + { 1027 + if (ses->binding) 1028 + return ses->chans[ses->chan_count].server; 1029 + else 1030 + return ses->server; 1031 + } 1024 1032 1025 1033 static inline bool 1026 1034 cap_unix(struct cifs_ses *ses)
+2 -2
fs/cifs/connect.c
··· 5185 5185 cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses) 5186 5186 { 5187 5187 int rc = 0; 5188 - struct TCP_Server_Info *server = ses->server; 5188 + struct TCP_Server_Info *server = cifs_ses_server(ses); 5189 5189 5190 5190 if (!server->ops->need_neg || !server->ops->negotiate) 5191 5191 return -ENOSYS; ··· 5212 5212 struct nls_table *nls_info) 5213 5213 { 5214 5214 int rc = -ENOSYS; 5215 - struct TCP_Server_Info *server = ses->server; 5215 + struct TCP_Server_Info *server = cifs_ses_server(ses); 5216 5216 5217 5217 ses->capabilities = server->capabilities; 5218 5218 if (linuxExtEnabled == 0)
+3 -2
fs/cifs/sess.c
··· 342 342 void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, 343 343 struct cifs_ses *ses) 344 344 { 345 + struct TCP_Server_Info *server = cifs_ses_server(ses); 345 346 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; 346 347 __u32 flags; 347 348 ··· 355 354 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 356 355 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC | 357 356 NTLMSSP_NEGOTIATE_SEAL; 358 - if (ses->server->sign) 357 + if (server->sign) 359 358 flags |= NTLMSSP_NEGOTIATE_SIGN; 360 - if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) 359 + if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess) 361 360 flags |= NTLMSSP_NEGOTIATE_KEY_XCH; 362 361 363 362 sec_blob->NegotiateFlags = cpu_to_le32(flags);
+1 -1
fs/cifs/smb2ops.c
··· 310 310 { 311 311 int rc; 312 312 313 - ses->server->CurrentMid = 0; 313 + cifs_ses_server(ses)->CurrentMid = 0; 314 314 rc = SMB2_negotiate(xid, ses); 315 315 /* BB we probably don't need to retry with modern servers */ 316 316 if (rc == -EAGAIN)
+16 -15
fs/cifs/smb2pdu.c
··· 791 791 struct kvec rsp_iov; 792 792 int rc = 0; 793 793 int resp_buftype; 794 - struct TCP_Server_Info *server = ses->server; 794 + struct TCP_Server_Info *server = cifs_ses_server(ses); 795 795 int blob_offset, blob_length; 796 796 char *security_blob; 797 797 int flags = CIFS_NEG_OP; ··· 813 813 memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); 814 814 memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); 815 815 816 - if (strcmp(ses->server->vals->version_string, 816 + if (strcmp(server->vals->version_string, 817 817 SMB3ANY_VERSION_STRING) == 0) { 818 818 req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); 819 819 req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); ··· 829 829 total_len += 8; 830 830 } else { 831 831 /* otherwise send specific dialect */ 832 - req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); 832 + req->Dialects[0] = cpu_to_le16(server->vals->protocol_id); 833 833 req->DialectCount = cpu_to_le16(1); 834 834 total_len += 2; 835 835 } ··· 1171 1171 int rc; 1172 1172 struct cifs_ses *ses = sess_data->ses; 1173 1173 struct smb2_sess_setup_req *req; 1174 - struct TCP_Server_Info *server = ses->server; 1174 + struct TCP_Server_Info *server = cifs_ses_server(ses); 1175 1175 unsigned int total_len; 1176 1176 1177 1177 rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, (void **) &req, ··· 1258 1258 { 1259 1259 int rc = 0; 1260 1260 struct cifs_ses *ses = sess_data->ses; 1261 + struct TCP_Server_Info *server = cifs_ses_server(ses); 1261 1262 1262 - mutex_lock(&ses->server->srv_mutex); 1263 - if (ses->server->ops->generate_signingkey) { 1264 - rc = ses->server->ops->generate_signingkey(ses); 1263 + mutex_lock(&server->srv_mutex); 1264 + if (server->ops->generate_signingkey) { 1265 + rc = server->ops->generate_signingkey(ses); 1265 1266 if (rc) { 1266 1267 cifs_dbg(FYI, 1267 1268 "SMB3 session key generation failed\n"); 1268 - mutex_unlock(&ses->server->srv_mutex); 1269 + mutex_unlock(&server->srv_mutex); 1269 1270 return rc; 1270 1271 } 1271 1272 } 1272 - if (!ses->server->session_estab) { 1273 - ses->server->sequence_number = 0x2; 1274 - ses->server->session_estab = true; 1273 + if (!server->session_estab) { 1274 + server->sequence_number = 0x2; 1275 + server->session_estab = true; 1275 1276 } 1276 - mutex_unlock(&ses->server->srv_mutex); 1277 + mutex_unlock(&server->srv_mutex); 1277 1278 1278 1279 cifs_dbg(FYI, "SMB2/3 session established successfully\n"); 1279 1280 spin_lock(&GlobalMid_Lock); ··· 1510 1509 { 1511 1510 int type; 1512 1511 1513 - type = smb2_select_sectype(ses->server, ses->sectype); 1512 + type = smb2_select_sectype(cifs_ses_server(ses), ses->sectype); 1514 1513 cifs_dbg(FYI, "sess setup type %d\n", type); 1515 1514 if (type == Unspecified) { 1516 1515 cifs_dbg(VFS, ··· 1538 1537 const struct nls_table *nls_cp) 1539 1538 { 1540 1539 int rc = 0; 1541 - struct TCP_Server_Info *server = ses->server; 1540 + struct TCP_Server_Info *server = cifs_ses_server(ses); 1542 1541 struct SMB2_sess_data *sess_data; 1543 1542 1544 1543 cifs_dbg(FYI, "Session Setup\n"); ··· 1564 1563 /* 1565 1564 * Initialize the session hash with the server one. 1566 1565 */ 1567 - memcpy(ses->preauth_sha_hash, ses->server->preauth_sha_hash, 1566 + memcpy(ses->preauth_sha_hash, server->preauth_sha_hash, 1568 1567 SMB2_PREAUTH_HASH_SIZE); 1569 1568 1570 1569 while (sess_data->func)