diff options
author | Stefan Metzmacher <metze@samba.org> | 2014-06-24 00:22:30 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2014-07-24 19:07:06 +0200 |
commit | 720189f246c33c763882731e626c5b0fe558d0f9 (patch) | |
tree | 372962e6517ef6a1509b57e7fc498307253b64d5 /source4 | |
parent | 78e46d7349b5839993c001a5afc2060a48244d15 (diff) | |
download | samba-720189f246c33c763882731e626c5b0fe558d0f9.tar.gz samba-720189f246c33c763882731e626c5b0fe558d0f9.tar.xz samba-720189f246c33c763882731e626c5b0fe558d0f9.zip |
s4:libcli/smb2: add smb2_session_channel()
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/smb2/session.c | 83 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2.h | 1 |
2 files changed, 74 insertions, 10 deletions
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 4d1402a09b..9ab96a3a13 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -66,11 +66,54 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, return session; } +/* + * Note: that the caller needs to keep 'transport' around as + * long as the returned session is active! + */ +struct smb2_session *smb2_session_channel(struct smb2_transport *transport, + struct gensec_settings *settings, + TALLOC_CTX *parent_ctx, + struct smb2_session *base_session) +{ + struct smb2_session *session; + NTSTATUS status; + + session = talloc_zero(parent_ctx, struct smb2_session); + if (!session) { + return NULL; + } + session->transport = transport; + + status = smb2cli_session_create_channel(session, + base_session->smbXcli, + transport->conn, + &session->smbXcli); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(session); + return NULL; + } + + session->needs_bind = true; + + /* prepare a gensec context for later use */ + status = gensec_client_start(session, &session->gensec, + settings); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(session); + return NULL; + } + + gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); + + return session; +} + struct smb2_session_setup_spnego_state { struct tevent_context *ev; struct smb2_session *session; struct cli_credentials *credentials; uint64_t previous_session_id; + bool session_bind; bool reauth; NTSTATUS gensec_status; DATA_BLOB in_secblob; @@ -98,6 +141,7 @@ struct tevent_req *smb2_session_setup_spnego_send( const DATA_BLOB *server_gss_blob; DATA_BLOB negprot_secblob = data_blob_null; uint32_t timeout_msec; + uint8_t in_flags = 0; timeout_msec = session->transport->options.request_timeout * 1000; @@ -112,10 +156,11 @@ struct tevent_req *smb2_session_setup_spnego_send( state->previous_session_id = previous_session_id; current_session_id = smb2cli_session_current_id(state->session->smbXcli); - if (current_session_id != 0) { + if (state->session->needs_bind) { + state->session_bind = true; + } else if (current_session_id != 0) { state->reauth = true; } - server_gss_blob = smbXcli_conn_server_gss_blob(session->transport->conn); if (server_gss_blob) { negprot_secblob = *server_gss_blob; @@ -158,11 +203,15 @@ struct tevent_req *smb2_session_setup_spnego_send( } state->gensec_status = status; + if (state->session_bind) { + in_flags |= SMB2_SESSION_FLAG_BINDING; + } + subreq = smb2cli_session_setup_send(state, state->ev, session->transport->conn, timeout_msec, session->smbXcli, - 0, /* in_flags */ + in_flags, 0, /* in_capabilities */ 0, /* in_channel */ state->previous_session_id, @@ -191,6 +240,7 @@ static void smb2_session_setup_spnego_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *recv_iov; uint32_t timeout_msec; + uint8_t in_flags = 0; timeout_msec = session->transport->options.request_timeout * 1000; @@ -246,22 +296,35 @@ static void smb2_session_setup_spnego_done(struct tevent_req *subreq) return; } - status = smb2cli_session_set_session_key(session->smbXcli, - session_key, - recv_iov); - if (tevent_req_nterror(req, status)) { - return; + if (state->session_bind) { + status = smb2cli_session_set_channel_key(session->smbXcli, + session_key, + recv_iov); + if (tevent_req_nterror(req, status)) { + return; + } + session->needs_bind = false; + } else { + status = smb2cli_session_set_session_key(session->smbXcli, + session_key, + recv_iov); + if (tevent_req_nterror(req, status)) { + return; + } } - tevent_req_done(req); return; } + if (state->session_bind) { + in_flags |= SMB2_SESSION_FLAG_BINDING; + } + subreq = smb2cli_session_setup_send(state, state->ev, session->transport->conn, timeout_msec, session->smbXcli, - 0, /* in_flags */ + in_flags, 0, /* in_capabilities */ 0, /* in_channel */ state->previous_session_id, diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 101ef73807..73e117a961 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -116,6 +116,7 @@ struct smb2_session { struct smb2_transport *transport; struct gensec_security *gensec; struct smbXcli_session *smbXcli; + bool needs_bind; }; |