]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cifs: SMB1 split: connect.c
authorDavid Howells <dhowells@redhat.com>
Wed, 17 Dec 2025 17:41:38 +0000 (17:41 +0000)
committerSteve French <stfrench@microsoft.com>
Sun, 8 Feb 2026 23:07:46 +0000 (17:07 -0600)
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>
fs/smb/client/cifsproto.h
fs/smb/client/cifssmb.c
fs/smb/client/connect.c
fs/smb/client/smb1ops.c
fs/smb/client/smb1proto.h

index 49ff68f3c999d516fe6155ae72f8e1d31d6bf161..96d6b5325aa33c713459b16a72f79f5acafb05c7 100644 (file)
@@ -291,31 +291,11 @@ int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
 int cifs_enable_signing(struct TCP_Server_Info *server,
                        bool mnt_sign_required);
 
-int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
-            struct cifs_tcon *tcon, const struct nls_table *nls_codepage);
-
-
-
-
-
-
-
 int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
                        unsigned int *num_of_nodes,
                        struct dfs_info3_param **target_nodes,
                        const struct nls_table *nls_codepage, int remap,
                        const char *searchName, bool is_unicode);
-void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
-                         struct cifs_sb_info *cifs_sb,
-                         struct smb3_fs_context *ctx);
-
-
-
-
-
-
-
-
 
 struct cifs_ses *sesInfoAlloc(void);
 void sesInfoFree(struct cifs_ses *buf_to_free);
index 8738fdbb5a599d4f3a11419158fe24e09722b04a..3990a901226401b3ca1151cf9b66e7f690773c2a 100644 (file)
@@ -534,6 +534,146 @@ neg_err_exit:
        return rc;
 }
 
+/*
+ * Issue a TREE_CONNECT request.
+ */
+int
+CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+        const char *tree, struct cifs_tcon *tcon,
+        const struct nls_table *nls_codepage)
+{
+       struct smb_hdr *smb_buffer;
+       struct smb_hdr *smb_buffer_response;
+       TCONX_REQ *pSMB;
+       TCONX_RSP *pSMBr;
+       unsigned char *bcc_ptr;
+       int rc = 0;
+       int length, in_len;
+       __u16 bytes_left, count;
+
+       if (ses == NULL)
+               return smb_EIO(smb_eio_trace_null_pointers);
+
+       smb_buffer = cifs_buf_get();
+       if (smb_buffer == NULL)
+               return -ENOMEM;
+
+       smb_buffer_response = smb_buffer;
+
+       in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
+                                NULL /*no tid */, 4 /*wct */);
+
+       smb_buffer->Mid = get_next_mid(ses->server);
+       smb_buffer->Uid = ses->Suid;
+       pSMB = (TCONX_REQ *) smb_buffer;
+       pSMBr = (TCONX_RSP *) smb_buffer_response;
+
+       pSMB->AndXCommand = 0xFF;
+       pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+       bcc_ptr = &pSMB->Password[0];
+
+       pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
+       *bcc_ptr = 0; /* password is null byte */
+       bcc_ptr++;              /* skip password */
+       /* already aligned so no need to do it below */
+
+       if (ses->server->sign)
+               smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+       if (ses->capabilities & CAP_STATUS32)
+               smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+
+       if (ses->capabilities & CAP_DFS)
+               smb_buffer->Flags2 |= SMBFLG2_DFS;
+
+       if (ses->capabilities & CAP_UNICODE) {
+               smb_buffer->Flags2 |= SMBFLG2_UNICODE;
+               length =
+                   cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
+                       6 /* max utf8 char length in bytes */ *
+                       (/* server len*/ + 256 /* share len */), nls_codepage);
+               bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
+               bcc_ptr += 2;   /* skip trailing null */
+       } else {                /* ASCII */
+               strcpy(bcc_ptr, tree);
+               bcc_ptr += strlen(tree) + 1;
+       }
+       strcpy(bcc_ptr, "?????");
+       bcc_ptr += strlen("?????");
+       bcc_ptr += 1;
+       count = bcc_ptr - &pSMB->Password[0];
+       in_len += count;
+       pSMB->ByteCount = cpu_to_le16(count);
+
+       rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
+                        &length, 0);
+
+       /* above now done in SendReceive */
+       if (rc == 0) {
+               bool is_unicode;
+
+               tcon->tid = smb_buffer_response->Tid;
+               bcc_ptr = pByteArea(smb_buffer_response);
+               bytes_left = get_bcc(smb_buffer_response);
+               length = strnlen(bcc_ptr, bytes_left - 2);
+               if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
+                       is_unicode = true;
+               else
+                       is_unicode = false;
+
+
+               /* skip service field (NB: this field is always ASCII) */
+               if (length == 3) {
+                       if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+                           (bcc_ptr[2] == 'C')) {
+                               cifs_dbg(FYI, "IPC connection\n");
+                               tcon->ipc = true;
+                               tcon->pipe = true;
+                       }
+               } else if (length == 2) {
+                       if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+                               /* the most common case */
+                               cifs_dbg(FYI, "disk share connection\n");
+                       }
+               }
+               bcc_ptr += length + 1;
+               bytes_left -= (length + 1);
+               strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
+
+               /* mostly informational -- no need to fail on error here */
+               kfree(tcon->nativeFileSystem);
+               tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
+                                                     bytes_left, is_unicode,
+                                                     nls_codepage);
+
+               cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
+
+               if ((smb_buffer_response->WordCount == 3) ||
+                        (smb_buffer_response->WordCount == 7))
+                       /* field is in same location */
+                       tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
+               else
+                       tcon->Flags = 0;
+               cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
+
+               /*
+                * reset_cifs_unix_caps calls QFSInfo which requires
+                * need_reconnect to be false, but we would not need to call
+                * reset_caps if this were not a reconnect case so must check
+                * need_reconnect flag here.  The caller will also clear
+                * need_reconnect when tcon was successful but needed to be
+                * cleared earlier in the case of unix extensions reconnect
+                */
+               if (tcon->need_reconnect && tcon->unix_ext) {
+                       cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
+                       tcon->need_reconnect = false;
+                       reset_cifs_unix_caps(xid, tcon, NULL, NULL);
+               }
+       }
+       cifs_buf_release(smb_buffer);
+       return rc;
+}
+
 int
 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
 {
index 756384636ac81f477d12cd11eec76e65948c0110..1b479561cbf9157dcfe8086b756b1111c13a2044 100644 (file)
@@ -3466,115 +3466,6 @@ ip_connect(struct TCP_Server_Info *server)
        return generic_ip_connect(server);
 }
 
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
-                         struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
-{
-       /*
-        * If we are reconnecting then should we check to see if
-        * any requested capabilities changed locally e.g. via
-        * remount but we can not do much about it here
-        * if they have (even if we could detect it by the following)
-        * Perhaps we could add a backpointer to array of sb from tcon
-        * or if we change to make all sb to same share the same
-        * sb as NFS - then we only have one backpointer to sb.
-        * What if we wanted to mount the server share twice once with
-        * and once without posixacls or posix paths?
-        */
-       __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-
-       if (ctx && ctx->no_linux_ext) {
-               tcon->fsUnixInfo.Capability = 0;
-               tcon->unix_ext = 0; /* Unix Extensions disabled */
-               cifs_dbg(FYI, "Linux protocol extensions disabled\n");
-               return;
-       } else if (ctx)
-               tcon->unix_ext = 1; /* Unix Extensions supported */
-
-       if (!tcon->unix_ext) {
-               cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
-               return;
-       }
-
-       if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
-               __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-
-               cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
-               /*
-                * check for reconnect case in which we do not
-                * want to change the mount behavior if we can avoid it
-                */
-               if (ctx == NULL) {
-                       /*
-                        * turn off POSIX ACL and PATHNAMES if not set
-                        * originally at mount time
-                        */
-                       if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
-                               cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
-                       if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
-                               if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                                       cifs_dbg(VFS, "POSIXPATH support change\n");
-                               cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
-                       } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
-                               cifs_dbg(VFS, "possible reconnect error\n");
-                               cifs_dbg(VFS, "server disabled POSIX path support\n");
-                       }
-               }
-
-               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
-                       cifs_dbg(VFS, "per-share encryption not supported yet\n");
-
-               cap &= CIFS_UNIX_CAP_MASK;
-               if (ctx && ctx->no_psx_acl)
-                       cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
-               else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
-                       cifs_dbg(FYI, "negotiated posix acl support\n");
-                       if (cifs_sb)
-                               cifs_sb->mnt_cifs_flags |=
-                                       CIFS_MOUNT_POSIXACL;
-               }
-
-               if (ctx && ctx->posix_paths == 0)
-                       cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
-               else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
-                       cifs_dbg(FYI, "negotiate posix pathnames\n");
-                       if (cifs_sb)
-                               cifs_sb->mnt_cifs_flags |=
-                                       CIFS_MOUNT_POSIX_PATHS;
-               }
-
-               cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
-#ifdef CONFIG_CIFS_DEBUG2
-               if (cap & CIFS_UNIX_FCNTL_CAP)
-                       cifs_dbg(FYI, "FCNTL cap\n");
-               if (cap & CIFS_UNIX_EXTATTR_CAP)
-                       cifs_dbg(FYI, "EXTATTR cap\n");
-               if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                       cifs_dbg(FYI, "POSIX path cap\n");
-               if (cap & CIFS_UNIX_XATTR_CAP)
-                       cifs_dbg(FYI, "XATTR cap\n");
-               if (cap & CIFS_UNIX_POSIX_ACL_CAP)
-                       cifs_dbg(FYI, "POSIX ACL cap\n");
-               if (cap & CIFS_UNIX_LARGE_READ_CAP)
-                       cifs_dbg(FYI, "very large read cap\n");
-               if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
-                       cifs_dbg(FYI, "very large write cap\n");
-               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
-                       cifs_dbg(FYI, "transport encryption cap\n");
-               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
-                       cifs_dbg(FYI, "mandatory transport encryption cap\n");
-#endif /* CIFS_DEBUG2 */
-               if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
-                       if (ctx == NULL)
-                               cifs_dbg(FYI, "resetting capabilities failed\n");
-                       else
-                               cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
-
-               }
-       }
-}
-#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
-
 int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
 {
        struct smb3_fs_context *ctx = cifs_sb->ctx;
@@ -4053,148 +3944,6 @@ error:
 }
 #endif
 
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-/*
- * Issue a TREE_CONNECT request.
- */
-int
-CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-        const char *tree, struct cifs_tcon *tcon,
-        const struct nls_table *nls_codepage)
-{
-       struct smb_hdr *smb_buffer;
-       struct smb_hdr *smb_buffer_response;
-       TCONX_REQ *pSMB;
-       TCONX_RSP *pSMBr;
-       unsigned char *bcc_ptr;
-       int rc = 0;
-       int length, in_len;
-       __u16 bytes_left, count;
-
-       if (ses == NULL)
-               return smb_EIO(smb_eio_trace_null_pointers);
-
-       smb_buffer = cifs_buf_get();
-       if (smb_buffer == NULL)
-               return -ENOMEM;
-
-       smb_buffer_response = smb_buffer;
-
-       in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
-                                NULL /*no tid */, 4 /*wct */);
-
-       smb_buffer->Mid = get_next_mid(ses->server);
-       smb_buffer->Uid = ses->Suid;
-       pSMB = (TCONX_REQ *) smb_buffer;
-       pSMBr = (TCONX_RSP *) smb_buffer_response;
-
-       pSMB->AndXCommand = 0xFF;
-       pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
-       bcc_ptr = &pSMB->Password[0];
-
-       pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
-       *bcc_ptr = 0; /* password is null byte */
-       bcc_ptr++;              /* skip password */
-       /* already aligned so no need to do it below */
-
-       if (ses->server->sign)
-               smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
-       if (ses->capabilities & CAP_STATUS32)
-               smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-
-       if (ses->capabilities & CAP_DFS)
-               smb_buffer->Flags2 |= SMBFLG2_DFS;
-
-       if (ses->capabilities & CAP_UNICODE) {
-               smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-               length =
-                   cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
-                       6 /* max utf8 char length in bytes */ *
-                       (/* server len*/ + 256 /* share len */), nls_codepage);
-               bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
-               bcc_ptr += 2;   /* skip trailing null */
-       } else {                /* ASCII */
-               strcpy(bcc_ptr, tree);
-               bcc_ptr += strlen(tree) + 1;
-       }
-       strcpy(bcc_ptr, "?????");
-       bcc_ptr += strlen("?????");
-       bcc_ptr += 1;
-       count = bcc_ptr - &pSMB->Password[0];
-       in_len += count;
-       pSMB->ByteCount = cpu_to_le16(count);
-
-       rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
-                        &length, 0);
-
-       /* above now done in SendReceive */
-       if (rc == 0) {
-               bool is_unicode;
-
-               tcon->tid = smb_buffer_response->Tid;
-               bcc_ptr = pByteArea(smb_buffer_response);
-               bytes_left = get_bcc(smb_buffer_response);
-               length = strnlen(bcc_ptr, bytes_left - 2);
-               if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
-                       is_unicode = true;
-               else
-                       is_unicode = false;
-
-
-               /* skip service field (NB: this field is always ASCII) */
-               if (length == 3) {
-                       if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
-                           (bcc_ptr[2] == 'C')) {
-                               cifs_dbg(FYI, "IPC connection\n");
-                               tcon->ipc = true;
-                               tcon->pipe = true;
-                       }
-               } else if (length == 2) {
-                       if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
-                               /* the most common case */
-                               cifs_dbg(FYI, "disk share connection\n");
-                       }
-               }
-               bcc_ptr += length + 1;
-               bytes_left -= (length + 1);
-               strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
-
-               /* mostly informational -- no need to fail on error here */
-               kfree(tcon->nativeFileSystem);
-               tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
-                                                     bytes_left, is_unicode,
-                                                     nls_codepage);
-
-               cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
-
-               if ((smb_buffer_response->WordCount == 3) ||
-                        (smb_buffer_response->WordCount == 7))
-                       /* field is in same location */
-                       tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
-               else
-                       tcon->Flags = 0;
-               cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
-
-               /*
-                * reset_cifs_unix_caps calls QFSInfo which requires
-                * need_reconnect to be false, but we would not need to call
-                * reset_caps if this were not a reconnect case so must check
-                * need_reconnect flag here.  The caller will also clear
-                * need_reconnect when tcon was successful but needed to be
-                * cleared earlier in the case of unix extensions reconnect
-                */
-               if (tcon->need_reconnect && tcon->unix_ext) {
-                       cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
-                       tcon->need_reconnect = false;
-                       reset_cifs_unix_caps(xid, tcon, NULL, NULL);
-               }
-       }
-       cifs_buf_release(smb_buffer);
-       return rc;
-}
-#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
-
 static void delayed_free(struct rcu_head *p)
 {
        struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
index 65d55a81b1b2972c0e8b6e603e3a5a2901432799..9c3b97d2a20aa53dc2ee4b9b56523cfde4c8e466 100644 (file)
 #include "smberr.h"
 #include "reparse.h"
 
+void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
+                         struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+{
+       /*
+        * If we are reconnecting then should we check to see if
+        * any requested capabilities changed locally e.g. via
+        * remount but we can not do much about it here
+        * if they have (even if we could detect it by the following)
+        * Perhaps we could add a backpointer to array of sb from tcon
+        * or if we change to make all sb to same share the same
+        * sb as NFS - then we only have one backpointer to sb.
+        * What if we wanted to mount the server share twice once with
+        * and once without posixacls or posix paths?
+        */
+       __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+
+       if (ctx && ctx->no_linux_ext) {
+               tcon->fsUnixInfo.Capability = 0;
+               tcon->unix_ext = 0; /* Unix Extensions disabled */
+               cifs_dbg(FYI, "Linux protocol extensions disabled\n");
+               return;
+       } else if (ctx)
+               tcon->unix_ext = 1; /* Unix Extensions supported */
+
+       if (!tcon->unix_ext) {
+               cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
+               return;
+       }
+
+       if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
+               __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+
+               cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
+               /*
+                * check for reconnect case in which we do not
+                * want to change the mount behavior if we can avoid it
+                */
+               if (ctx == NULL) {
+                       /*
+                        * turn off POSIX ACL and PATHNAMES if not set
+                        * originally at mount time
+                        */
+                       if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
+                               cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
+                       if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+                               if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+                                       cifs_dbg(VFS, "POSIXPATH support change\n");
+                               cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
+                       } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+                               cifs_dbg(VFS, "possible reconnect error\n");
+                               cifs_dbg(VFS, "server disabled POSIX path support\n");
+                       }
+               }
+
+               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
+                       cifs_dbg(VFS, "per-share encryption not supported yet\n");
+
+               cap &= CIFS_UNIX_CAP_MASK;
+               if (ctx && ctx->no_psx_acl)
+                       cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
+               else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
+                       cifs_dbg(FYI, "negotiated posix acl support\n");
+                       if (cifs_sb)
+                               cifs_sb->mnt_cifs_flags |=
+                                       CIFS_MOUNT_POSIXACL;
+               }
+
+               if (ctx && ctx->posix_paths == 0)
+                       cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
+               else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+                       cifs_dbg(FYI, "negotiate posix pathnames\n");
+                       if (cifs_sb)
+                               cifs_sb->mnt_cifs_flags |=
+                                       CIFS_MOUNT_POSIX_PATHS;
+               }
+
+               cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
+#ifdef CONFIG_CIFS_DEBUG2
+               if (cap & CIFS_UNIX_FCNTL_CAP)
+                       cifs_dbg(FYI, "FCNTL cap\n");
+               if (cap & CIFS_UNIX_EXTATTR_CAP)
+                       cifs_dbg(FYI, "EXTATTR cap\n");
+               if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+                       cifs_dbg(FYI, "POSIX path cap\n");
+               if (cap & CIFS_UNIX_XATTR_CAP)
+                       cifs_dbg(FYI, "XATTR cap\n");
+               if (cap & CIFS_UNIX_POSIX_ACL_CAP)
+                       cifs_dbg(FYI, "POSIX ACL cap\n");
+               if (cap & CIFS_UNIX_LARGE_READ_CAP)
+                       cifs_dbg(FYI, "very large read cap\n");
+               if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
+                       cifs_dbg(FYI, "very large write cap\n");
+               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
+                       cifs_dbg(FYI, "transport encryption cap\n");
+               if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
+                       cifs_dbg(FYI, "mandatory transport encryption cap\n");
+#endif /* CIFS_DEBUG2 */
+               if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
+                       if (ctx == NULL)
+                               cifs_dbg(FYI, "resetting capabilities failed\n");
+                       else
+                               cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
+
+               }
+       }
+}
+
 /*
  * An NT cancel request header looks just like the original request except:
  *
index 446aa1f18f7605d29789df46ad73bca0896c3d30..d326952e28af59924d71aed924e3423278fac2f0 100644 (file)
@@ -32,6 +32,8 @@ int small_smb_init_no_tc(const int smb_command, const int wct,
                         struct cifs_ses *ses, void **request_buf);
 int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses,
                     struct TCP_Server_Info *server);
+int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
+            struct cifs_tcon *tcon, const struct nls_table *nls_codepage);
 int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon);
 int CIFSSMBEcho(struct TCP_Server_Info *server);
 int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
@@ -249,6 +251,10 @@ unsigned int smbCalcSize(void *buf);
 extern struct smb_version_operations smb1_operations;
 extern struct smb_version_values smb1_values;
 
+void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
+                         struct cifs_sb_info *cifs_sb,
+                         struct smb3_fs_context *ctx);
+
 /*
  * smb1session.c
  */