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;
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;
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;
}
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,
NTSTATUS status;
struct iovec *recv_iov;
uint32_t timeout_msec;
+ uint8_t in_flags = 0;
timeout_msec = session->transport->options.request_timeout * 1000;
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,