summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h12
-rw-r--r--source3/libsmb/clirap.c166
-rw-r--r--source3/torture/torture.c13
3 files changed, 124 insertions, 67 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3759a78c72..cbfe103000 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2642,7 +2642,17 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
void *state);
bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
const char *old_password);
-bool cli_qpathinfo1(struct cli_state *cli,
+struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname);
+NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req,
+ time_t *change_time,
+ time_t *access_time,
+ time_t *write_time,
+ SMB_OFF_T *size,
+ uint16 *mode);
+NTSTATUS cli_qpathinfo1(struct cli_state *cli,
const char *fname,
time_t *change_time,
time_t *access_time,
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index afea8b5d9c..2135859f68 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -531,90 +531,134 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char
Send a qpathinfo call.
****************************************************************************/
-bool cli_qpathinfo1(struct cli_state *cli,
- const char *fname,
- time_t *change_time,
- time_t *access_time,
- time_t *write_time,
- SMB_OFF_T *size,
- uint16 *mode)
+struct cli_qpathinfo1_state {
+ struct cli_state *cli;
+ uint32_t num_data;
+ uint8_t *data;
+};
+
+static void cli_qpathinfo1_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname)
{
- unsigned int data_len = 0;
- unsigned int param_len = 0;
- unsigned int rparam_len, rdata_len;
- uint16 setup = TRANSACT2_QPATHINFO;
- char *param;
- char *rparam=NULL, *rdata=NULL;
- int count=8;
- bool ret;
- time_t (*date_fn)(struct cli_state *, const void *);
- char *p;
- size_t nlen = 2*(strlen(fname)+1);
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct cli_qpathinfo1_state *state = NULL;
- param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
- if (!param) {
- return false;
+ req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo1_state);
+ if (req == NULL) {
+ return NULL;
}
- p = param;
- memset(p, '\0', 6);
- SSVAL(p, 0, SMB_INFO_STANDARD);
- p += 6;
- p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
+ state->cli = cli;
+ subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_INFO_STANDARD,
+ 22, cli->max_xmit);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_qpathinfo1_done, req);
+ return req;
+}
- do {
- ret = (cli_send_trans(cli, SMBtrans2,
- NULL, /* Name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 10, /* param, length, max */
- NULL, data_len, cli->max_xmit /* data, length, max */
- ) &&
- cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_len,
- &rdata, &rdata_len));
- if (!cli_is_dos_error(cli)) break;
- if (!ret) {
- /* we need to work around a Win95 bug - sometimes
- it gives ERRSRV/ERRerror temprarily */
- uint8 eclass;
- uint32 ecode;
- cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRSRV || ecode != ERRerror) break;
- smb_msleep(100);
- }
- } while (count-- && ret==False);
+static void cli_qpathinfo1_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_qpathinfo1_state *state = tevent_req_data(
+ req, struct cli_qpathinfo1_state);
+ NTSTATUS status;
- SAFE_FREE(param);
- if (!ret || !rdata || rdata_len < 22) {
- return False;
+ status = cli_qpathinfo_recv(subreq, state, &state->data,
+ &state->num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- if (cli->win95) {
+NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req,
+ time_t *change_time,
+ time_t *access_time,
+ time_t *write_time,
+ SMB_OFF_T *size,
+ uint16 *mode)
+{
+ struct cli_qpathinfo1_state *state = tevent_req_data(
+ req, struct cli_qpathinfo1_state);
+ NTSTATUS status;
+
+ time_t (*date_fn)(struct cli_state *, const void *);
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ if (state->cli->win95) {
date_fn = cli_make_unix_date;
} else {
date_fn = cli_make_unix_date2;
}
if (change_time) {
- *change_time = date_fn(cli, rdata+0);
+ *change_time = date_fn(state->cli, state->data+0);
}
if (access_time) {
- *access_time = date_fn(cli, rdata+4);
+ *access_time = date_fn(state->cli, state->data+4);
}
if (write_time) {
- *write_time = date_fn(cli, rdata+8);
+ *write_time = date_fn(state->cli, state->data+8);
}
if (size) {
- *size = IVAL(rdata, 12);
+ *size = IVAL(state->data, 12);
}
if (mode) {
- *mode = SVAL(rdata,l1_attrFile);
+ *mode = SVAL(state->data, l1_attrFile);
}
+ return NT_STATUS_OK;
+}
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return True;
+NTSTATUS cli_qpathinfo1(struct cli_state *cli,
+ const char *fname,
+ time_t *change_time,
+ time_t *access_time,
+ time_t *write_time,
+ SMB_OFF_T *size,
+ uint16 *mode)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = cli_qpathinfo1_send(frame, ev, cli, fname);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+ status = cli_qpathinfo1_recv(req, change_time, access_time,
+ write_time, size, mode);
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index f958817320..37c43f5a5b 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -2868,8 +2868,10 @@ static bool run_trans2test(int dummy)
}
cli_close(cli, fnum);
- if (!cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
- printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
+ status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
correct = False;
} else {
if (c_time != m_time) {
@@ -5962,10 +5964,11 @@ static bool run_mangle1(int dummy)
}
cli_close(cli, fnum);
- if (!cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
- &write_time, &size, &mode)) {
+ status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
+ &write_time, &size, &mode);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
- cli_errstr(cli));
+ nt_errstr(status));
return false;
}