summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/client/client.c17
-rw-r--r--source3/include/proto.h12
-rw-r--r--source3/libsmb/clidfs.c6
-rw-r--r--source3/libsmb/clifsinfo.c164
-rw-r--r--source3/torture/torture.c15
5 files changed, 159 insertions, 55 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index 6a3e73c710..f81762a563 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2449,14 +2449,18 @@ static int cmd_posix(void)
uint16 major, minor;
uint32 caplow, caphigh;
char *caps;
+ NTSTATUS status;
if (!SERVER_HAS_UNIX_CIFS(cli)) {
d_printf("Server doesn't support UNIX CIFS extensions.\n");
return 1;
}
- if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
- d_printf("Can't get UNIX CIFS extensions version from server.\n");
+ status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Can't get UNIX CIFS extensions version from "
+ "server: %s\n", nt_errstr(status));
return 1;
}
@@ -2983,6 +2987,7 @@ static int cmd_getfacl(void)
uint16 num_file_acls = 0;
uint16 num_dir_acls = 0;
uint16 i;
+ NTSTATUS status;
if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
d_printf("getfacl filename\n");
@@ -3006,9 +3011,11 @@ static int cmd_getfacl(void)
return 1;
}
- if (!cli_unix_extensions_version(targetcli, &major, &minor,
- &caplow, &caphigh)) {
- d_printf("Can't get UNIX CIFS version from server.\n");
+ status = cli_unix_extensions_version(targetcli, &major, &minor,
+ &caplow, &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Can't get UNIX CIFS version from server: %s.\n",
+ nt_errstr(status));
return 1;
}
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0eb5815f64..f9a2a50ec2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2682,8 +2682,16 @@ NTSTATUS cli_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
/* The following definitions come from libsmb/clifsinfo.c */
-bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor,
- uint32 *pcaplow, uint32 *pcaphigh);
+struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli);
+NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req,
+ uint16_t *pmajor, uint16_t *pminor,
+ uint32_t *pcaplow,
+ uint32_t *pcaphigh);
+NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
+ uint16 *pminor, uint32 *pcaplow,
+ uint32 *pcaphigh);
bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor,
uint32 caplow, uint32 caphigh);
bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr);
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 33529595a2..0afb75975e 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -322,8 +322,10 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
if (referring_cli && referring_cli->posix_capabilities) {
uint16 major, minor;
uint32 caplow, caphigh;
- if (cli_unix_extensions_version(cli, &major,
- &minor, &caplow, &caphigh)) {
+ NTSTATUS status;
+ status = cli_unix_extensions_version(cli, &major, &minor,
+ &caplow, &caphigh);
+ if (NT_STATUS_IS_OK(status)) {
cli_set_unix_extensions_capabilities(cli,
major, minor,
caplow, caphigh);
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index 308a6f7215..03ec54ab8c 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -25,59 +25,136 @@
Get UNIX extensions version info.
****************************************************************************/
-bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor,
- uint32 *pcaplow, uint32 *pcaphigh)
+struct cli_unix_extensions_version_state {
+ uint16_t setup[1];
+ uint8_t param[2];
+ uint16_t major, minor;
+ uint32_t caplow, caphigh;
+};
+
+static void cli_unix_extensions_version_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli)
{
- bool ret = False;
- uint16 setup;
- char param[2];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
-
- setup = TRANSACT2_QFSINFO;
-
- SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO);
+ struct tevent_req *req, *subreq;
+ struct cli_unix_extensions_version_state *state;
- if (!cli_send_trans(cli, SMBtrans2,
- NULL,
- 0, 0,
- &setup, 1, 0,
- param, 2, 0,
- NULL, 0, 560)) {
- goto cleanup;
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_unix_extensions_version_state);
+ if (req == NULL) {
+ return NULL;
}
+ SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
+ SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO);
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- goto cleanup;
+ subreq = cli_trans_send(state, ev, cli, SMBtrans2,
+ NULL, 0, 0, 0,
+ state->setup, 1, 0,
+ state->param, 2, 0,
+ NULL, 0, 560);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq, cli_unix_extensions_version_done, req);
+ return req;
+}
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
+static void cli_unix_extensions_version_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_unix_extensions_version_state *state = tevent_req_data(
+ req, struct cli_unix_extensions_version_state);
+ uint8_t *data;
+ uint32_t num_data;
+ NTSTATUS status;
+
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+ &data, &num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ if (num_data < 12) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
}
- if (rdata_count < 12) {
- goto cleanup;
+ state->major = SVAL(data, 0);
+ state->minor = SVAL(data, 2);
+ state->caplow = IVAL(data, 4);
+ state->caphigh = IVAL(data, 8);
+ TALLOC_FREE(data);
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req,
+ uint16_t *pmajor, uint16_t *pminor,
+ uint32_t *pcaplow,
+ uint32_t *pcaphigh)
+{
+ struct cli_unix_extensions_version_state *state = tevent_req_data(
+ req, struct cli_unix_extensions_version_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *pmajor = state->major;
+ *pminor = state->minor;
+ *pcaplow = state->caplow;
+ *pcaphigh = state->caphigh;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
+ uint16 *pminor, uint32 *pcaplow,
+ uint32 *pcaphigh)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ 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;
}
- *pmajor = SVAL(rdata,0);
- *pminor = SVAL(rdata,2);
- cli->posix_capabilities = *pcaplow = IVAL(rdata,4);
- *pcaphigh = IVAL(rdata,8);
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
- /* todo: but not yet needed
- * return the other stuff
- */
+ req = cli_unix_extensions_version_send(frame, ev, cli);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
-cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
- return ret;
+ status = cli_unix_extensions_version_recv(req, pmajor, pminor, pcaplow,
+ pcaphigh);
+ if (NT_STATUS_IS_OK(status)) {
+ cli->posix_capabilities = *pcaplow;
+ }
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -789,12 +866,17 @@ NTSTATUS cli_force_encryption(struct cli_state *c,
{
uint16 major, minor;
uint32 caplow, caphigh;
+ NTSTATUS status;
if (!SERVER_HAS_UNIX_CIFS(c)) {
return NT_STATUS_NOT_SUPPORTED;
}
- if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+ status = cli_unix_extensions_version(c, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("cli_force_encryption: cli_unix_extensions_version "
+ "returned %s\n", nt_errstr(status)));
return NT_STATUS_UNKNOWN_REVISION;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index bda82f2b74..9abcabde89 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -136,10 +136,12 @@ static bool force_cli_encryption(struct cli_state *c,
return false;
}
- if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+ status = cli_unix_extensions_version(c, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Encryption required and "
"can't get UNIX CIFS extensions "
- "version from server.\n");
+ "version from server: %s\n", nt_errstr(status));
return false;
}
@@ -4367,6 +4369,7 @@ static bool run_simple_posix_open_test(int dummy)
uint16_t fnum1 = (uint16_t)-1;
SMB_STRUCT_STAT sbuf;
bool correct = false;
+ NTSTATUS status;
printf("Starting simple POSIX open test\n");
@@ -4381,9 +4384,11 @@ static bool run_simple_posix_open_test(int dummy)
return false;
}
- if (!cli_unix_extensions_version(cli1, &major,
- &minor, &caplow, &caphigh)) {
- printf("Server didn't return UNIX CIFS extensions.\n");
+ status = cli_unix_extensions_version(cli1, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Server didn't return UNIX CIFS extensions: %s\n",
+ nt_errstr(status));
return false;
}