]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libsmb: Add cli_fchmod
authorVolker Lendecke <vl@samba.org>
Sat, 27 Jul 2024 13:43:55 +0000 (15:43 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 6 Aug 2024 16:29:33 +0000 (16:29 +0000)
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@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/libsmb/clifile.c
source3/libsmb/proto.h

index 7732cb9127907eeb42a83185e262fe1a8860dfd3..8ea457f6132b8f71b807ee7c55f4dde88b9bddb8 100644 (file)
@@ -1081,6 +1081,64 @@ NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
        return status;
 }
 
+struct cli_fchmod_state {
+       uint8_t data[100]; /* smb1 posix extensions */
+};
+
+static void cli_fchmod_done1(struct tevent_req *subreq);
+
+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_fchmod_state *state = NULL;
+       const enum protocol_types proto = smbXcli_conn_protocol(cli->conn);
+
+       req = tevent_req_create(mem_ctx, &state, struct cli_fchmod_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       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;
+       }
+
+       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);
+}
+
+NTSTATUS cli_fchmod_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
 /****************************************************************************
  chown a file (UNIX extensions).
 ****************************************************************************/
index 5665c4d6ca483b3eb7022ae2d2c2b6e4747eca49..a91dd06cfec1188bae7d372af1dcdb3ce3ec48d2 100644 (file)
@@ -319,6 +319,12 @@ struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx,
                                        mode_t mode);
 NTSTATUS cli_posix_chmod_recv(struct tevent_req *req);
 NTSTATUS cli_posix_chmod(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);
+NTSTATUS cli_fchmod_recv(struct tevent_req *req);
 struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
                                        struct cli_state *cli,