static void smbXsrv_session_close_shutdown_done(struct tevent_req *subreq) { struct smbXsrv_session *session = tevent_req_callback_data(subreq, struct smbXsrv_session); NTSTATUS status; status = smb2srv_session_shutdown_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smbXsrv_session_close_loop: " "smb2srv_session_shutdown_recv(%llu) failed: %s\n", (unsigned long long)session->global->session_wire_id, nt_errstr(status))); } status = smbXsrv_session_logoff(session); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smbXsrv_session_close_loop: " "smbXsrv_session_logoff(%llu) failed: %s\n", (unsigned long long)session->global->session_wire_id, nt_errstr(status))); } TALLOC_FREE(session); }
static void smbXsrv_session_close_loop(struct tevent_req *subreq) { struct smbXsrv_connection *conn = tevent_req_callback_data(subreq, struct smbXsrv_connection); struct smbXsrv_session_table *table = conn->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 = msg_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(conn, 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; } /* * TODO: cancel all outstanding requests on the session */ status = smbXsrv_session_logoff(session); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smbXsrv_session_close_loop: " "smbXsrv_session_logoff(%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); } } TALLOC_FREE(session); next: TALLOC_FREE(rec); subreq = msg_read_send(table, conn->ev_ctx, table->close_channel); if (subreq == NULL) { smbd_server_connection_terminate(conn->sconn, "msg_read_send() failed"); return; } tevent_req_set_callback(subreq, smbXsrv_session_close_loop, conn); }