summaryrefslogtreecommitdiff
path: root/source4/libcli/smb2
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/smb2')
-rw-r--r--source4/libcli/smb2/session.c126
1 files changed, 64 insertions, 62 deletions
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
index 12479623e7..121323e1dc 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -143,10 +143,72 @@ struct smb2_session_state {
NTSTATUS gensec_status;
};
+static void smb2_session_setup_spnego_handler(struct smb2_request *req);
+
+/*
+ a composite function that does a full SPNEGO session setup
+ */
+struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session,
+ struct cli_credentials *credentials)
+{
+ struct composite_context *c;
+ struct smb2_session_state *state;
+ const char *chosen_oid;
+
+ c = composite_create(session, session->transport->socket->event.ctx);
+ if (c == NULL) return NULL;
+
+ state = talloc(c, struct smb2_session_state);
+ if (composite_nomem(state, c)) return c;
+ c->private_data = state;
+
+ ZERO_STRUCT(state->io);
+ state->io.in.vc_number = 0;
+ if (session->transport->signing_required) {
+ state->io.in.security_mode =
+ SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ }
+ state->io.in.capabilities = 0;
+ state->io.in.channel = 0;
+ state->io.in.previous_sessionid = 0;
+
+ c->status = gensec_set_credentials(session->gensec, credentials);
+ if (!composite_is_ok(c)) return c;
+
+ c->status = gensec_set_target_hostname(session->gensec,
+ session->transport->socket->hostname);
+ if (!composite_is_ok(c)) return c;
+
+ c->status = gensec_set_target_service(session->gensec, "cifs");
+ if (!composite_is_ok(c)) return c;
+
+ if (session->transport->negotiate.secblob.length > 0) {
+ chosen_oid = GENSEC_OID_SPNEGO;
+ } else {
+ chosen_oid = GENSEC_OID_NTLMSSP;
+ }
+
+ c->status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
+ if (!composite_is_ok(c)) return c;
+
+ c->status = gensec_update(session->gensec, c,
+ session->transport->negotiate.secblob,
+ &state->io.in.secblob);
+ if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ composite_error(c, c->status);
+ return c;
+ }
+ state->gensec_status = c->status;
+
+ state->req = smb2_session_setup_send(session, &state->io);
+ composite_continue_smb2(c, state->req, smb2_session_setup_spnego_handler, c);
+ return c;
+}
+
/*
handle continuations of the spnego session setup
*/
-static void session_request_handler(struct smb2_request *req)
+static void smb2_session_setup_spnego_handler(struct smb2_request *req)
{
struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
@@ -184,7 +246,7 @@ static void session_request_handler(struct smb2_request *req)
return;
}
- state->req->async.fn = session_request_handler;
+ state->req->async.fn = smb2_session_setup_spnego_handler;
state->req->async.private_data = c;
return;
}
@@ -208,66 +270,6 @@ static void session_request_handler(struct smb2_request *req)
}
/*
- a composite function that does a full SPNEGO session setup
- */
-struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session,
- struct cli_credentials *credentials)
-{
- struct composite_context *c;
- struct smb2_session_state *state;
- const char *chosen_oid;
-
- c = composite_create(session, session->transport->socket->event.ctx);
- if (c == NULL) return NULL;
-
- state = talloc(c, struct smb2_session_state);
- if (composite_nomem(state, c)) return c;
- c->private_data = state;
-
- ZERO_STRUCT(state->io);
- state->io.in.vc_number = 0;
- if (session->transport->signing_required) {
- state->io.in.security_mode =
- SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
- }
- state->io.in.capabilities = 0;
- state->io.in.channel = 0;
- state->io.in.previous_sessionid = 0;
-
- c->status = gensec_set_credentials(session->gensec, credentials);
- if (!composite_is_ok(c)) return c;
-
- c->status = gensec_set_target_hostname(session->gensec,
- session->transport->socket->hostname);
- if (!composite_is_ok(c)) return c;
-
- c->status = gensec_set_target_service(session->gensec, "cifs");
- if (!composite_is_ok(c)) return c;
-
- if (session->transport->negotiate.secblob.length > 0) {
- chosen_oid = GENSEC_OID_SPNEGO;
- } else {
- chosen_oid = GENSEC_OID_NTLMSSP;
- }
-
- c->status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
- if (!composite_is_ok(c)) return c;
-
- c->status = gensec_update(session->gensec, c,
- session->transport->negotiate.secblob,
- &state->io.in.secblob);
- if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- composite_error(c, c->status);
- return c;
- }
- state->gensec_status = c->status;
-
- state->req = smb2_session_setup_send(session, &state->io);
- composite_continue_smb2(c, state->req, session_request_handler, c);
- return c;
-}
-
-/*
receive a composite session setup reply
*/
NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c)