Cli context error

24 views
Skip to first unread message

Alexandre Heidemann

unread,
Jul 20, 2026, 1:03:49 PM (7 days ago) Jul 20
to Event-Driven Servers

Hello,

I'm trying to implement CLI context awareness (context = / if (context == ...)) but the context set in one session comes back empty in the next session on the same single-connection. While debugging this, the daemon also crashes (13:50:36 in the log) with a SIGSEGV right after the authorization request, while processing the subsequent accounting packet.

Reproducible on the latest master (commit 4570c1c568d16905c3090aaad8f625f7b1a28203) with a ZTE device (single-connect flag negotiated, PAP login).

Steps to reproduce: log in, then run configure terminalinterface vlan82ip address 10.27.27.1/30. The crash happens on the accounting packet for the last command.

Attached: debug logs (PACKET + regex trace), backtrace, profile and device config.

The profile config:


profile access_zte_movel_homolog {
  script {
    if (service == exec) {
      if (cmd == "") {
        set priv-lvl = 14
        permit
      }
      permit
    }
    if (service == shell) {
      set priv-lvl = 14
      if (cmd == "") {
        permit
      }

      # entrou numa interface vlan -> contexto "vlan"
      if (cmd =~ /^interface\s+vlan/) {
        context = "vlan"
        permit
      }
      # qualquer outra interface (xgei, etc.) -> contexto "other"
      if (cmd =~ /^interface\s+/) {
        context = "other"
        permit
      }
      # saiu da interface -> limpa contexto
      if (cmd =~ /^(exit|quit|end)/) {
        context = ""
        permit
      }

      # ip address só passa dentro de interface vlan
      if (cmd =~ /ip address/) {

        if (context == "vlan") {
          permit
}
deny

      }

      # demais comandos
      if (cmd =~ /(show)|(exit)|(configure terminal)|(switchvlan)|(smartgroup)|(switchport)|(lacp)|(interface xgei)|(no smartgroup)|(commit)|(ip dhcp relay)|(server)|(dhcp)|(enable)|(relay)|(disable)|(shutdown)|(interface vlan)|(description)|(ping)/) {
        permit
      }

      if (cmd =~ / /) {
        deny
      }
    }
    permit
  }
}
crash.txt

Marc Huber

unread,
Jul 20, 2026, 2:17:16 PM (6 days ago) Jul 20
to event-driv...@googlegroups.com

Hi Alexandre,

thanks for reporting! I'd like to address the SEGV issue first, I think

diff --git a/tac_plus-ng/context.c b/tac_plus-ng/context.c
index 1ed910f..6d32940 100644
--- a/tac_plus-ng/context.c
+++ b/tac_plus-ng/context.c
@@ -107,6 +107,8 @@ void tac_script_set_exec_context(tac_session *session, char *ctxname)
        sc = RB_payload(rb, struct shellctx *);
        free(sc->ctxname);
     } else {
+       if (!ctxname || !*ctxname)
+           return;
        sc = calloc(1, sizeof(struct shellctx) + session->username.len + session->port.len);
        sc->username = sc->data;
        sc->portname = sc->data + session->username.len + 1;

will fix that one, I'll commit this change shortly.

Regarding the main issue: Could you please retry with full debugging enabled? I don't see any script related logs, but these might actually help locating the problem.

Thanks,

Marc

--
You received this message because you are subscribed to the Google Groups "Event-Driven Servers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to event-driven-ser...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/event-driven-servers/e4d6e063-ebb4-42d6-9bc9-ac0f6cbb3d75n%40googlegroups.com.

Alexandre Heidemann

unread,
Jul 20, 2026, 2:38:00 PM (6 days ago) Jul 20
to Event-Driven Servers
In the crash.txt there are the full session with the bug.
crash.txt

Marc Huber

unread,
Jul 20, 2026, 2:51:00 PM (6 days ago) Jul 20
to event-driv...@googlegroups.com

Hi Alexandre,

you sure about the debug level? The debug output shows no ACL debugs at all.

Cheers,

Marc

Alexandre Heidemann

unread,
Jul 20, 2026, 2:52:30 PM (6 days ago) Jul 20
to Event-Driven Servers

id = tac_plus-ng {

  debug = PACKET AUTHEN AUTHOR MAVIS PROC


This is the current debug level.  What more do you need?

Marc Huber

unread,
Jul 20, 2026, 2:55:55 PM (6 days ago) Jul 20
to event-driv...@googlegroups.com

Hi Alexandre,

debug = PACKET AUTHEN AUTHOR MAVIS PROC ACL

should work.

Thanks,

Marc

Alexandre Heidemann

unread,
Jul 20, 2026, 3:39:09 PM (6 days ago) Jul 20
to Event-Driven Servers
Hi

Pls check if there are everthing what u need.

Thanks

crash_tac_2.txt

Marc Huber

unread,
Jul 21, 2026, 12:18:16 PM (6 days ago) Jul 21
to event-driv...@googlegroups.com

Hi Alexandre,

thanks -- the debug output indicates that the "context" value was set, but the daemon didn't recognize it later.

Alas, I couldn't reproduce that behavior on my system. Is the "context timeout" value still at the 3600s default?

Cheers,

Marc

Alexandre Heidemann

unread,
Jul 21, 2026, 1:29:35 PM (6 days ago) Jul 21
to event-driv...@googlegroups.com
This is all of my config

--
You received this message because you are subscribed to the Google Groups "Event-Driven Servers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to event-driven-ser...@googlegroups.com.
tac_config.txt

Marc Huber

unread,
Jul 21, 2026, 2:41:00 PM (5 days ago) Jul 21
to event-driv...@googlegroups.com

Hi Alexandre,

I've tested the context feature with the config below, no issues seen.

Please provide a minimalistic but complete config file for further testing. Also, I've seen gcc bugs before, so please let me know your compiler version.

Cheers,

Marc


id = spawnd {
    background = yes
    single process = yes
    listen { port = 4949 }
}

id = tac_plus-ng {
    device world {
        address = ::/0
        key = demo
        single-connection = yes
        enable 15 = login
    }
    user demo {
        password login = clear demo
        password pap = login
        profile {
            script {
                if (service == shell) {
                    if (cmd == "") {
                        set priv-lvl = 15
                        permit
                    }
                    if (cmd =~ /^interface Loopback 100 /) {
                        context = "lo100"
                        message = "context set to ${context} (${cmd})"
                        permit
                    }
                    if (cmd =~ /^interface /) {
                        context = ""
                        message = "context reset (${cmd})"
                        permit
                    }
                    if (context == "lo100" && cmd =~ /^(no )?ip address /) {
                        message = "context ${context} matched, permitting ${cmd}"
                        permit
                    }
                    if (cmd =~ /^(no )?ip address /) {
                        deny
                    }
                    permit
                }
            }
        }
    }
}

Alexandre Heidemann

unread,
Jul 21, 2026, 3:51:15 PM (5 days ago) Jul 21
to event-driv...@googlegroups.com
Hi Marc,

Thanks! Here's what you asked for.

Compiler / platform:
- gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-11.0.2)
- Oracle Linux Server 9.7 (ID_LIKE=fedora)
- GNU ld 2.35.2-67.0.1.el9_7.1

Minimal config (attached as repro.cfg):

    id = spawnd {
        background = no

        single process = yes
        listen { port = 4949 }
    }

    id = tac_plus-ng {
        device world {
            address = ::/0
            key = demo
            single-connection = yes
            enable 15 = login
        }
        user teste_1 {

            password login = clear demo
            password pap = login
            profile {
                script {
                    if (service == shell) {
                        # permit "interface ..." and stamp a context
                        # (this creates the shellctxcache tree + an entry)

                        if (cmd =~ /^interface /) {
                            context = "vlan82"
                            permit
                        }
                        # everything else is denied -> no context is set
                        deny
                    }
                }
            }
        }
    }

This is on version 4570c1c568d16905c3090aaad8f625f7b1a28203 (the version the
crashing process reports in the log I already sent you).

The crash needs an accounting STOP, not authorization alone. acct.c:128
calls tac_script_set_exec_context(session, NULL) on every ACCT STOP with
service=shell; when shellctxcache already exists but the lookup returns no
entry for the session's user/port/device, the else branch reaches
strdup(NULL). That rb == NULL && cache != NULL state is left
behind by the *previous* command's ACCT STOP: set_exec_context(NULL) finds
the entry, RB_delete()s it and returns, but the tree object survives empty.
The next shell ACCT STOP that finds no entry then hits strdup(NULL). There
is no "context = """ reset anywhere -- the ACCT STOP path alone both creates
and destroys the state.

Trigger sequence over one single-connection session (this is exactly the
log I already sent, sessions 3e561d9c..3e561d9f):
  1. AUTHOR, service=shell, cmd="interface vlan82" -> matches /^interface /
     -> context = "vlan82" -> set_exec_context("vlan82") creates the tree
     + entry for teste_1/vty0/device.
  2. ACCT STOP, service=shell, cmd="interface vlan82" -> set_exec_context(NULL):
     rb is found -> RB_delete() drops the entry and returns. Tree survives,
     now empty.
  3. AUTHOR, service=shell, cmd="ip address 10.27.27.1/30" -> denied (no
     /^interface / match) -> no context set, entry is NOT recreated.
  4. ACCT STOP, service=shell, cmd="ip address 10.27.27.1/30" ->
     set_exec_context(NULL): shellctxcache != NULL but the lookup returns
     rb == NULL -> else branch -> strdup(NULL) -> SIGSEGV.

Note: the trigger analysis above was worked out with help from AI (Claude).

Cheers,
Alexandre



repro.cfg

Marc Huber

unread,
Jul 21, 2026, 4:58:50 PM (5 days ago) Jul 21
to event-driv...@googlegroups.com

Hi,

the configuration you gave closely mirrors my sample, but sets a context and doesn't evaluate it. This looks AI generated and unvalidated. Please don't waste my time.

Cheers,

Marc

Alexandre Heidemann

unread,
Jul 21, 2026, 5:04:35 PM (5 days ago) Jul 21
to Event-Driven Servers
Sorry Marc. 

My config it's long i just try to reduce it. AI doesn't always help.. Just try to accelerate the process. 
As soon as possible I'll try to validate a minimal config. 

Is there something else to help u to replicate and correct the issue? The cli context is really good feature. 

Alexandre Heidemann

unread,
Jul 21, 2026, 9:19:11 PM (5 days ago) Jul 21
to Event-Driven Servers
Hi Marc

Check the attached files. 
"tac-debug-wiht-tac-config_clean-210726-01.txt" is a journalctl of the service after a restart with "tac-config_clean-210726-01.txt"

I'm trying with a ZTE device, I don't know if it's matter.

LER-ZTE-6120H-S(config)#interface  vlan82
LER-ZTE-6120H-S(config-if-vlan82)#ip address 10.27.27.1/30
% Command authorization did not pass
LER-ZTE-6120H-S(config-if-vlan82)#

I noticed that in the last debug was missing some rpm
" 21 22:08:06 TIO-CGR-TACACS-MANAGER-01 tac_plus-ng[929019]: GDB: Missing rpms, try: dnf --enablerepo='*debug*' install openssl-lib..."

It's already fixed in the debug file.

I hope this can help. Let me know if I need to do something else.

Thanks
tac-debug-wiht-tac-config_clean-210726-01.txt
tac-config_clean-210726-01.txt

Marc Huber

unread,
Jul 22, 2026, 11:43:12 AM (5 days ago) Jul 22
to event-driv...@googlegroups.com

Hi Alexandre,

I couldn't repoduce the problem, but I've done some code refactoring (e626beba064fa375e1619e13f0fc917bfcc80f76) nevertheless. Please git pull, rebuild and retry.

Thanks,

Marc

Alexandre Heidemann

unread,
Jul 22, 2026, 2:20:37 PM (4 days ago) Jul 22
to Event-Driven Servers
The crash no longer occurred, but the command was still not authorized.


LER-ZTE-6120H-S#configure  terminal
Enter configuration commands, one per line.  End with CTRL/Z.
LER-ZTE-6120H-S(config)#int

LER-ZTE-6120H-S(config)#interface  vlan82
LER-ZTE-6120H-S(config-if-vlan82)#ip address 10.27.27.1/30
% Command authorization did not pass
LER-ZTE-6120H-S(config-if-vlan82)#


tac-debug-e626beba064fa375e1619e13f0fc917bfcc80f76.txt

Marc Huber

unread,
Jul 23, 2026, 9:31:28 AM (4 days ago) Jul 23
to event-driv...@googlegroups.com

Hi Alexandre,

ok, thanks, I think I found the issue, this only happened with command accounting being active, and 59299e1fd41808531d6c1271dea8712d8d8ca160 should fix it. Please git pull and retry once more.

Cheers,

Marc

Alexandre Heidemann

unread,
Jul 23, 2026, 2:19:07 PM (3 days ago) Jul 23
to Event-Driven Servers
It's working now


LER-ZTE-6120H-S(config)#interface vlan82
LER-ZTE-6120H-S(config-if-vlan82)#ip address 10.27.27.1/30
*LER-ZTE-6120H-S(config-if-vlan82)#$
*LER-ZTE-6120H-S(config-if-xgei-1/1/0/1)#ip ad
*LER-ZTE-6120H-S(config-if-xgei-1/1/0/1)#ip address 10.28.28.2/30

% Command authorization did not pass
*LER-ZTE-6120H-S(config-if-xgei-1/1/0/1)#
tac-debug-230726.txt
Reply all
Reply to author
Forward
0 new messages