[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Aug 6 17:38:01 UTC 2024


The branch, master has been updated
       via  2686a189c6c smbd: Assert we have an fsp in smbd_do_setfilepathinfo
       via  7e82052ce7a smbd: filename_convert_dirfsp always gives an fsp
       via  0e8a0f3bd4b smbd: Simplify check_user_ok()
       via  95c031b6606 smbd: Make parent_override_delete a bit more readable
       via  83537703bab smbd: Remove some dead code
       via  fe7b78adb3d smbd: Fix some DBGs
       via  51262e47af0 smbd: Modernize a DEBUG
       via  cfa24f05639 smbd: Fix a comment and an error message
       via  cb67a701131 smbd: Save a few lines with a "goto done;"
       via  ec736543237 lib: Fix a typo
       via  d8271bd9375 vfs: Fix a DBG message
       via  7fe93402f3e smbclient: Modernize a d_printf
       via  3719c5c4391 lib: Fix whitespace
       via  6a0fc464df8 tsocket: Use iov_buflen
       via  af442249a0a tsocket: Use iov_buflen
       via  33d517fe135 smbd: Modernize DEBUGs
       via  230d8efe72c libsmb: Remove cli_posix_chmod
       via  14d6e7d4121 torture3: Use cli_chmod instead of cli_posix_chmod
       via  a3fcb5f7404 smbclient: Use cli_chmod instead of cli_posix_chmod
       via  70da8f7d626 libsmb: Add cli_fchmod for smb311 posix extensions
       via  773c4641cea libsmb: Add cli_chmod
       via  ac92f2d34ac libsmb: Add cli_fchmod
       via  3720198d221 libsmb: Add cli_smb2_fnum_is_posix
       via  cd0352a9ca2 libsmb: Slightly restructure map_smb2_handle_to_fnum
       via  51ce5ce7094 smbd: protect check_smb2_posix_chmod_ace against invalid trustees
      from  6b10cfbaf2c tdb: version 1.4.12

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


- Log -----------------------------------------------------------------
commit 2686a189c6cfbbcd93b60ba565967ef08647100d
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 22 11:59:40 2024 +0200

    smbd: Assert we have an fsp in smbd_do_setfilepathinfo
    
    With this in the future we can avoid some special cases in our callees
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Aug  6 17:37:39 UTC 2024 on atb-devel-224

commit 7e82052ce7a75a2a4839a0b26670d2ef08af0a82
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 22 10:42:11 2024 +0200

    smbd: filename_convert_dirfsp always gives an fsp
    
    We're in setpathinfo, so if there's without an fsp it's
    OBJECT_NAME_NOT_FOUND, the last component is missing.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0e8a0f3bd4b0e1f4bebb70317ff60ce7339a520d
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 04:24:30 2024 -0700

    smbd: Simplify check_user_ok()
    
    Don't walk the cache at all if we get UID_FIELD_INVALID
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 95c031b660676f693739ed9e1f49754da0691ff0
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 22 20:56:25 2024 +0200

    smbd: Make parent_override_delete a bit more readable
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 83537703bab9b28f2cff4f497fa1bafa12c83a24
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jul 24 09:58:47 2024 +0200

    smbd: Remove some dead code
    
    We have returned from this function if fsp==NULL above
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit fe7b78adb3da6d18e5fc252487c0a3817fb106dd
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jul 24 10:00:22 2024 +0200

    smbd: Fix some DBGs
    
    DBG_DEBUG already has the function name prefix
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 51262e47af037efb2b9195437bb48f59cd6901d6
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jul 24 10:00:44 2024 +0200

    smbd: Modernize a DEBUG
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cfa24f05639d2c65c8b7e045cbdeaabcbcf16861
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 22 19:53:40 2024 +0200

    smbd: Fix a comment and an error message
    
    Tested manually, but OBJECT_NAME_NOT_FOUND makes much more sense given
    the new semantics of filename_convert_dirfsp.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cb67a701131d0e024cf54c7d6bf982a8ebd856d5
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 22 10:41:47 2024 +0200

    smbd: Save a few lines with a "goto done;"
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ec7365432374f4e8a9be12ba78ab0cd0ac64234f
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 03:39:32 2024 -0700

    lib: Fix a typo
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d8271bd937583b17bf183988949f4df04ad7bde4
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 03:39:32 2024 -0700

    vfs: Fix a DBG message
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7fe93402f3e06c35d427842fea1fedaef8f7a4c0
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jul 21 12:38:25 2024 +0200

    smbclient: Modernize a d_printf
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3719c5c439101dbf0b1adfdd09f2618056df6fe1
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jul 17 10:23:26 2024 +0200

    lib: Fix whitespace
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6a0fc464df8d34a32289a5fcde9db2596bce6e5e
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jul 12 17:58:58 2024 +0200

    tsocket: Use iov_buflen
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit af442249a0a11f3e6c159ae97d95d38384284a59
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jul 12 17:52:32 2024 +0200

    tsocket: Use iov_buflen
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 33d517fe1353c3f8371b92ca8006df35c397184a
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jul 7 20:09:46 2024 +0200

    smbd: Modernize DEBUGs
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 230d8efe72cf18a7609641c247cbc246f2b9066b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 23:09:07 2024 +0200

    libsmb: Remove cli_posix_chmod
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 14d6e7d412109f37b0c9c005149c6b21a303d4f7
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 23:06:17 2024 +0200

    torture3: Use cli_chmod instead of cli_posix_chmod
    
    Show that it works the same even for dangling posix symlinks
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a3fcb5f740479cdc9edd55a532fed376fda8fd41
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 13:06:58 2024 +0200

    smbclient: Use cli_chmod instead of cli_posix_chmod
    
    Skip the smb1-only SERVER_HAS_UNIX_CIFS(), chmod now also does SMB2
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 70da8f7d62682feb8073e1ac9b0ce3f16ae89245
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 12:53:05 2024 +0200

    libsmb: Add cli_fchmod for smb311 posix extensions
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 773c4641cea7df37b5fa3d3fb7fce479c527f82e
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jul 26 17:27:30 2024 +0200

    libsmb: Add cli_chmod
    
    Go via create/fchmod/close. Only fchmod has to be smb2-specific this way.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ac92f2d34aca01fe1d496eed79a22ad6b3730c81
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jul 27 15:43:55 2024 +0200

    libsmb: Add cli_fchmod
    
    Do a posix-level fchmod on a fnum. This will be used for smb2 soon as
    well which does not have setpathinfo.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3720198d221fcb5ecc5997009bbb031932cbe622
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 11:18:40 2024 +0200

    libsmb: Add cli_smb2_fnum_is_posix
    
    Will be used in smb311 unix chmod soon: We should only do the special
    setsd on real posix handles. Otherwise we would probably destroy a
    valid acl.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cd0352a9ca2988d7a4525fbcd21fd730e1f37ed7
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 11:04:31 2024 +0200

    libsmb: Slightly restructure map_smb2_handle_to_fnum
    
    Pass the persistent/volatile handle as uint64's. Why? I found the
    talloc_memdup() slightly misleading, and smbXcli handles those 2 id's
    separately. map_smb2_handle_to_fnum() is the function to create the
    smb2_hnd.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 51ce5ce7094d4e2190a9eb45a2cfea2e0cffa3c2
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Aug 2 13:06:28 2024 +0200

    smbd: protect check_smb2_posix_chmod_ace against invalid trustees
    
    Found because I got this wrong in new code coming soon
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 lib/tsocket/tsocket.c           |  34 ++----
 lib/util/util_net.h             |   8 +-
 libcli/smb/tstream_smbXcli_np.c |  11 +-
 source3/client/client.c         |  11 +-
 source3/lib/util_namearray.c    |   2 +-
 source3/libsmb/cli_smb2_fnum.c  |  57 ++++++---
 source3/libsmb/cli_smb2_fnum.h  |   2 +
 source3/libsmb/clifile.c        | 248 +++++++++++++++++++++++++++++++++-------
 source3/libsmb/proto.h          |  21 ++--
 source3/modules/vfs_fruit.c     |   2 +-
 source3/smbd/open.c             |  12 +-
 source3/smbd/smb1_reply.c       |   7 +-
 source3/smbd/smb1_trans2.c      |  41 +++----
 source3/smbd/smb2_nttrans.c     |   4 +
 source3/smbd/smb2_trans2.c      |  20 ++--
 source3/smbd/uid.c              |  32 +++---
 source3/torture/test_posix.c    |  24 ++--
 source3/torture/torture.c       |   7 +-
 18 files changed, 363 insertions(+), 180 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c
index 674858de0a5..b589959f771 100644
--- a/lib/tsocket/tsocket.c
+++ b/lib/tsocket/tsocket.c
@@ -25,6 +25,7 @@
 #include "system/filesys.h"
 #include "tsocket.h"
 #include "tsocket_internal.h"
+#include "lib/util/iov_buf.h"
 
 int tsocket_simple_int_recv(struct tevent_req *req, int *perrno)
 {
@@ -524,8 +525,7 @@ struct tevent_req *tstream_readv_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req;
 	struct tstream_readv_state *state;
 	struct tevent_req *subreq;
-	int to_read = 0;
-	size_t i;
+	ssize_t to_read;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct tstream_readv_state);
@@ -545,16 +545,11 @@ struct tevent_req *tstream_readv_send(TALLOC_CTX *mem_ctx,
 	}
 #endif
 
-	for (i=0; i < count; i++) {
-		int tmp = to_read;
-		tmp += vector[i].iov_len;
+	to_read = iov_buflen(vector, count);
 
-		if (tmp < to_read) {
-			tevent_req_error(req, EMSGSIZE);
-			goto post;
-		}
-
-		to_read = tmp;
+	if (to_read < 0) {
+		tevent_req_error(req, EMSGSIZE);
+		goto post;
 	}
 
 	if (to_read == 0) {
@@ -646,8 +641,7 @@ struct tevent_req *tstream_writev_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req;
 	struct tstream_writev_state *state;
 	struct tevent_req *subreq;
-	int to_write = 0;
-	size_t i;
+	ssize_t to_write;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct tstream_writev_state);
@@ -667,16 +661,10 @@ struct tevent_req *tstream_writev_send(TALLOC_CTX *mem_ctx,
 	}
 #endif
 
-	for (i=0; i < count; i++) {
-		int tmp = to_write;
-		tmp += vector[i].iov_len;
-
-		if (tmp < to_write) {
-			tevent_req_error(req, EMSGSIZE);
-			goto post;
-		}
-
-		to_write = tmp;
+	to_write = iov_buflen(vector, count);
+	if (to_write < 0) {
+		tevent_req_error(req, EMSGSIZE);
+		goto post;
 	}
 
 	if (to_write == 0) {
diff --git a/lib/util/util_net.h b/lib/util/util_net.h
index 1aed45a432c..30399d81105 100644
--- a/lib/util/util_net.h
+++ b/lib/util/util_net.h
@@ -1,19 +1,19 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Utility functions for Samba
    Copyright (C) Andrew Tridgell 1992-1999
    Copyright (C) Jelmer Vernooij 2005
-    
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c
index 02483004080..ad92ba43b27 100644
--- a/libcli/smb/tstream_smbXcli_np.c
+++ b/libcli/smb/tstream_smbXcli_np.c
@@ -26,6 +26,7 @@
 #include "smbXcli_base.h"
 #include "tstream_smbXcli_np.h"
 #include "libcli/security/security.h"
+#include "lib/util/iov_buf.h"
 
 static const struct tstream_context_ops tstream_smbXcli_np_ops;
 
@@ -537,11 +538,13 @@ static void tstream_smbXcli_np_writev_write_next(struct tevent_req *req)
 		tstream_context_data(state->stream,
 		struct tstream_smbXcli_np);
 	struct tevent_req *subreq;
-	size_t i;
-	size_t left = 0;
+	ssize_t left;
 
-	for (i=0; i < state->count; i++) {
-		left += state->vector[i].iov_len;
+	left = iov_buflen(state->vector, state->count);
+
+	if (left < 0) {
+		tevent_req_error(req, EMSGSIZE);
+		return;
 	}
 
 	if (left == 0) {
diff --git a/source3/client/client.c b/source3/client/client.c
index 2052eb5ed4c..08cf63018f3 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3182,7 +3182,9 @@ static int cmd_posix(void)
 		return 1;
 	}
 
-	d_printf("Server supports CIFS extensions %u.%u\n", (unsigned int)major, (unsigned int)minor);
+	d_printf("Server supports CIFS extensions %" PRIu16 ".%" PRIu16 "\n",
+		 major,
+		 minor);
 
 	caps = talloc_strdup(ctx, "");
 	if (caplow & CIFS_UNIX_FCNTL_LOCKS_CAP) {
@@ -3674,18 +3676,13 @@ static int cmd_chmod(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 \"chmod\" command can be used.\n");
 		return 1;
 	}
 
-	status = cli_posix_chmod(targetcli, targetname, mode);
+	status = cli_chmod(targetcli, targetname, mode);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("%s chmod file %s 0%o\n",
 			 nt_errstr(status), src, (unsigned int)mode);
diff --git a/source3/lib/util_namearray.c b/source3/lib/util_namearray.c
index 1c5b4ac6a0e..8d05beb7d31 100644
--- a/source3/lib/util_namearray.c
+++ b/source3/lib/util_namearray.c
@@ -192,7 +192,7 @@ static size_t namearray_len(const struct name_compare_entry *array)
 
 /*******************************************************************
  Strip a '/' separated list into an array of
- name_compare_enties structures suitable for
+ name_compare_entry structures suitable for
  passing to is_in_path(). We do this for
  speed so we can pre-parse all the names in the list
  and don't do it for each call to is_in_path().
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 7f44435963f..34d65019d80 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -49,6 +49,7 @@
 struct smb2_hnd {
 	uint64_t fid_persistent;
 	uint64_t fid_volatile;
+	bool posix; /* Opened with posix context */
 };
 
 /*
@@ -56,23 +57,29 @@ struct smb2_hnd {
  */
 
 /***************************************************************
- Allocate a new fnum between 1 and 0xFFFE from an smb2_hnd.
+ Allocate a new fnum between 1 and 0xFFFE from an smb2 file id.
  Ensures handle is owned by cli struct.
 ***************************************************************/
 
 static NTSTATUS map_smb2_handle_to_fnum(struct cli_state *cli,
-				const struct smb2_hnd *ph,	/* In */
-				uint16_t *pfnum)		/* Out */
+					uint64_t fid_persistent,
+					uint64_t fid_volatile,
+					bool posix,
+					uint16_t *pfnum)
 {
 	int ret;
 	struct idr_context *idp = cli->smb2.open_handles;
-	struct smb2_hnd *owned_h = talloc_memdup(cli,
-						ph,
-						sizeof(struct smb2_hnd));
+	struct smb2_hnd *owned_h = NULL;
 
+	owned_h = talloc(cli, struct smb2_hnd);
 	if (owned_h == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
+	*owned_h = (struct smb2_hnd){
+		.fid_persistent = fid_persistent,
+		.fid_volatile = fid_volatile,
+		.posix = posix,
+	};
 
 	if (idp == NULL) {
 		/* Lazy init */
@@ -342,22 +349,30 @@ static void cli_smb2_create_fnum_done(struct tevent_req *subreq)
 		subreq, struct tevent_req);
 	struct cli_smb2_create_fnum_state *state = tevent_req_data(
 		req, struct cli_smb2_create_fnum_state);
-	struct smb2_hnd h;
+	uint64_t fid_persistent, fid_volatile;
+	struct smb2_create_blob *posix = NULL;
 	NTSTATUS status;
 
-	status = smb2cli_create_recv(
-		subreq,
-		&h.fid_persistent,
-		&h.fid_volatile, &state->cr,
-		state,
-		&state->out_cblobs,
-		&state->symlink);
+	status = smb2cli_create_recv(subreq,
+				     &fid_persistent,
+				     &fid_volatile,
+				     &state->cr,
+				     state,
+				     &state->out_cblobs,
+				     &state->symlink);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
 
-	status = map_smb2_handle_to_fnum(state->cli, &h, &state->fnum);
+	posix = smb2_create_blob_find(&state->in_cblobs,
+				      SMB2_CREATE_TAG_POSIX);
+
+	status = map_smb2_handle_to_fnum(state->cli,
+					 fid_persistent,
+					 fid_volatile,
+					 (posix != NULL),
+					 &state->fnum);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
@@ -408,6 +423,18 @@ NTSTATUS cli_smb2_create_fnum_recv(
 	return NT_STATUS_OK;
 }
 
+bool cli_smb2_fnum_is_posix(struct cli_state *cli, uint16_t fnum)
+{
+	struct smb2_hnd *ph = NULL;
+	NTSTATUS status;
+
+	status = map_fnum_to_smb2_handle(cli, fnum, &ph);
+	if (!NT_STATUS_IS_OK(status)) {
+		return false;
+	}
+	return ph->posix;
+}
+
 NTSTATUS cli_smb2_create_fnum(
 	struct cli_state *cli,
 	const char *fname,
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index abac569385d..2b19e6ebb4e 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -67,6 +67,8 @@ NTSTATUS cli_smb2_create_fnum(
 	TALLOC_CTX *mem_ctx,
 	struct smb2_create_blobs *out_cblobs);
 
+bool cli_smb2_fnum_is_posix(struct cli_state *cli, uint16_t fnum);
+
 struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
 					    struct tevent_context *ev,
 					    struct cli_state *cli,
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 7732cb91279..57eb75eb228 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -989,62 +989,233 @@ static NTSTATUS cli_posix_chown_chmod_internal_recv(struct tevent_req *req)
 	return tevent_req_simple_recv_ntstatus(req);
 }
 
-/****************************************************************************
- chmod a file (UNIX extensions).
-****************************************************************************/
-
-struct cli_posix_chmod_state {
-	uint8_t dummy;
+struct cli_fchmod_state {
+	uint8_t data[100]; /* smb1 posix extensions */
 };
 
-static void cli_posix_chmod_done(struct tevent_req *subreq);
+static void cli_fchmod_done1(struct tevent_req *subreq);
+static void cli_fchmod_done2(struct tevent_req *subreq);
 
-struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx,
-					struct tevent_context *ev,
-					struct cli_state *cli,
-					const char *fname,
-					mode_t mode)
+struct tevent_req *cli_fchmod_send(TALLOC_CTX *mem_ctx,
+				   struct tevent_context *ev,
+				   struct cli_state *cli,
+				   uint16_t fnum,
+				   mode_t mode)
 {
 	struct tevent_req *req = NULL, *subreq = NULL;
-	struct cli_posix_chmod_state *state = NULL;
+	struct cli_fchmod_state *state = NULL;
+	const enum protocol_types proto = smbXcli_conn_protocol(cli->conn);
 
-	req = tevent_req_create(mem_ctx, &state, struct cli_posix_chmod_state);
+	req = tevent_req_create(mem_ctx, &state, struct cli_fchmod_state);
 	if (req == NULL) {
 		return NULL;
 	}
 
-	subreq = cli_posix_chown_chmod_internal_send(
-		state,
-		ev,
-		cli,
-		fname,
-		unix_perms_to_wire(mode),
-		SMB_UID_NO_CHANGE,
-		SMB_GID_NO_CHANGE);
+	if ((proto < PROTOCOL_SMB2_02) && SERVER_HAS_UNIX_CIFS(cli)) {
+		memset(state->data,
+		       0xff,
+		       40); /* Set all sizes/times to no change. */
+		PUSH_LE_U32(state->data, 40, SMB_UID_NO_CHANGE);
+		PUSH_LE_U32(state->data, 48, SMB_GID_NO_CHANGE);
+		PUSH_LE_U32(state->data, 84, mode);
+
+		subreq = cli_setfileinfo_send(state,
+					      ev,
+					      cli,
+					      fnum,
+					      SMB_SET_FILE_UNIX_BASIC,
+					      state->data,
+					      sizeof(state->data));
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, cli_fchmod_done1, req);
+		return req;
+	}
+
+	if ((proto >= PROTOCOL_SMB3_11) && cli_smb2_fnum_is_posix(cli, fnum)) {
+		struct security_ace ace = {
+			.type = SEC_ACE_TYPE_ACCESS_ALLOWED,
+			.trustee = global_sid_Unix_NFS_Mode,
+		};
+		struct security_acl acl = {
+			.revision = SECURITY_ACL_REVISION_NT4,
+			.num_aces = 1,
+			.aces = &ace,
+		};
+		struct security_descriptor *sd = NULL;
+
+		sid_append_rid(&ace.trustee, mode);
+
+		sd = make_sec_desc(state,
+				   SECURITY_DESCRIPTOR_REVISION_1,
+				   SEC_DESC_SELF_RELATIVE |
+					   SEC_DESC_DACL_PRESENT,
+				   NULL,
+				   NULL,
+				   NULL,
+				   &acl,
+				   NULL);
+		if (tevent_req_nomem(sd, req)) {
+			return tevent_req_post(req, ev);
+		}
+
+		subreq = cli_set_security_descriptor_send(
+			state, ev, cli, fnum, SECINFO_DACL, sd);
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, cli_fchmod_done2, req);
+		return req;
+	}
+
+	tevent_req_nterror(req, NT_STATUS_INVALID_LEVEL);
+	return tevent_req_post(req, ev);
+}
+
+static void cli_fchmod_done1(struct tevent_req *subreq)
+{
+	NTSTATUS status = cli_setfileinfo_recv(subreq);
+	tevent_req_simple_finish_ntstatus(subreq, status);
+}
+
+static void cli_fchmod_done2(struct tevent_req *subreq)
+{
+	NTSTATUS status = cli_set_security_descriptor_recv(subreq);
+	tevent_req_simple_finish_ntstatus(subreq, status);
+}
+
+NTSTATUS cli_fchmod_recv(struct tevent_req *req)
+{
+	return tevent_req_simple_recv_ntstatus(req);
+}
+
+struct cli_chmod_state {
+	struct tevent_context *ev;
+	struct cli_state *cli;
+	mode_t mode;
+
+	uint16_t fnum;
+
+	NTSTATUS fchmod_status;
+
+	uint8_t data[100]; /* smb1 posix extensions */
+};
+
+static void cli_chmod_opened(struct tevent_req *subreq);
+static void cli_chmod_done(struct tevent_req *subreq);
+static void cli_chmod_closed(struct tevent_req *subreq);
+
+struct tevent_req *cli_chmod_send(TALLOC_CTX *mem_ctx,
+				  struct tevent_context *ev,
+				  struct cli_state *cli,
+				  const char *fname,
+				  mode_t mode)
+{
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct cli_chmod_state *state = NULL;
+
+	req = tevent_req_create(mem_ctx, &state, struct cli_chmod_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->cli = cli;
+	state->mode = mode;
+
+	subreq = cli_ntcreate_send(
+		state,				    /* mem_ctx */
+		ev,				    /* ev */
+		cli,				    /* cli */
+		fname,				    /* fname */
+		0,				    /* create_flags */
+		SEC_STD_WRITE_DAC,		    /* desired_access */
+		0,				    /* file_attributes */
+		FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
+		FILE_OPEN,			    /* create_disposition */
+		0x0,				    /* create_options */
+		SMB2_IMPERSONATION_IMPERSONATION,   /* impersonation_level */
+		0x0);				    /* SecurityFlags */
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-	tevent_req_set_callback(subreq, cli_posix_chmod_done, req);
+	tevent_req_set_callback(subreq, cli_chmod_opened, req);
 	return req;
 }
 
-static void cli_posix_chmod_done(struct tevent_req *subreq)
+static void cli_chmod_opened(struct tevent_req *subreq)
 {
-	NTSTATUS status = cli_posix_chown_chmod_internal_recv(subreq);
-	tevent_req_simple_finish_ntstatus(subreq, status);
+	struct tevent_req *req = tevent_req_callback_data(subreq,
+							  struct tevent_req);
+	struct cli_chmod_state *state = tevent_req_data(
+		req, struct cli_chmod_state);
+	NTSTATUS status;
+
+	status = cli_ntcreate_recv(subreq, &state->fnum, NULL);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list