Znuny/Znuny LTS is a fork of the ((OTRS)) Community Edition, one of the most flexible web-based ticketing systems used for Customer Service, Help Desk, IT Service Management.
On Znuny user logout races may occur i.e. logout HTTP request that removes session rows from sessions table is processed in parallel with other HTTP request from the same session that updates records in the sessions table. Example orphaned session records that we observed (very rare incidents):
# mysql -e "select * from sessions where session_id='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'" otrs
+--------+----------------------------------+--------------------+------------+------------+
| id | session_id | data_key | data_value | serialized |
+--------+----------------------------------+--------------------+------------+------------+
| 123 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | LastScreenOverview | | 0 |
+--------+----------------------------------+--------------------+------------+------------+
# mysql -e "select * from sessions where session_id='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'" otrs
+--------+----------------------------------+-------------------------------------------------+------------+------------+
| id | session_id | data_key | data_value | serialized |
+--------+----------------------------------+-------------------------------------------------+------------+------------+
| 100107 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | UserDashboardTicketGenericFilter0120-TicketNew | All | 0 |
| 100108 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | UserDashboardTicketGenericFilter0130-TicketOpen | All | 0 |
+--------+----------------------------------+-------------------------------------------------+------------+------------+
# mysql -e "select * from sessions where session_id='cccccccccccccccccccccccccccccccc'" otrs
+--------+----------------------------------+-------------------------------------------------+------------+------------+
| id | session_id | data_key | data_value | serialized |
+--------+----------------------------------+-------------------------------------------------+------------+------------+
| 200956 | cccccccccccccccccccccccccccccccc | UserDashboardTicketGenericFilter0130-TicketOpen | All | 0 |
+--------+----------------------------------+-------------------------------------------------+------------+------------+
Such orphaned sessions are visible in session admin in UI (with empty user column) and can be removed there manually.
When such orphaned session records exist in DB, invalidation of any agent account throws error
ERROR: OTRS-otrs.Daemon.pl - Daemon Kernel::System::Daemon::DaemonModules::SchedulerTaskWorker-1 Perl: 5.32.1 OS: linux Time: Fri Dec 23 09:30:32 2022
Message: There was an error executing RemoveSessionByUser() in Kernel::System::AuthSession: Use of uninitialized value in string ne at /opt/otrs/Kernel/System/AuthSession.pm line 359.
Use of uninitialized value in string ne at /opt/otrs/Kernel/System/AuthSession.pm line 359.
Use of uninitialized value in string ne at /opt/otrs/Kernel/System/AuthSession.pm line 359.
Traceback (4149066):
Module: Kernel::System::Daemon::DaemonModules::BaseTaskWorker::_HandleError Line: 54
Module: Kernel::System::Daemon::DaemonModules::SchedulerTaskWorker::AsynchronousExecutor::Run Line: 150
Module: Kernel::System::Daemon::DaemonModules::SchedulerTaskWorker::Run Line: 241
Module: (eval) Line: 348
Module: main::Start Line: 348
Module: /opt/otrs/bin/otrs.Daemon.pl Line: 164
to SchedulerTaskWorkerERR.log.
Znuny should remove such orphaned records from sessions table automatically (probably in GetExpiredSessionIDs which ignores such orphans now because of lack of UserSessionStart and UserLastRequest records) after making sure, that session is already expired (adding column create_time would help; without it one may consider finding any UserSessionStart or UserLastRequest record from any session with greater id and only if found - use it as orphaned session last request time for expiry calculation).
RemoveSessionByUser() line
next SESSIONID if $SessionData{UserLogin} ne $Param{UserLogin};
should be protected against throwing errors like above in case $SessionData{UserLogin} is undefined (occurs when processing orphaned session).
Actual behaviour
Orphaned session records are left in DB forever. Errors are generated in RemoveSessionByUser() (i.e. when any agent account is invalidated by admin).
How to reproduce
Try to find system with orphaned session (or insert orphaned session record /similar to examples above/ into sessions table manually) and invalidate test agent account there. See SchedulerTaskWorkerERR.log for log message.
Environment
Expected behaviour
On Znuny user logout races may occur i.e. logout HTTP request that removes session rows from
sessions
table is processed in parallel with other HTTP request from the same session that updates records in thesessions
table. Example orphaned session records that we observed (very rare incidents):Such orphaned sessions are visible in session admin in UI (with empty user column) and can be removed there manually.
When such orphaned session records exist in DB, invalidation of any agent account throws error
to
SchedulerTaskWorkerERR.log
.Znuny should remove such orphaned records from
sessions
table automatically (probably inGetExpiredSessionIDs
which ignores such orphans now because of lack ofUserSessionStart
andUserLastRequest
records) after making sure, that session is already expired (adding columncreate_time
would help; without it one may consider finding anyUserSessionStart
orUserLastRequest
record from any session with greaterid
and only if found - use it as orphaned session last request time for expiry calculation).RemoveSessionByUser()
lineshould be protected against throwing errors like above in case
$SessionData{UserLogin}
is undefined (occurs when processing orphaned session).Actual behaviour
Orphaned session records are left in DB forever. Errors are generated in
RemoveSessionByUser()
(i.e. when any agent account is invalidated by admin).How to reproduce
Try to find system with orphaned session (or insert orphaned session record /similar to examples above/ into
sessions
table manually) and invalidate test agent account there. SeeSchedulerTaskWorkerERR.log
for log message.