From: Gregor Beck Date: Thu, 12 Sep 2013 07:51:01 +0000 (+0200) Subject: libcli/smb: add smb1cli_close* X-Git-Tag: tevent-0.9.21~220 X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=b9d19e876f002f39a90042231ab5c34ebe24d5c2 libcli/smb: add smb1cli_close* Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Gregor Beck Signed-off-by: Stefan Metzmacher Reviewed-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/libcli/smb/smb1cli_close.c b/libcli/smb/smb1cli_close.c new file mode 100644 index 00000000000..89fbbba83f5 --- /dev/null +++ b/libcli/smb/smb1cli_close.c @@ -0,0 +1,188 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Gregor Beck 2013 + Copyright (C) Stefan Metzmacher 2013 + + 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 . +*/ + +#include "includes.h" +#include "system/network.h" +#include "lib/util/tevent_ntstatus.h" +#include "smb_common.h" +#include "smbXcli_base.h" + +struct smb1cli_close_state { + uint16_t vwv[3]; +}; + +static void smb1cli_close_done(struct tevent_req *subreq); + +/** + * Send an asynchronous SMB_COM_CLOSE request. + * MS-CIFS 2.2.4.5.1 + * @see smb1cli_close_recv(), smb1cli_close() + * + * @param[in] mem_ctx The memory context for the result. + * @param[in] ev The event context to work on. + * @param[in] conn The smb connection. + * @param[in] timeout_msec If positiv a timeout for the request. + * @param[in] pid The process identifier. + * @param[in] tcon The smb tree connect. + * @param[in] session The smb session. + * @param[in] fnum The file id of the file to be closed. + * @param[in] last_modified If not 0 or 0xFFFFFFFF request to set modification time to this number of seconds since January 1, 1970. + * + * @return a tevent_req or NULL. + */ +struct tevent_req *smb1cli_close_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_tcon *tcon, + struct smbXcli_session *session, + uint16_t fnum, + uint32_t last_modified) +{ + struct tevent_req *req, *subreq; + struct smb1cli_close_state *state; + + req = tevent_req_create(mem_ctx, &state, struct smb1cli_close_state); + if (req == NULL) { + return NULL; + } + + SSVAL(state->vwv+0, 0, fnum); + SIVALS(state->vwv+1, 0, last_modified); + + subreq = smb1cli_req_send(state, ev, conn, SMBclose, + 0, 0, /* *_flags */ + 0, 0, /* *_flags2 */ + timeout_msec, pid, tcon, session, + ARRAY_SIZE(state->vwv), state->vwv, + 0, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, smb1cli_close_done, req); + return req; +} + +static void smb1cli_close_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct smb1cli_close_state *state = tevent_req_data( + req, struct smb1cli_close_state); + NTSTATUS status; + static const struct smb1cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .wct = 0x00 + }, + }; + + status = smb1cli_req_recv(subreq, state, + NULL, /* recv_iov */ + NULL, /* phdr */ + NULL, /* wct */ + NULL, /* vwv */ + NULL, /* pvwv_offset */ + NULL, /* num_bytes */ + NULL, /* bytes */ + NULL, /* pbytes_offset */ + NULL, /* inbuf */ + expected, ARRAY_SIZE(expected)); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); +} + +/** + * Receive the response to an asynchronous SMB_COM_CLOSE request. + * MS-CIFS 2.2.4.5.2 + * + * @param req A tevent_req created with smb1cli_close_send() + * + * @return NT_STATUS_OK on success + */ +NTSTATUS smb1cli_close_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +/** + * Send an synchronous SMB_COM_CLOSE request. + * MS-CIFS 2.2.4.5 + * @see smb1cli_close_send(), smb1cli_close_recv() + * + * @param[in] conn The smb connection. + * @param[in] timeout_msec If positiv a timeout for the request. + * @param[in] pid The process identifier. + * @param[in] tcon The smb tree connect. + * @param[in] session The smb session. + * @param[in] fnum The file id of the file to be closed. + * @param[in] last_modified If not 0 or 0xFFFFFFFF request to set modification time to this number of seconds since J + * + * @return NT_STATUS_OK on success. + */ +NTSTATUS smb1cli_close(struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_tcon *tcon, + struct smbXcli_session *session, + uint16_t fnum, + uint32_t last_modified) +{ + NTSTATUS status = NT_STATUS_OK; + struct tevent_req *req; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev; + + if (smbXcli_conn_has_async_calls(conn)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + ev = samba_tevent_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + req = smb1cli_close_send(frame, ev, conn, + timeout_msec, pid, tcon, session, + fnum, last_modified); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto done; + } + + status = smb1cli_close_recv(req); +done: + talloc_free(frame); + return status; +} diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index cb705f1f17f..64c6e417c58 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -237,6 +237,23 @@ NTSTATUS smb1cli_ntcreatex(struct smbXcli_conn *conn, uint32_t ImpersonationLevel, uint8_t SecurityFlags, uint16_t *pfnum); +struct tevent_req *smb1cli_close_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_tcon *tcon, + struct smbXcli_session *session, + uint16_t fnum, + uint32_t last_modified); +NTSTATUS smb1cli_close_recv(struct tevent_req *req); +NTSTATUS smb1cli_close(struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_tcon *tcon, + struct smbXcli_session *session, + uint16_t fnum, + uint32_t last_modified); bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len); uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn); diff --git a/libcli/smb/wscript b/libcli/smb/wscript index 06a5dc861d7..a6fc381ea07 100755 --- a/libcli/smb/wscript +++ b/libcli/smb/wscript @@ -24,6 +24,7 @@ def build(bld): smb1cli_trans.c smb1cli_echo.c smb1cli_create.c + smb1cli_close.c smb2cli_session.c smb2cli_create.c smb2cli_close.c