diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/client/client.c | 9 | ||||
-rw-r--r-- | source3/include/proto.h | 25 | ||||
-rw-r--r-- | source3/libsmb/clirap.c | 151 | ||||
-rw-r--r-- | source3/libsmb/libsmb_file.c | 4 | ||||
-rw-r--r-- | source3/torture/torture.c | 47 |
5 files changed, 144 insertions, 92 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index b88f180855..efe733e7f4 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1576,10 +1576,11 @@ static int do_allinfo(const char *name) } d_printf("altname: %s\n", altname); - if (!cli_qpathinfo2(cli, name, &b_time, &a_time, &m_time, &c_time, - &size, &mode, &ino)) { - d_printf("%s getting pathinfo for %s\n", - cli_errstr(cli),name); + status = cli_qpathinfo2(cli, name, &b_time, &a_time, &m_time, &c_time, + &size, &mode, &ino); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s getting pathinfo for %s\n", nt_errstr(status), + name); return false; } diff --git a/source3/include/proto.h b/source3/include/proto.h index cbfe103000..c802b69951 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2665,13 +2665,24 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, time_t write_time, time_t change_time, uint16 mode); -bool cli_qpathinfo2(struct cli_state *cli, const char *fname, - struct timespec *create_time, - struct timespec *access_time, - struct timespec *write_time, - struct timespec *change_time, - SMB_OFF_T *size, uint16 *mode, - SMB_INO_T *ino); +struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_OFF_T *size, uint16 *mode, + SMB_INO_T *ino); +NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_OFF_T *size, uint16 *mode, + SMB_INO_T *ino); bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, TALLOC_CTX *mem_ctx, unsigned int *pnum_streams, diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c4b36486bb..baa2dcd8e2 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -768,81 +768,132 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, Send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level. ****************************************************************************/ -bool cli_qpathinfo2(struct cli_state *cli, const char *fname, - struct timespec *create_time, - struct timespec *access_time, - struct timespec *write_time, - struct timespec *change_time, - SMB_OFF_T *size, uint16 *mode, - SMB_INO_T *ino) +struct cli_qpathinfo2_state { + uint32_t num_data; + uint8_t *data; +}; + +static void cli_qpathinfo2_done(struct tevent_req *subreq); + +struct tevent_req *cli_qpathinfo2_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; - uint16 setup = TRANSACT2_QPATHINFO; - char *param; - char *rparam=NULL, *rdata=NULL; - char *p; - size_t nlen = 2*(strlen(fname)+1); + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_qpathinfo2_state *state = NULL; - param = SMB_MALLOC_ARRAY(char, 6+nlen+2); - if (!param) { - return false; + req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo2_state); + if (req == NULL) { + return NULL; } - p = param; - memset(param, '\0', 6); - SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); - p += 6; - p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); + subreq = cli_qpathinfo_send(state, ev, cli, fname, + SMB_QUERY_FILE_ALL_INFO, + 68, cli->max_xmit); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_qpathinfo2_done, req); + return req; +} - param_len = PTR_DIFF(p, param); +static void cli_qpathinfo2_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_qpathinfo2_state *state = tevent_req_data( + req, struct cli_qpathinfo2_state); + NTSTATUS status; - if (!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 */ - )) { - SAFE_FREE(param); - 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); +} - SAFE_FREE(param); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } +NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_OFF_T *size, uint16 *mode, + SMB_INO_T *ino) +{ + struct cli_qpathinfo2_state *state = tevent_req_data( + req, struct cli_qpathinfo2_state); + NTSTATUS status; - if (!rdata || data_len < 68) { - return False; + if (tevent_req_is_nterror(req, &status)) { + return status; } if (create_time) { - *create_time = interpret_long_date(rdata+0); + *create_time = interpret_long_date((char *)state->data+0); } if (access_time) { - *access_time = interpret_long_date(rdata+8); + *access_time = interpret_long_date((char *)state->data+8); } if (write_time) { - *write_time = interpret_long_date(rdata+16); + *write_time = interpret_long_date((char *)state->data+16); } if (change_time) { - *change_time = interpret_long_date(rdata+24); + *change_time = interpret_long_date((char *)state->data+24); } if (mode) { - *mode = SVAL(rdata, 32); + *mode = SVAL(state->data, 32); } if (size) { - *size = IVAL2_TO_SMB_BIG_UINT(rdata,48); + *size = IVAL2_TO_SMB_BIG_UINT(state->data,48); } if (ino) { - *ino = IVAL(rdata, 64); + *ino = IVAL(state->data, 64); } + return NT_STATUS_OK; +} - SAFE_FREE(rdata); - SAFE_FREE(rparam); - return True; +NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_OFF_T *size, uint16 *mode, + SMB_INO_T *ino) +{ + 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_qpathinfo2_send(frame, ev, cli, fname); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_qpathinfo2_recv(req, change_time, access_time, + write_time, change_time, size, mode, ino); + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index b3b0bc2b9f..8250da2b30 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -531,12 +531,12 @@ SMBC_getatr(SMBCCTX * context, } if (!srv->no_pathinfo2 && - cli_qpathinfo2(targetcli, targetpath, + NT_STATUS_IS_OK(cli_qpathinfo2(targetcli, targetpath, create_time_ts, access_time_ts, write_time_ts, change_time_ts, - size, mode, ino)) { + size, mode, ino))) { TALLOC_FREE(frame); return True; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 37c43f5a5b..90cbf90c1a 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2896,9 +2896,10 @@ static bool run_trans2test(int dummy) cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum); cli_close(cli, fnum); - if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, - &m_time_ts, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); + status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, + &m_time_ts, &size, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status)); correct = False; } else { if (w_time_ts.tv_sec < 60*60*24*2) { @@ -2918,9 +2919,10 @@ static bool run_trans2test(int dummy) correct = False; } sleep(3); - if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, - &m_time_ts, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); + status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, + &w_time_ts, &m_time_ts, &size, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status)); correct = False; } @@ -2928,9 +2930,10 @@ static bool run_trans2test(int dummy) O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum); cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum)); cli_close(cli, fnum); - if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, - &m_time2_ts, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli)); + status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, + &w_time_ts, &m_time2_ts, &size, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status)); correct = False; } else { if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec)) @@ -6408,16 +6411,9 @@ static bool run_dir_createtime(int dummy) goto out; } - if (!cli_qpathinfo2(cli, - dname, - &create_time, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL)) { - status = cli_nt_error(cli); + status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { printf("cli_qpathinfo2 returned %s\n", nt_errstr(status)); goto out; @@ -6433,16 +6429,9 @@ static bool run_dir_createtime(int dummy) goto out; } - if (!cli_qpathinfo2(cli, - dname, - &create_time1, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL)) { - status = cli_nt_error(cli); + status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { printf("cli_qpathinfo2 (2) returned %s\n", nt_errstr(status)); goto out; |