s4:libcli: add fallback_to_anonymous to smb2_connect_send()
authorStefan Metzmacher <metze@samba.org>
Wed, 18 Jul 2018 21:52:30 +0000 (23:52 +0200)
committerAlexander Bokovoy <ab@samba.org>
Tue, 24 Jul 2018 04:55:23 +0000 (06:55 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13308

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
source4/libcli/smb2/connect.c
source4/librpc/rpc/dcerpc_connect.c

index 2dee5021869485110e101d701e4c77889ce16666..e4cbf8c5c4198fc18b5a6acdb4d8834b1aa1cd1a 100644 (file)
@@ -35,6 +35,7 @@
 struct smb2_connect_state {
        struct tevent_context *ev;
        struct cli_credentials *credentials;
+       bool fallback_to_anonymous;
        uint64_t previous_session_id;
        struct resolve_context *resolve_ctx;
        const char *host;
@@ -64,6 +65,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
                                     const char *share,
                                     struct resolve_context *resolve_ctx,
                                     struct cli_credentials *credentials,
+                                    bool fallback_to_anonymous,
                                     struct smbXcli_conn **existing_conn,
                                     uint64_t previous_session_id,
                                     const struct smbcli_options *options,
@@ -83,6 +85,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 
        state->ev = ev;
        state->credentials = credentials;
+       state->fallback_to_anonymous = fallback_to_anonymous;
        state->previous_session_id = previous_session_id;
        state->options = *options;
        state->host = host;
@@ -240,6 +243,34 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
 
        status = smb2_session_setup_spnego_recv(subreq);
        TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status) &&
+           !cli_credentials_is_anonymous(state->credentials) &&
+           state->fallback_to_anonymous) {
+               struct cli_credentials *anon_creds = NULL;
+
+               /*
+                * The transport was moved to session,
+                * we need to revert that before removing
+                * the old broken session.
+                */
+               state->transport = talloc_move(state, &state->session->transport);
+               TALLOC_FREE(state->session);
+
+               anon_creds = cli_credentials_init_anon(state);
+               if (tevent_req_nomem(anon_creds, req)) {
+                       return;
+               }
+               cli_credentials_set_workstation(anon_creds,
+                  cli_credentials_get_workstation(state->credentials),
+                  CRED_SPECIFIED);
+
+               /*
+                * retry with anonymous credentials
+                */
+               state->credentials = anon_creds;
+               smb2_connect_session_start(req);
+               return;
+       }
        if (tevent_req_nterror(req, status)) {
                return;
        }
@@ -331,6 +362,7 @@ NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx,
                                   share,
                                   resolve_ctx,
                                   credentials,
+                                  false, /* fallback_to_anonymous */
                                   NULL, /* existing_conn */
                                   previous_session_id,
                                   options,
index a3f25efc0b47e9b5930ef94c89cfb379a216a2d0..d31bbe152e3eb731e45e3134156aee55f139c16e 100644 (file)
@@ -301,6 +301,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send(
                        "IPC$",
                        s->io.resolve_ctx,
                        s->io.creds,
+                       false, /* fallback_to_anonymous */
                        NULL, /* existing_conn */
                        0, /* previous_session_id */
                        &options,