+ struct smbXsrv_session *session;
+ NTSTATUS status;
+ NTTIME now = timeval_to_nttime(&req->request_time);
+
+ *out_session_flags = 0;
+ *out_session_id = 0;
+
+ if (in_session_id == 0) {
+ /* create a new session */
+ status = smbXsrv_session_create(smb2req->sconn->conn,
+ now, &session);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ } else {
+ status = smb2srv_session_lookup(smb2req->sconn->conn,
+ in_session_id, now,
+ &session);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+ status = NT_STATUS_OK;
+ }
+ if (NT_STATUS_IS_OK(status)) {
+ session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ TALLOC_FREE(session->gensec);
+ }
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ return status;
+ }
+ }
+
+ return smbd_smb2_auth_generic(session,
+ smb2req,
+ in_security_mode,
+ in_previous_session_id,
+ in_security_buffer,
+ out_session_flags,
+ out_security_buffer,
+ out_session_id);
+}
+
+struct smbd_smb2_session_setup_state {
+ struct tevent_context *ev;
+ struct smbd_smb2_request *smb2req;
+ uint64_t in_session_id;
+ uint8_t in_flags;
+ uint8_t in_security_mode;
+ uint64_t in_previous_session_id;
+ DATA_BLOB in_security_buffer;
+ uint16_t out_session_flags;
+ DATA_BLOB out_security_buffer;
+ uint64_t out_session_id;
+};
+
+static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbd_smb2_request *smb2req,
+ uint64_t in_session_id,
+ uint8_t in_flags,
+ uint8_t in_security_mode,
+ uint64_t in_previous_session_id,
+ DATA_BLOB in_security_buffer)
+{
+ struct tevent_req *req;
+ struct smbd_smb2_session_setup_state *state;
+ NTSTATUS status;