]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: libsmb: Add cli_smb2_ftruncate(), plumb into cli_ftruncate().
authorJeremy Allison <jra@samba.org>
Wed, 21 Dec 2016 21:55:50 +0000 (13:55 -0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 9 Jan 2017 09:44:38 +0000 (10:44 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12479

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
(cherry picked from commit e0f1ed9f450851bf5b7fec84577b50047309db3f)

source3/libsmb/cli_smb2_fnum.c
source3/libsmb/cli_smb2_fnum.h
source3/libsmb/clifile.c

index c5b1434eaaa844c84c6788976fbc6edb2e69c833..665a38d3c73a91637187f2dae808653f11bbc81f 100644 (file)
@@ -2873,3 +2873,68 @@ NTSTATUS cli_smb2_splice_recv(struct tevent_req *req, off_t *written)
        tevent_req_received(req);
        return NT_STATUS_OK;
 }
+
+/***************************************************************
+ Wrapper that allows SMB2 to truncate a file.
+ Synchronous only.
+***************************************************************/
+
+NTSTATUS cli_smb2_ftruncate(struct cli_state *cli,
+                       uint16_t fnum,
+                       uint64_t newsize)
+{
+       NTSTATUS status;
+       DATA_BLOB inbuf = data_blob_null;
+       struct smb2_hnd *ph = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       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;
+       }
+
+       if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+
+       status = map_fnum_to_smb2_handle(cli,
+                                       fnum,
+                                       &ph);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto fail;
+       }
+
+       inbuf = data_blob_talloc_zero(frame, 8);
+       if (inbuf.data == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       SBVAL(inbuf.data, 0, newsize);
+
+       /* setinfo on the handle with info_type SMB2_SETINFO_FILE (1),
+          level 20 (SMB_FILE_END_OF_FILE_INFORMATION - 1000). */
+
+       status = smb2cli_set_info(cli->conn,
+                               cli->timeout,
+                               cli->smb2.session,
+                               cli->smb2.tcon,
+                               1, /* in_info_type */
+                                       /* in_file_info_class */
+                               SMB_FILE_END_OF_FILE_INFORMATION - 1000,
+                               &inbuf, /* in_input_buffer */
+                               0, /* in_additional_info */
+                               ph->fid_persistent,
+                               ph->fid_volatile);
+
+  fail:
+
+       cli->raw_status = status;
+
+       TALLOC_FREE(frame);
+       return status;
+}
index ceb5629903656c8a2b653f3b7e5d354ce40f3580..f1ce31bea825f9a2527a98ee29120374808a9fa3 100644 (file)
@@ -184,4 +184,7 @@ struct tevent_req *cli_smb2_splice_send(TALLOC_CTX *mem_ctx,
                        off_t size, off_t src_offset, off_t dst_offset,
                        int (*splice_cb)(off_t n, void *priv), void *priv);
 NTSTATUS cli_smb2_splice_recv(struct tevent_req *req, off_t *written);
+NTSTATUS cli_smb2_ftruncate(struct cli_state *cli,
+                       uint16_t fnum,
+                       uint64_t newsize);
 #endif /* __SMB2CLI_FNUM_H__ */
index 684f26386b6d109e541f8b96e36a52b390b728ff..43a7f247f280c5b4055e758b4748d39dade00a96 100644 (file)
@@ -2889,11 +2889,17 @@ NTSTATUS cli_ftruncate_recv(struct tevent_req *req)
 
 NTSTATUS cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
+       TALLOC_CTX *frame = NULL;
        struct tevent_context *ev = NULL;
        struct tevent_req *req = NULL;
        NTSTATUS status = NT_STATUS_OK;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_ftruncate(cli, fnum, size);
+       }
+
+       frame = talloc_stackframe();
+
        if (smbXcli_conn_has_async_calls(cli->conn)) {
                /*
                 * Can't use sync call while an async call is in flight