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 <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Aug 6 17:37:39 UTC 2024 on atb-devel-224 commit 7e82052ce7a75a2a4839a0b26670d2ef08af0a82 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0e8a0f3bd4b0e1f4bebb70317ff60ce7339a520d Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 95c031b660676f693739ed9e1f49754da0691ff0 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 83537703bab9b28f2cff4f497fa1bafa12c83a24 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit fe7b78adb3da6d18e5fc252487c0a3817fb106dd Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 51262e47af037efb2b9195437bb48f59cd6901d6 Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 24 10:00:44 2024 +0200 smbd: Modernize a DEBUG Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cfa24f05639d2c65c8b7e045cbdeaabcbcf16861 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cb67a701131d0e024cf54c7d6bf982a8ebd856d5 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ec7365432374f4e8a9be12ba78ab0cd0ac64234f Author: Volker Lendecke <v...@samba.org> Date: Mon Jul 29 03:39:32 2024 -0700 lib: Fix a typo Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit d8271bd937583b17bf183988949f4df04ad7bde4 Author: Volker Lendecke <v...@samba.org> Date: Mon Jul 29 03:39:32 2024 -0700 vfs: Fix a DBG message Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 7fe93402f3e06c35d427842fea1fedaef8f7a4c0 Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 21 12:38:25 2024 +0200 smbclient: Modernize a d_printf Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3719c5c439101dbf0b1adfdd09f2618056df6fe1 Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 17 10:23:26 2024 +0200 lib: Fix whitespace Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6a0fc464df8d34a32289a5fcde9db2596bce6e5e Author: Volker Lendecke <v...@samba.org> Date: Fri Jul 12 17:58:58 2024 +0200 tsocket: Use iov_buflen Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit af442249a0a11f3e6c159ae97d95d38384284a59 Author: Volker Lendecke <v...@samba.org> Date: Fri Jul 12 17:52:32 2024 +0200 tsocket: Use iov_buflen Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 33d517fe1353c3f8371b92ca8006df35c397184a Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 7 20:09:46 2024 +0200 smbd: Modernize DEBUGs Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 230d8efe72cf18a7609641c247cbc246f2b9066b Author: Volker Lendecke <v...@samba.org> Date: Fri Aug 2 23:09:07 2024 +0200 libsmb: Remove cli_posix_chmod Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 14d6e7d412109f37b0c9c005149c6b21a303d4f7 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a3fcb5f740479cdc9edd55a532fed376fda8fd41 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 70da8f7d62682feb8073e1ac9b0ce3f16ae89245 Author: Volker Lendecke <v...@samba.org> Date: Fri Aug 2 12:53:05 2024 +0200 libsmb: Add cli_fchmod for smb311 posix extensions Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 773c4641cea7df37b5fa3d3fb7fce479c527f82e Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ac92f2d34aca01fe1d496eed79a22ad6b3730c81 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3720198d221fcb5ecc5997009bbb031932cbe622 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cd0352a9ca2988d7a4525fbcd21fd730e1f37ed7 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 51ce5ce7094d4e2190a9eb45a2cfea2e0cffa3c2 Author: Volker Lendecke <v...@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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@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