From: Jeremy Allison Date: Wed, 21 Dec 2016 21:55:50 +0000 (-0800) Subject: s3: libsmb: Add cli_smb2_ftruncate(), plumb into cli_ftruncate(). X-Git-Tag: samba-4.4.10~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=837a6664564d81c7032411044d205f86cbd0e1b9;p=thirdparty%2Fsamba.git s3: libsmb: Add cli_smb2_ftruncate(), plumb into cli_ftruncate(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12479 Signed-off-by: Jeremy Allison Reviewed-by: Uri Simchoni (cherry picked from commit e0f1ed9f450851bf5b7fec84577b50047309db3f) --- diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index c5b1434eaaa..665a38d3c73 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -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; +} diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index ceb56299036..f1ce31bea82 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -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__ */ diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 684f26386b6..43a7f247f28 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -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