s3: Convert cli_unix_extensions_version to async
authorVolker Lendecke <vl@samba.org>
Thu, 12 Nov 2009 22:07:21 +0000 (23:07 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 13 Nov 2009 08:30:30 +0000 (09:30 +0100)
source3/client/client.c
source3/include/proto.h
source3/libsmb/clidfs.c
source3/libsmb/clifsinfo.c
source3/torture/torture.c

index 6a3e73c710ea01beb5a657599d6c27630d8c4b55..f81762a5632e2ddafafe7a91d73c5b8fb83278f5 100644 (file)
@@ -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;
        }
 
index 0eb5815f64190529597f0c793b9d0ddfd0f8316e..f9a2a50ec25aa7e95f8d77148531234ecf37c0a2 100644 (file)
@@ -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);
index 33529595a20d6335f37b3f62837f43ea5cab4ccd..0afb75975ed80f1ff8de094672ac4f85571e3dff 100644 (file)
@@ -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);
index 308a6f7215f53ca983f7ffaa0d07afdc60a60405..03ec54ab8cbec6d1b9ec01f9e30fb8c88b719a36 100644 (file)
  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;
        }
 
index bda82f2b7494504f90d5c04a09dc60b1b21aa530..9abcabde89b05682d2cda1aa346d2ebefc87eb05 100644 (file)
@@ -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;
        }