static NTSTATUS smbXsrv_session_table_init(struct smbXsrv_connection *conn, uint32_t lowest_id, uint32_t highest_id, uint32_t max_sessions) { struct smbXsrv_client *client = conn->client; struct smbXsrv_session_table *table; NTSTATUS status; struct tevent_req *subreq; uint64_t max_range; if (lowest_id > highest_id) { return NT_STATUS_INTERNAL_ERROR; } max_range = highest_id; max_range -= lowest_id; max_range += 1; if (max_sessions > max_range) { return NT_STATUS_INTERNAL_ERROR; } table = talloc_zero(client, struct smbXsrv_session_table); if (table == NULL) { return NT_STATUS_NO_MEMORY; } table->local.db_ctx = db_open_rbt(table); if (table->local.db_ctx == NULL) { TALLOC_FREE(table); return NT_STATUS_NO_MEMORY; } table->local.lowest_id = lowest_id; table->local.highest_id = highest_id; table->local.max_sessions = max_sessions; status = smbXsrv_session_global_init(); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(table); return status; } table->global.db_ctx = smbXsrv_session_global_db_ctx; dbwrap_watch_db(table->global.db_ctx, client->msg_ctx); subreq = messaging_read_send(table, client->ev_ctx, client->msg_ctx, MSG_SMBXSRV_SESSION_CLOSE); if (subreq == NULL) { TALLOC_FREE(table); return NT_STATUS_NO_MEMORY; } tevent_req_set_callback(subreq, smbXsrv_session_close_loop, client); client->session_table = table; return NT_STATUS_OK; }
static void smbXsrv_session_close_loop(struct tevent_req *subreq) { struct smbXsrv_client *client = tevent_req_callback_data(subreq, struct smbXsrv_client); struct smbXsrv_session_table *table = client->session_table; int ret; struct messaging_rec *rec = NULL; struct smbXsrv_session_closeB close_blob; enum ndr_err_code ndr_err; struct smbXsrv_session_close0 *close_info0 = NULL; struct smbXsrv_session *session = NULL; NTSTATUS status; struct timeval tv = timeval_current(); NTTIME now = timeval_to_nttime(&tv); ret = messaging_read_recv(subreq, talloc_tos(), &rec); TALLOC_FREE(subreq); if (ret != 0) { goto next; } ndr_err = ndr_pull_struct_blob(&rec->buf, rec, &close_blob, (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_session_closeB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(1,("smbXsrv_session_close_loop: " "ndr_pull_struct_blob - %s\n", nt_errstr(status))); goto next; } DEBUG(10,("smbXsrv_session_close_loop: MSG_SMBXSRV_SESSION_CLOSE\n")); if (DEBUGLVL(10)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } if (close_blob.version != SMBXSRV_VERSION_0) { DEBUG(0,("smbXsrv_session_close_loop: " "ignore invalid version %u\n", close_blob.version)); NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); goto next; } close_info0 = close_blob.info.info0; if (close_info0 == NULL) { DEBUG(0,("smbXsrv_session_close_loop: " "ignore NULL info %u\n", close_blob.version)); NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); goto next; } status = smb2srv_session_lookup_client(client, close_info0->old_session_wire_id, now, &session); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) { DEBUG(4,("smbXsrv_session_close_loop: " "old_session_wire_id %llu not found\n", (unsigned long long)close_info0->old_session_wire_id)); if (DEBUGLVL(4)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } goto next; } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) { DEBUG(1,("smbXsrv_session_close_loop: " "old_session_wire_id %llu - %s\n", (unsigned long long)close_info0->old_session_wire_id, nt_errstr(status))); if (DEBUGLVL(1)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } goto next; } if (session->global->session_global_id != close_info0->old_session_global_id) { DEBUG(1,("smbXsrv_session_close_loop: " "old_session_wire_id %llu - global %u != %u\n", (unsigned long long)close_info0->old_session_wire_id, session->global->session_global_id, close_info0->old_session_global_id)); if (DEBUGLVL(1)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } goto next; } if (session->global->creation_time != close_info0->old_creation_time) { DEBUG(1,("smbXsrv_session_close_loop: " "old_session_wire_id %llu - " "creation %s (%llu) != %s (%llu)\n", (unsigned long long)close_info0->old_session_wire_id, nt_time_string(rec, session->global->creation_time), (unsigned long long)session->global->creation_time, nt_time_string(rec, close_info0->old_creation_time), (unsigned long long)close_info0->old_creation_time)); if (DEBUGLVL(1)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } goto next; } subreq = smb2srv_session_shutdown_send(session, client->ev_ctx, session, NULL); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; DEBUG(0, ("smbXsrv_session_close_loop: " "smb2srv_session_shutdown_send(%llu) failed: %s\n", (unsigned long long)session->global->session_wire_id, nt_errstr(status))); if (DEBUGLVL(1)) { NDR_PRINT_DEBUG(smbXsrv_session_closeB, &close_blob); } goto next; } tevent_req_set_callback(subreq, smbXsrv_session_close_shutdown_done, session); next: TALLOC_FREE(rec); subreq = messaging_read_send(table, client->ev_ctx, client->msg_ctx, MSG_SMBXSRV_SESSION_CLOSE); if (subreq == NULL) { const char *r; r = "messaging_read_send(MSG_SMBXSRV_SESSION_CLOSE) failed"; exit_server_cleanly(r); return; } tevent_req_set_callback(subreq, smbXsrv_session_close_loop, client); }