summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h8
-rw-r--r--source3/libsmb/clifile.c114
-rw-r--r--source3/torture/torture.c11
3 files changed, 108 insertions, 25 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 51d0c1788d..3759a78c72 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2466,7 +2466,13 @@ NTSTATUS cli_ctemp(struct cli_state *cli,
NTSTATUS cli_raw_ioctl(struct cli_state *cli, uint16_t fnum, uint32_t code, DATA_BLOB *blob);
bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len);
bool cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, const char *ea_name, const char *ea_val, size_t ea_len);
-bool cli_get_ea_list_path(struct cli_state *cli, const char *path,
+struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ const char *fname);
+NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ size_t *pnum_eas, struct ea_struct **peas);
+NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 93e926492b..319812357a 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4329,32 +4329,106 @@ fail:
Get an extended attribute list from a pathname.
*********************************************************/
-bool cli_get_ea_list_path(struct cli_state *cli, const char *path,
+struct cli_get_ea_list_path_state {
+ uint32_t num_data;
+ uint8_t *data;
+};
+
+static void cli_get_ea_list_path_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ const char *fname)
+{
+ struct tevent_req *req, *subreq;
+ struct cli_get_ea_list_path_state *state;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_get_ea_list_path_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ subreq = cli_qpathinfo_send(state, ev, cli, fname,
+ SMB_INFO_QUERY_ALL_EAS, 4,
+ cli->max_xmit);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_get_ea_list_path_done, req);
+ return req;
+}
+
+static void cli_get_ea_list_path_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_get_ea_list_path_state *state = tevent_req_data(
+ req, struct cli_get_ea_list_path_state);
+ NTSTATUS status;
+
+ 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);
+}
+
+NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ size_t *pnum_eas, struct ea_struct **peas)
+{
+ struct cli_get_ea_list_path_state *state = tevent_req_data(
+ req, struct cli_get_ea_list_path_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ if (!parse_ea_blob(mem_ctx, state->data, state->num_data,
+ pnum_eas, peas)) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list)
{
- uint16_t setup = TRANSACT2_QPATHINFO;
- unsigned int param_len = 0;
- char *param;
- char *p;
- size_t srclen = 2*(strlen(path)+1);
- bool ret;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
- param = SMB_MALLOC_ARRAY(char, 6+srclen+2);
- if (!param) {
- return false;
+ 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;
}
- p = param;
- memset(p, 0, 6);
- SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS);
- p += 6;
- p += clistr_push(cli, p, path, srclen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
-
- ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list);
- SAFE_FREE(param);
- return ret;
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = cli_get_ea_list_path_send(frame, ev, cli, path);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+ status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list);
+ 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 be9cfccf98..f958817320 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5009,6 +5009,7 @@ static bool run_eatest(int dummy)
size_t num_eas;
struct ea_struct *ea_list = NULL;
TALLOC_CTX *mem_ctx = talloc_init("eatest");
+ NTSTATUS status;
printf("starting eatest\n");
@@ -5052,8 +5053,9 @@ static bool run_eatest(int dummy)
}
}
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
+ status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ea_get list failed - %s\n", nt_errstr(status));
correct = False;
}
@@ -5087,8 +5089,9 @@ static bool run_eatest(int dummy)
}
#endif
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
+ status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ea_get list failed - %s\n", nt_errstr(status));
correct = False;
}