From: Stefan Metzmacher Date: Tue, 20 Jun 2017 06:35:13 +0000 (+0200) Subject: s3:libsmb: add cli_smb2_delete_on_close*() X-Git-Tag: tevent-0.9.32~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d4005b07b08d5673b75d5d79f9b3d6936596fae;p=thirdparty%2Fsamba.git s3:libsmb: add cli_smb2_delete_on_close*() Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 351fccfb645..954f3fe3a7f 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -485,6 +485,133 @@ NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum) return status; } +struct cli_smb2_delete_on_close_state { + struct cli_state *cli; + uint16_t fnum; + struct smb2_hnd *ph; + uint8_t data[1]; + DATA_BLOB inbuf; +}; + +static void cli_smb2_delete_on_close_done(struct tevent_req *subreq); + +struct tevent_req *cli_smb2_delete_on_close_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t fnum, + bool flag) +{ + struct tevent_req *req = NULL; + struct cli_smb2_delete_on_close_state *state = NULL; + struct tevent_req *subreq = NULL; + uint8_t in_info_type; + uint8_t in_file_info_class; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct cli_smb2_delete_on_close_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; + state->fnum = fnum; + + if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + status = map_fnum_to_smb2_handle(cli, fnum, &state->ph); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + /* + * setinfo on the handle with info_type SMB2_SETINFO_FILE (1), + * level 13 (SMB_FILE_DISPOSITION_INFORMATION - 1000). + */ + in_info_type = 1; + in_file_info_class = SMB_FILE_DISPOSITION_INFORMATION - 1000; + /* Setup data array. */ + SCVAL(&state->data[0], 0, flag ? 1 : 0); + state->inbuf.data = &state->data[0]; + state->inbuf.length = 1; + + subreq = smb2cli_set_info_send(state, ev, + cli->conn, + cli->timeout, + cli->smb2.session, + cli->smb2.tcon, + in_info_type, + in_file_info_class, + &state->inbuf, /* in_input_buffer */ + 0, /* in_additional_info */ + state->ph->fid_persistent, + state->ph->fid_volatile); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + cli_smb2_delete_on_close_done, + req); + return req; +} + +static void cli_smb2_delete_on_close_done(struct tevent_req *subreq) +{ + NTSTATUS status = smb2cli_set_info_recv(subreq); + tevent_req_simple_finish_ntstatus(subreq, status); +} + +NTSTATUS cli_smb2_delete_on_close_recv(struct tevent_req *req) +{ + struct cli_smb2_delete_on_close_state *state = + tevent_req_data(req, + struct cli_smb2_delete_on_close_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + state->cli->raw_status = status; + tevent_req_received(req); + return status; + } + + state->cli->raw_status = NT_STATUS_OK; + tevent_req_received(req); + return NT_STATUS_OK; +} + +NTSTATUS cli_smb2_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + 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; + } + ev = samba_tevent_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_smb2_delete_on_close_send(frame, ev, cli, fnum, flag); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_smb2_delete_on_close_recv(req); + fail: + TALLOC_FREE(frame); + return status; +} + /*************************************************************** Small wrapper that allows SMB2 to create a directory Synchronous only. diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index 43e04713da1..190ec59971b 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -54,6 +54,13 @@ struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx, uint16_t fnum); NTSTATUS cli_smb2_close_fnum_recv(struct tevent_req *req); NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum); +struct tevent_req *cli_smb2_delete_on_close_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t fnum, + bool flag); +NTSTATUS cli_smb2_delete_on_close_recv(struct tevent_req *req); +NTSTATUS cli_smb2_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag); NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dirname); NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dirname); NTSTATUS cli_smb2_unlink(struct cli_state *cli,const char *fname);