[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Mon Dec 5 16:07:01 UTC 2022


The branch, master has been updated
       via  6ea1af287ee smbd: Simplify symlink_target_below_conn()
       via  f31fb6e1ad0 smbd: Simplify readlink_talloc()
       via  453f846e189 smbd: No dfs_filename_convert() in filename_convert_smb1_search_path()
       via  71772c48f24 libsmb: Remove sync cli_posix_readlink() wrapper
       via  a7f4ed09084 smbclient: Use cli_readlink
       via  f17131020ec libsmb: Make readlink issue posix_readlink
       via  4be2569c002 smbd: Fix a comment
       via  a1a0a7119d7 smbd: Slightly simplify smb_posix_unlink()
       via  0996ccdb821 tests: Test error codes for SET_REPARSE_POINT
       via  96580c8e195 tests: Try setting a 0-sized reparse point
       via  b58f5f3379a tests: Ignore symlink trusts flags in symlink error returns
       via  ec86c377238 pylibsmb: Add symlink flags
       via  7239d756290 lib: Add symlink trust flags from dochelp
       via  f10f259eaeb tests: Fix use of self.assertRaises()
       via  73233bc341e tests: Show that we can write to a reparse point file
       via  62302849dd9 tests: Show that a directory with a reparse point can't be populated
       via  7fe3fab655e tests: IO_REPARSE_TAG_NOT_HANDLED is acceptable for unlink
      from  ef8c8ac54cd s3:utils: Fix stack smashing in net offlinejoin

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6ea1af287eef832641464c6f764ea84a484a06f7
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 4 12:16:39 2022 +0100

    smbd: Simplify symlink_target_below_conn()
    
    readlink_talloc() deals exactly the same way with a NULL relname
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Mon Dec  5 16:06:51 UTC 2022 on sn-devel-184

commit f31fb6e1ad0664fdba351822ec754c0d1b771657
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 4 12:14:12 2022 +0100

    smbd: Simplify readlink_talloc()
    
    SMB_VFS_READLINKAT() just looks at the basename, we can avoid the
    relname being talloc'ed
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 453f846e1897f7cbcc454f3095eb21d7ffb32be8
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Oct 24 19:56:31 2022 +0200

    smbd: No dfs_filename_convert() in filename_convert_smb1_search_path()
    
    We further down call filename_convert_dirfsp(), which also has this
    call. No need to copy that code here as well.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 71772c48f241bdc048f99f297b5e0a77fdfda253
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 4 11:07:09 2022 +0100

    libsmb: Remove sync cli_posix_readlink() wrapper
    
    cli_readlink() now covers smb1 posix extensions as well
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a7f4ed090845023069693412033da803edc32a31
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 12 20:38:14 2022 +0200

    smbclient: Use cli_readlink
    
    Make smbclient's readlink command also work for SMB2 reparse style
    symlink.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f17131020ec23c5b88f56b4c8f4dfd4d3e88d6a2
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 12 20:35:10 2022 +0200

    libsmb: Make readlink issue posix_readlink
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 4be2569c002a8d592e08b0f1fb8b85154082e4a5
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Oct 11 17:01:28 2022 +0200

    smbd: Fix a comment
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a1a0a7119d746b884de43db6466b9e064d124a87
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 12 07:27:36 2022 +0200

    smbd: Slightly simplify smb_posix_unlink()
    
    We did check VALID_STAT() above.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 0996ccdb821692f037eb1f6f2c01490aa7ab062e
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:34:55 2022 +0100

    tests: Test error codes for SET_REPARSE_POINT
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit 96580c8e1957776a8564fc73363f30259827a686
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:20:06 2022 +0100

    tests: Try setting a 0-sized reparse point
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit b58f5f3379abac496d27f6afc0e31c8b874aa851
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:17:15 2022 +0100

    tests: Ignore symlink trusts flags in symlink error returns
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit ec86c377238ccc4e00b36ed3c9fe203a19a8139b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:10:12 2022 +0100

    pylibsmb: Add symlink flags
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit 7239d756290292f5056ea0235630e8413ef5960f
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:06:31 2022 +0100

    lib: Add symlink trust flags from dochelp
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit f10f259eaebdb98f5e0827482e98f5abeb65e55c
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 09:26:56 2022 +0100

    tests: Fix use of self.assertRaises()
    
    The with statement creates a new variable. I thought it opens a block
    where "e" is only valid in that block. But instead it runs the whole
    thing, expecting an exception somewhere. Learning python....
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit 73233bc341e0dfe6cb61a638707567e79e639b28
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 15:14:03 2022 +0100

    tests: Show that we can write to a reparse point file
    
    Works against Windows 2016
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit 62302849dd9477a46684462db4106664d8d787e9
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 14:49:37 2022 +0100

    tests: Show that a directory with a reparse point can't be populated
    
    Works against Windows 2016
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

commit 7fe3fab655e92d8906f196d7984a2cd99e8462c1
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 14:48:46 2022 +0100

    tests: IO_REPARSE_TAG_NOT_HANDLED is acceptable for unlink
    
    This happens when a path has an unknown reparse point in the middle
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb_constants.h          | 11 +++++
 python/samba/tests/reparsepoints.py | 84 ++++++++++++++++++++++++++++++++++---
 python/samba/tests/smb2symlink.py   | 56 +++++++++++++++----------
 source3/client/client.c             | 16 ++-----
 source3/libsmb/clifile.c            | 42 -------------------
 source3/libsmb/clisymlink.c         | 47 +++++++++++++++++++++
 source3/libsmb/proto.h              |  5 ---
 source3/libsmb/pylibsmb.c           |  7 ++++
 source3/smbd/filename.c             | 23 ----------
 source3/smbd/files.c                | 10 ++---
 source3/smbd/open.c                 | 16 +++----
 source3/smbd/smb2_trans2.c          |  2 +-
 source3/torture/test_posix.c        | 11 +++--
 source3/torture/torture.c           |  2 +-
 14 files changed, 202 insertions(+), 130 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index 876ea63f2b9..a08b1931277 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -624,4 +624,15 @@ enum csc_policy {
  */
 #define SYMLINK_ERROR_TAG	     0x4C4D5953
 
+/*
+ * Flags according to answer from Dochelp:
+ * https://lists.samba.org/archive/cifs-protocol/2022-November/003909.html
+ */
+#define SYMLINK_ADMIN           0x20000000   /* The symlink creator is an admin */
+#define SYMLINK_UNTRUSTED       0x10000000   /* The symlink creator is untrusted */
+#define SYMLINK_TRUST_UNKNOWN   0x00000000   /* The symlink creator is unknown/legacy */
+
+#define SYMLINK_TRUST_MASK      0x30000000   /* Encodes the redirection trust level (maps to REDIRECTION_TRUST_LEVEL) */
+#define SYMLINK_TRUST_SHIFT     28           /* Bits to shift to convert to/from REDIRECTION_TRUST_LEVEL */
+
 #endif /* _SMB_CONSTANTS_H */
diff --git a/python/samba/tests/reparsepoints.py b/python/samba/tests/reparsepoints.py
index 07abdb03975..95c41d18525 100644
--- a/python/samba/tests/reparsepoints.py
+++ b/python/samba/tests/reparsepoints.py
@@ -41,6 +41,7 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
             err = e.args[0]
             ok = (err == ntstatus.NT_STATUS_OBJECT_NAME_NOT_FOUND)
             ok |= (err == ntstatus.NT_STATUS_OBJECT_PATH_NOT_FOUND)
+            ok |= (err == ntstatus.NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED)
             if not ok:
                 raise
 
@@ -56,7 +57,9 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
 
         with self.assertRaises(NTSTATUSError) as e:
             conn.fsctl(fd, libsmb.FSCTL_GET_REPARSE_POINT, b'', 1024)
-            self.assertEqual(e.args[0], ntstatus.NT_STATUS_NOT_A_REPARSE_POINT)
+
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_NOT_A_REPARSE_POINT)
 
         conn.close(fd)
 
@@ -71,28 +74,97 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
             filename,
             DesiredAccess=sec.SEC_FILE_WRITE_ATTRIBUTE,
             CreateDisposition=libsmb.FILE_CREATE)
+
+        with self.assertRaises(NTSTATUSError) as e:
+            conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b'', 0)
+
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_INVALID_BUFFER_SIZE)
+
+        for i in range(1,15):
+            with self.assertRaises(NTSTATUSError) as e:
+                conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, i * b'0', 0)
+
+            self.assertEqual(e.exception.args[0],
+                             ntstatus.NT_STATUS_IO_REPARSE_DATA_INVALID)
+
+        # Create a syntactically valid [MS-FSCC] 2.1.2.2 REPARSE_DATA_BUFFER
         b = reparse_symlink.put(0x80000025, 0, b'asdfasdfasdfasdfasdfasdf')
+
+        # Show that SET_REPARSE_POINT does exact length checks
+
+        with self.assertRaises(NTSTATUSError) as e:
+            conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b + b'0', 0)
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_IO_REPARSE_DATA_INVALID)
+
+        with self.assertRaises(NTSTATUSError) as e:
+            conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b[:-1], 0)
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_IO_REPARSE_DATA_INVALID)
+
         conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
         b = reparse_symlink.put(0x80000026, 0, b'asdfasdfasdfasdfasdfasdf')
         conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
 
+    # Show that we can write to a reparse point when opened properly
+    def test_write_reparse(self):
+        conn = self.connection()
+        filename = 'reparse'
+        self.clean_file(conn, filename)
+
+        fd = conn.create(
+            filename,
+            DesiredAccess=sec.SEC_FILE_WRITE_ATTRIBUTE,
+            CreateDisposition=libsmb.FILE_CREATE)
+        b = reparse_symlink.put(0x80000025, 0, b'asdfasdfasdfasdfasdfasdf')
+        conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
+        conn.close(fd);
+
+        fd,cr,_ = conn.create_ex(
+            filename,
+            DesiredAccess=sec.SEC_FILE_WRITE_DATA|sec.SEC_STD_DELETE,
+            CreateOptions=libsmb.FILE_OPEN_REPARSE_POINT,
+            CreateDisposition=libsmb.FILE_OPEN)
+        self.assertEqual(
+            cr['file_attributes'] & libsmb.FILE_ATTRIBUTE_REPARSE_POINT,
+            libsmb.FILE_ATTRIBUTE_REPARSE_POINT)
+
+        conn.write(fd, b'x', 1)
+
+        conn.delete_on_close(fd, 1)
+        conn.close(fd);
+
     # Show that directories can carry reparse points
 
     def test_create_reparse_directory(self):
         conn = self.connection()
         dirname = "reparse_dir"
+        filename = f'{dirname}\\file.txt'
 
+        self.clean_file(conn, filename)
         self.clean_file(conn, dirname)
 
-        fd = conn.create(
+        dir_fd = conn.create(
             dirname,
             DesiredAccess=sec.SEC_FILE_WRITE_ATTRIBUTE|
             sec.SEC_STD_DELETE,
             CreateDisposition=libsmb.FILE_CREATE,
             CreateOptions=libsmb.FILE_DIRECTORY_FILE)
         b = reparse_symlink.put(0x80000025, 0, b'asdfasdfasdfasdfasdfasdf')
-        conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
-        conn.delete_on_close(fd, 1)
+        conn.fsctl(dir_fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
+
+        with self.assertRaises(NTSTATUSError) as e:
+            fd = conn.create(
+                filename,
+                DesiredAccess=sec.SEC_STD_DELETE,
+                CreateDisposition=libsmb.FILE_CREATE)
+
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED)
+
+        conn.delete_on_close(dir_fd, 1)
+        conn.close(dir_fd);
 
     # Only empty directories can carry reparse points
 
@@ -157,7 +229,9 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
                 DesiredAccess=sec.SEC_FILE_READ_DATA,
                 CreateDisposition=libsmb.FILE_OPEN,
                 CreateOptions=libsmb.FILE_OPEN_REPARSE_POINT)
-            self.assertEqual(e.args[0], ntstatus.NT_STATUS_SHARING_VIOLATION)
+
+        self.assertEqual(e.exception.args[0],
+                         ntstatus.NT_STATUS_SHARING_VIOLATION)
 
         conn.delete_on_close(fd1, 1);
         conn.close(fd1)
diff --git a/python/samba/tests/smb2symlink.py b/python/samba/tests/smb2symlink.py
index e918ade45bb..14f6056ac15 100644
--- a/python/samba/tests/smb2symlink.py
+++ b/python/samba/tests/smb2symlink.py
@@ -78,7 +78,13 @@ class Smb2SymlinkTests(samba.tests.libsmb.LibsmbTests):
     def assert_symlink_exception(self, e, expect):
         self.assertEqual(e.args[0], ntstatus.NT_STATUS_STOPPED_ON_SYMLINK)
         for k,v in expect.items():
-            self.assertEqual((k,e.args[2].get(k)), (k,v))
+            if (k == "flags"):
+                # Ignore symlink trust flags for now
+                expected = v & ~libsmb.SYMLINK_TRUST_MASK
+                got = e.args[2].get(k) & ~libsmb.SYMLINK_TRUST_MASK
+                self.assertEqual((k,got), (k,expected))
+            else:
+                self.assertEqual((k,e.args[2].get(k)), (k,v))
 
     def test_symlinkerror_directory(self):
         """Test a symlink in a nonterminal path component"""
@@ -91,11 +97,13 @@ class Smb2SymlinkTests(samba.tests.libsmb.LibsmbTests):
 
         with self.assertRaises(NTSTATUSError) as e:
             fd = smb2.create_ex(f'{symlink}\\{suffix}')
-            self.assert_symlink_exception(
-                e, { 'unparsed_path_length' : len(suffix)+1,
-                     'substitute_name' : target,
-                     'print_name' : target,
-                     'flags' : 0x20000001 })
+
+        self.assert_symlink_exception(
+            e.exception,
+            { 'unparsed_path_length' : len(suffix)+1,
+              'substitute_name' : target,
+              'print_name' : target,
+              'flags' : 0x20000001 })
 
         self.clean_file(smb1, symlink)
 
@@ -109,11 +117,13 @@ class Smb2SymlinkTests(samba.tests.libsmb.LibsmbTests):
 
         with self.assertRaises(NTSTATUSError) as e:
             fd = smb2.create_ex(f'{symlink}')
-            self.assert_symlink_exception(
-                e, { 'unparsed_path_length' : 0,
-                     'substitute_name' : target,
-                     'print_name' : target,
-                     'flags' : 0x20000001 })
+
+        self.assert_symlink_exception(
+                e.exception,
+            { 'unparsed_path_length' : 0,
+              'substitute_name' : target,
+              'print_name' : target,
+              'flags' : 0x20000001 })
 
         self.clean_file(smb1, symlink)
 
@@ -131,11 +141,13 @@ class Smb2SymlinkTests(samba.tests.libsmb.LibsmbTests):
 
             with self.assertRaises(NTSTATUSError) as e:
                 fd = smb2.create_ex(f'{symlink}')
-                self.assert_symlink_exception(
-                    e, { 'unparsed_path_length' : 0,
-                         'substitute_name' : target,
-                         'print_name' : target,
-                         'flags' : 0 })
+
+            self.assert_symlink_exception(
+                e.exception,
+                { 'unparsed_path_length' : 0,
+                  'substitute_name' : target,
+                  'print_name' : target,
+                  'flags' : 0 })
 
             self.clean_file(smb1, symlink)
 
@@ -153,11 +165,13 @@ class Smb2SymlinkTests(samba.tests.libsmb.LibsmbTests):
 
         with self.assertRaises(NTSTATUSError) as e:
             fd = smb2.create_ex(f'{symlink}')
-            self.assert_symlink_exception(
-                e, { 'unparsed_path_length' : 0,
-                     'substitute_name' : rel_dest,
-                     'print_name' : rel_dest,
-                     'flags' : 0 })
+
+        self.assert_symlink_exception(
+            e.exception,
+            { 'unparsed_path_length' : 0,
+              'substitute_name' : rel_dest,
+              'print_name' : rel_dest,
+              'flags' : 0 })
 
         self.clean_file(smb1, symlink)
 
diff --git a/source3/client/client.c b/source3/client/client.c
index 651da5fbf7a..f7719db118b 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3455,6 +3455,8 @@ static int cmd_readlink(void)
 	char *buf = NULL;
 	char *targetname = NULL;
 	char *linkname = NULL;
+	char *printname = NULL;
+	uint32_t flags;
 	struct cli_state *targetcli;
 	struct cli_credentials *creds = samba_cmdline_get_creds();
         NTSTATUS status;
@@ -3483,18 +3485,8 @@ static int cmd_readlink(void)
 		return 1;
 	}
 
-	if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
-		d_printf("Server doesn't support UNIX CIFS calls.\n");
-		return 1;
-	}
-
-	if (CLI_DIRSEP_CHAR != '/') {
-		d_printf("Command \"posix\" must be issued before "
-			 "the \"readlink\" command can be used.\n");
-		return 1;
-	}
-
-	status = cli_posix_readlink(targetcli, name, talloc_tos(), &linkname);
+	status = cli_readlink(
+		cli, name, talloc_tos(), &linkname, &printname, &flags);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("%s readlink on file %s\n",
 			 nt_errstr(status), name);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 31776a58621..91bb1095643 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -482,48 +482,6 @@ NTSTATUS cli_posix_readlink_recv(
 	return NT_STATUS_OK;
 }
 
-NTSTATUS cli_posix_readlink(
-	struct cli_state *cli,
-	const char *fname,
-	TALLOC_CTX *mem_ctx,
-	char **target)
-{
-	TALLOC_CTX *frame = talloc_stackframe();
-	struct tevent_context *ev = NULL;
-	struct tevent_req *req = NULL;
-	NTSTATUS status = NT_STATUS_OK;
-
-	if (smbXcli_conn_has_async_calls(cli->conn)) {
-		/*
-		 * Can't use sync call while an async call is in flight
-		 */
-		status = NT_STATUS_INVALID_PARAMETER;
-		goto fail;
-	}
-
-	ev = samba_tevent_context_init(frame);
-	if (ev == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto fail;
-	}
-
-	req = cli_posix_readlink_send(frame, ev, cli, fname);
-	if (req == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto fail;
-	}
-
-	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
-		goto fail;
-	}
-
-	status = cli_posix_readlink_recv(req, mem_ctx, target);
-
- fail:
-	TALLOC_FREE(frame);
-	return status;
-}
-
 /****************************************************************************
  Hard link a file (UNIX extensions).
 ****************************************************************************/
diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c
index f77f2c050ab..12d644eb68d 100644
--- a/source3/libsmb/clisymlink.c
+++ b/source3/libsmb/clisymlink.c
@@ -228,8 +228,10 @@ struct cli_readlink_state {
 	NTSTATUS get_reparse_status;
 	uint8_t *data;
 	uint32_t num_data;
+	char *target;
 };
 
+static void cli_readlink_posix1_done(struct tevent_req *subreq);
 static void cli_readlink_opened(struct tevent_req *subreq);
 static void cli_readlink_got_reparse_data(struct tevent_req *subreq);
 static void cli_readlink_closed(struct tevent_req *subreq);
@@ -249,6 +251,18 @@ struct tevent_req *cli_readlink_send(TALLOC_CTX *mem_ctx,
 	state->ev = ev;
 	state->cli = cli;
 
+	if (cli->requested_posix_capabilities != 0) {
+		/*
+		 * Only happens for negotiated SMB1 posix caps
+		 */
+		subreq = cli_posix_readlink_send(state, ev, cli, fname);
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, cli_readlink_posix1_done, req);
+		return req;
+	}
+
 	subreq = cli_ntcreate_send(
 		state, ev, cli, fname, 0, FILE_READ_ATTRIBUTES | FILE_READ_EA,
 		0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
@@ -261,6 +275,22 @@ struct tevent_req *cli_readlink_send(TALLOC_CTX *mem_ctx,
 	return req;
 }
 
+static void cli_readlink_posix1_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_readlink_state *state = tevent_req_data(
+		req, struct cli_readlink_state);
+	NTSTATUS status;
+
+	status = cli_posix_readlink_recv(subreq, state, &state->target);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+	tevent_req_done(req);
+}
+
 static void cli_readlink_opened(struct tevent_req *subreq)
 {
 	struct tevent_req *req = tevent_req_callback_data(
@@ -345,6 +375,23 @@ NTSTATUS cli_readlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 		return status;
 	}
 
+	if (state->target != NULL) {
+		/*
+		 * SMB1 posix version
+		 */
+		if (psubstitute_name != NULL) {
+			*psubstitute_name = talloc_move(
+				mem_ctx, &state->target);
+		}
+		if (pprint_name != NULL) {
+			*pprint_name = NULL;
+		}
+		if (pflags != NULL) {
+			*pflags = 0;
+		}
+		return NT_STATUS_OK;
+	}
+
 	symlink = symlink_reparse_buffer_parse(
 		talloc_tos(), state->data, state->num_data);
 	if (symlink == NULL) {
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 58fb2cbbf18..3d732fe8524 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -266,11 +266,6 @@ struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx,
 					const char *fname);
 NTSTATUS cli_posix_readlink_recv(
 	struct tevent_req *req, TALLOC_CTX *mem_ctx, char **target);
-NTSTATUS cli_posix_readlink(
-	struct cli_state *cli,
-	const char *fname,
-	TALLOC_CTX *mem_ctx,
-	char **target);
 struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx,
 					struct tevent_context *ev,
 					struct cli_state *cli,
diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index 3d8bb14bb78..0990e2dc995 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -2855,6 +2855,13 @@ MODULE_INIT_FUNC(libsmb_samba_cwrapper)
 	ADD_FLAGS(FSCTL_LMR_SET_LINK_TRACKING_INFORMATION);
 	ADD_FLAGS(FSCTL_QUERY_NETWORK_INTERFACE_INFO);
 
+	ADD_FLAGS(SYMLINK_ERROR_TAG);
+	ADD_FLAGS(SYMLINK_FLAG_RELATIVE);
+	ADD_FLAGS(SYMLINK_ADMIN);
+	ADD_FLAGS(SYMLINK_UNTRUSTED);
+	ADD_FLAGS(SYMLINK_TRUST_UNKNOWN);
+	ADD_FLAGS(SYMLINK_TRUST_MASK);
+
 #define ADD_STRING(val) PyModule_AddObject(m, #val, PyBytes_FromString(val))
 
 	ADD_STRING(SMB2_CREATE_TAG_EXTA);
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 1f8b33c7fda..c66e8b4b24e 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -509,29 +509,6 @@ NTSTATUS filename_convert_smb1_search_path(TALLOC_CTX *ctx,
 		ucf_flags &= ~UCF_GMT_PATHNAME;
 	}
 
-	if (ucf_flags & UCF_DFS_PATHNAME) {
-		/*
-		 * We've been given a raw DFS pathname.
-		 */
-		char *pathname = NULL;
-		DBG_DEBUG("Before dfs_filename_convert name_in: %s\n", name_in);
-		status = dfs_filename_convert(ctx,
-					      conn,
-					      ucf_flags,
-					      name_in,
-					      &pathname);
-                if (!NT_STATUS_IS_OK(status)) {
-			DBG_DEBUG("dfs_filename_convert "
-				"failed for name %s with %s\n",
-				name_in,
-				nt_errstr(status));
-			return status;
-		}
-		ucf_flags &= ~UCF_DFS_PATHNAME;
-		name_in = pathname;
-		DBG_DEBUG("After dfs_filename_convert name_in: %s\n", name_in);
-	}
-
 	/* Get the original lcomp. */
 	mask = get_original_lcomp(ctx,
 				  conn,
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 40d71d8851b..1b486757506 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -685,6 +685,9 @@ NTSTATUS readlink_talloc(
 	struct smb_filename *smb_relname,
 	char **_substitute)
 {
+	struct smb_filename null_fname = {
+		.base_name = discard_const_p(char, ""),
+	};
 	char buf[PATH_MAX];
 	ssize_t ret;
 	char *substitute;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list