Skip to content

Commit 88f7d7e

Browse files
dhowellssmfrench
authored andcommitted
cifs: SMB1 split: connect.c
Split SMB1-specific connection management stuff to smb1ops.c and move CIFSTCon() to cifssmb.c. Signed-off-by: David Howells <dhowells@redhat.com> cc: Steve French <sfrench@samba.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Enzo Matsumiya <ematsumiya@suse.de> cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-kernel@vger.kernel.org Acked-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent dec5a51 commit 88f7d7e

5 files changed

Lines changed: 253 additions & 271 deletions

File tree

fs/smb/client/cifsproto.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -291,31 +291,11 @@ int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
291291
int cifs_enable_signing(struct TCP_Server_Info *server,
292292
bool mnt_sign_required);
293293

294-
int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
295-
struct cifs_tcon *tcon, const struct nls_table *nls_codepage);
296-
297-
298-
299-
300-
301-
302-
303294
int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
304295
unsigned int *num_of_nodes,
305296
struct dfs_info3_param **target_nodes,
306297
const struct nls_table *nls_codepage, int remap,
307298
const char *searchName, bool is_unicode);
308-
void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
309-
struct cifs_sb_info *cifs_sb,
310-
struct smb3_fs_context *ctx);
311-
312-
313-
314-
315-
316-
317-
318-
319299

320300
struct cifs_ses *sesInfoAlloc(void);
321301
void sesInfoFree(struct cifs_ses *buf_to_free);

fs/smb/client/cifssmb.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,146 @@ CIFSSMBNegotiate(const unsigned int xid,
534534
return rc;
535535
}
536536

537+
/*
538+
* Issue a TREE_CONNECT request.
539+
*/
540+
int
541+
CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
542+
const char *tree, struct cifs_tcon *tcon,
543+
const struct nls_table *nls_codepage)
544+
{
545+
struct smb_hdr *smb_buffer;
546+
struct smb_hdr *smb_buffer_response;
547+
TCONX_REQ *pSMB;
548+
TCONX_RSP *pSMBr;
549+
unsigned char *bcc_ptr;
550+
int rc = 0;
551+
int length, in_len;
552+
__u16 bytes_left, count;
553+
554+
if (ses == NULL)
555+
return smb_EIO(smb_eio_trace_null_pointers);
556+
557+
smb_buffer = cifs_buf_get();
558+
if (smb_buffer == NULL)
559+
return -ENOMEM;
560+
561+
smb_buffer_response = smb_buffer;
562+
563+
in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
564+
NULL /*no tid */, 4 /*wct */);
565+
566+
smb_buffer->Mid = get_next_mid(ses->server);
567+
smb_buffer->Uid = ses->Suid;
568+
pSMB = (TCONX_REQ *) smb_buffer;
569+
pSMBr = (TCONX_RSP *) smb_buffer_response;
570+
571+
pSMB->AndXCommand = 0xFF;
572+
pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
573+
bcc_ptr = &pSMB->Password[0];
574+
575+
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
576+
*bcc_ptr = 0; /* password is null byte */
577+
bcc_ptr++; /* skip password */
578+
/* already aligned so no need to do it below */
579+
580+
if (ses->server->sign)
581+
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
582+
583+
if (ses->capabilities & CAP_STATUS32)
584+
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
585+
586+
if (ses->capabilities & CAP_DFS)
587+
smb_buffer->Flags2 |= SMBFLG2_DFS;
588+
589+
if (ses->capabilities & CAP_UNICODE) {
590+
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
591+
length =
592+
cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
593+
6 /* max utf8 char length in bytes */ *
594+
(/* server len*/ + 256 /* share len */), nls_codepage);
595+
bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
596+
bcc_ptr += 2; /* skip trailing null */
597+
} else { /* ASCII */
598+
strcpy(bcc_ptr, tree);
599+
bcc_ptr += strlen(tree) + 1;
600+
}
601+
strcpy(bcc_ptr, "?????");
602+
bcc_ptr += strlen("?????");
603+
bcc_ptr += 1;
604+
count = bcc_ptr - &pSMB->Password[0];
605+
in_len += count;
606+
pSMB->ByteCount = cpu_to_le16(count);
607+
608+
rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
609+
&length, 0);
610+
611+
/* above now done in SendReceive */
612+
if (rc == 0) {
613+
bool is_unicode;
614+
615+
tcon->tid = smb_buffer_response->Tid;
616+
bcc_ptr = pByteArea(smb_buffer_response);
617+
bytes_left = get_bcc(smb_buffer_response);
618+
length = strnlen(bcc_ptr, bytes_left - 2);
619+
if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
620+
is_unicode = true;
621+
else
622+
is_unicode = false;
623+
624+
625+
/* skip service field (NB: this field is always ASCII) */
626+
if (length == 3) {
627+
if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
628+
(bcc_ptr[2] == 'C')) {
629+
cifs_dbg(FYI, "IPC connection\n");
630+
tcon->ipc = true;
631+
tcon->pipe = true;
632+
}
633+
} else if (length == 2) {
634+
if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
635+
/* the most common case */
636+
cifs_dbg(FYI, "disk share connection\n");
637+
}
638+
}
639+
bcc_ptr += length + 1;
640+
bytes_left -= (length + 1);
641+
strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
642+
643+
/* mostly informational -- no need to fail on error here */
644+
kfree(tcon->nativeFileSystem);
645+
tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
646+
bytes_left, is_unicode,
647+
nls_codepage);
648+
649+
cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
650+
651+
if ((smb_buffer_response->WordCount == 3) ||
652+
(smb_buffer_response->WordCount == 7))
653+
/* field is in same location */
654+
tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
655+
else
656+
tcon->Flags = 0;
657+
cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
658+
659+
/*
660+
* reset_cifs_unix_caps calls QFSInfo which requires
661+
* need_reconnect to be false, but we would not need to call
662+
* reset_caps if this were not a reconnect case so must check
663+
* need_reconnect flag here. The caller will also clear
664+
* need_reconnect when tcon was successful but needed to be
665+
* cleared earlier in the case of unix extensions reconnect
666+
*/
667+
if (tcon->need_reconnect && tcon->unix_ext) {
668+
cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
669+
tcon->need_reconnect = false;
670+
reset_cifs_unix_caps(xid, tcon, NULL, NULL);
671+
}
672+
}
673+
cifs_buf_release(smb_buffer);
674+
return rc;
675+
}
676+
537677
int
538678
CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
539679
{

0 commit comments

Comments
 (0)