Giter Club home page Giter Club logo

event-driven-servers's Introduction

This is a collection of high-performance and scalable event-driven servers (notably tac_plus-ng, tac_plus, ftpd, tcprelay). Please have a look at the documentation for configuration details.

Issues can be reported via

https://github.com/MarcJHuber/event-driven-servers/issues

Discussions can be started via

https://github.com/MarcJHuber/event-driven-servers/discussions

Home site is https://www.pro-bono-publico.de/projects/

Installation instructions

This software suite should compile quite fine on a variety of platforms, e.g. current versions of Sun Solaris, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, Darwin, Linux and Cygwin. See the comments at the beginning of

misc/sysconf.h

for a somewhat comprehensive list.

Unless you're trying to install the software on an unsupported system, there shouldn't be any need to mess with the makefiles. If you do so, you're on your own, and you'll better know what you're doing.

Build environment

Required tools:

  • A supported C compiler, plus linker. LLVM is fine, GCC will work too (but has issues with optimization, so that's disabled for now).
  • GNU make (version 3.79.1, unpatched, recommended, others may or may not work).
  • Perl
  • Various development header files and libraries

Compile & Install

Please run "./configure --help". It will output a list of supported options. Then run ./configure with the appropriate arguments. After that, run "make" to start the compilation process and "make install" to install the compiled binaries.

Example:

./configure tac_plus-ng
make
sudo make install

You may actually omit the "configure" step if you're content with the default build options, which are to compile everything and to use all optional features your system supports at first glance.

If you don't care for the optional features (TLS support, C-ARES, others), just run

./configure --minimum tac_plus-ng
make
sudo make install

Documentation

The distribution comes with documentation located in the top-level "doc" director, and you can view it online at https://www.pro-bono-publico.de/projects, too.

Support

While I really appreciate that you're using the software I'd very much prefer not to receive private support enquiries.

As already mentioned on the top of this page: Please direct support queries to GitHub discussions or issues:

https://github.com/MarcJHuber/event-driven-servers/discussions https://github.com/MarcJHuber/event-driven-servers/issues

event-driven-servers's People

Contributors

dhoffend avatar kartiksubbarao avatar marcjhuber avatar strikerx22 avatar vostorga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

event-driven-servers's Issues

groups filter stops working after Oct 2 change

I have a groups filter similar to the one described in the documentation:

mavis module = groups {
  resolve gids = yes
  groups filter = /^(guest|staff)$/
  script out = {
    # copy the already filtered UNIX group access list to TACMEMBER
    eval $GIDS =~ /^(.*)$/
    set $TACMEMBER = $1
  }
}

This filter is not being applied properly since the following change on Oct 2: 14b3391. I get errors like the following which I did not get before:
1367463: 19:17:11.457 0/00000000: - jsmith:1: Group 'labs-dev' not found

The problem seems to be with the following two lines of code that were deleted in that change:

image

The good_name() function (which calls rxmatch() with the actual filter) is no longer being called on the AV_A_GIDS field. That means that GIDS still has the full list of resolved groups, which gets copied to TACMEMBER.

This patch seems to later introduce filtering on AV_A_TACMEMBER, but I don't see how to benefit from that since GIDS is the attribute that contains the list of resolved groups. Please clarify if there is another way we should be setting up group filtering after the Oct 2 change, or whether the code needs to be updated to keep filtering working as documented.

Cisco Nexus AAA problem

Hi, Marc.
Previously, I used the old tacacs+. I just installed tacacs-ng by your recommendation and it works fine.
But I have a question:
When I logging in to Cisco Nexus, it is not possible to enter even a single command.
image

the problem config profile tacacs-ng:

profile = NetAdm {
        script {
                if (service == shell) {
                        if (cmd == "") {
                            set priv-lvl = 15
                            permit
                        }
                }
                if (service == junos-exec) {
                        if (cmd == "") {
                                set local-user-name = admin
                                permit
                        }
                }
                if (service == fortigate) {
                        if (cmd == "") {
                                set memberof = remote_adm
                                set admin_prof = roaccess
                                permit
                        }
                }
        }
}

The old configuration of tacacs hasn't have such problems:

group = NetworkAdmins {
        service = shell {
            default command = permit
            set priv-lvl = 15
        }
        service = junos-exec {
            set local-user-name = admin
        }
        service = fortigate {
            set memberof = remote_adm
            set admin_prof = roaccess
        }
}

I've just tested the old configuration and in case when I remove "default command = permit", Cisco Nexus is not allow me to execute any command.

Is there any way to add default command = permit to tacacs+ ng config?
If you wish I can provide the full configuration.
Thank you.

D A

`pammavis` usage is wrong in the documentation and samples

I've been trying to understand why I couldn't authenticate users against pam and ended up adding a bunch of printf to pammavis.c.
In the doc and samples, for some reason the first argument of pammavis is pammavis again, while it seems it only expects the option -s <service>.

That is the configuration bit from the documentation: https://www.pro-bono-publico.de/projects/tac_plus-ng.html#AEN2282

  mavis module = external {
    exec = /usr/local/sbin/pammavis pammavis -s sshd
  }

It turns out that if the first argument is pammavis, the tool will discard the rest of the arguments and silently set the service variable to its default value mavis. Obviously with targeting the wrong pam service, authentication does not work.

  • Double pammavis, bogus credentials
/ # printf "4 gregory\
n8 password\n=\n" | /usr/local/sbin/pammavis pammavis -s sss_fromhost
4 gregory
8 password
authenticating gregory
pam_start res: 0, service: mavis
pam_authenticate res: 10
=16

Service is set to mavis, pam_authenticate returns PAM_USER_UNKNOWN

  • Single pammavis, bogus credentials
/ # printf "4 gregory\
n8 password\n=\n" | /usr/local/sbin/pammavis -s sss_fromhost
service: sss_fromhost
4 gregory
8 password
authenticating gregory
pam_start res: 0, service: sss_fromhost
pam_authenticate res: 7
17 Authentication failure
6 NAK
=0

Service is set to sss_fromhost, pam_authenticate returns PAM_USER_UNKNOWN

  • Single pammavis, valid credentials
/ # printf "4 gregory\
n8 <REDACTED>\n=\n" | /usr/local/sbin/pammavis -s sss_fromhost
service: sss_fromhost
4 gregory
8 <REDACTED>
authenticating gregory
pam_start res: 0, service: sss_fromhost
pam_authenticate res: 0
success
=16

Service is set to sss_fromhost, pam_authenticate returns PAM_SUCCESS

" tac_plus-ng" and " tac_plus" installation in Openwrt

Hi Everyone,

Is it possible to install "tac_plus-ng" and "tac_plus" on OpenWRT

Perl version installed in OpenWrt is:
This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-linux-musl

getting this error while executing ./configure
"root@OpenWrt:~/Share_OPENWRT/event-driven-servers-master# ./configure
Can't locate strict.pm in @inc (you may need to install the strict module) (@inc contains: /usr/lib/perl5/5.28) at ./configure line 13.
BEGIN failed--compilation aborted at ./configure line 13.
"

and if I comment "use strict;" in configure script then the make file is not getting generated.

Unable to compile on Debian

Hello,

On a clean Debian install, after installed the following packages :

apt install build-essential gcc make perl checkinstall 
apt install libc-ares-dev libssl-dev libcurl4-openssl-dev libradcli-dev libpam0g-dev libpcre2-dev libsctp-dev zlib1g-dev

./configure output give me :

Development files were found for: LIB-ARES, LIB-CRYPT, LIB-CRYPTO, LIB-CURL, LIB-PAM, LIB-PCRE2, LIB-RADCLI, LIB-SCTP, LIB-SSL, LIB-ZLIB
The file
    build/Makefile.inc.linux-5.10.0-9-amd64-x86_64
was just created. You may run "make" now.

But make cannot compile the program :

make

make[1]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavis'
make[3]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[4]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[4]: Nothing to be done for 'install'.
make[4]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[3]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[3]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavis'
make[4]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[4]: Nothing to be done for 'install'.
make[4]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[3]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavis'
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavis'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis/perl'
make[1]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavis'
make[1]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/spawnd'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/spawnd'
make[3]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/spawnd'
make[3]: Nothing to be done for 'install'.
make[3]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/spawnd'
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/spawnd'
make[1]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/spawnd'
make[1]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/mavisd'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavisd'
make[3]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavisd'
make[3]: Nothing to be done for 'install'.
make[3]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavisd'
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavisd'
make[1]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/mavisd'
make[1]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/ftpd'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/ftpd/extra'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/ftpd/extra'
make[2]: Entering directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/ftpd'
gcc -o ftpd pcre_rewrite.o h_auth.o ssl_init.o ssl_verify.o h_pbsz.o h_prot.o h_ccc.o h_abor.o h_cwd.o h_help.o h_list.o h_mdtm.o h_noop.o h_pass.o h_pasv.o h_port.o h_pwd.o h_quit.o h_rein.o h_rest.o h_retr.o h_size.o h_stat.o h_syst.o h_rnfr.o h_rnto.o h_type.o h_user.o h_stor.o h_dele.o h_mkd.o h_rmd.o h_site_chmod.o h_site_group.o h_site_checksum.o h_rang.o h_site_id.o h_site_umask.o h_site_idle.o h_site_groups.o h_feat.o log.o h_host.o h_lang.o h_mode.o main.o reply.o list.o readcmd.o parse.o path.o buffer2socket.o cleanup.o pickystat.o readme.o signals.o chunk.o file2buffer.o control2socket.o accept_data.o buffer.o auth.o quota.o accept_control.o glob.o socket2buffer.o foobar.o structs.o messages.o conversions.o tohex.o ident_buffer2socket.o ident_connect_out.o ident_connected.o conf.o ident_socket2buffer.o sig_bus.o h_esta.o h_mfmt.o h_mff.o mysendfile.o bug.o -Wl,-rpath,$ORIGIN/../lib -L/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/mavis -Wl,-rpath,/usr/local/lib -lmavis   -L/usr/x86_64-linux-gnu/lib -Wl,-rpath,/usr/x86_64-linux-gnu/lib -lz -L/usr/x86_64-linux-gnu/lib -Wl,-rpath,/usr/x86_64-linux-gnu/lib -lpcre2-8 -L/usr/x86_64-linux-gnu/lib -Wl,-rpath,/usr/x86_64-linux-gnu/lib -lssl -L/usr/x86_64-linux-gnu/lib -Wl,-rpath,/usr/x86_64-linux-gnu/lib -lcrypto -L/usr/x86_64-linux-gnu/lib -Wl,-rpath,/usr/x86_64-linux-gnu/lib -lcrypt
/usr/bin/ld: ssl_verify.o: warning: relocation against `ssl_auth_req' in read-only section `.text'
/usr/bin/ld: h_auth.o: in function `sslify_c':
h_auth.c:(.text+0x486): undefined reference to `ssl_auth'
/usr/bin/ld: h_auth.c:(.text+0x491): undefined reference to `ssl_ctx'
/usr/bin/ld: h_auth.c:(.text+0x4a7): undefined reference to `ssl_ctx'
/usr/bin/ld: h_auth.o: in function `sslify_d':
h_auth.c:(.text+0x54c): undefined reference to `ssl_auth'
/usr/bin/ld: h_auth.c:(.text+0x557): undefined reference to `ssl_ctx'
/usr/bin/ld: h_auth.c:(.text+0x56d): undefined reference to `ssl_ctx'
/usr/bin/ld: h_auth.o: in function `h_auth':
h_auth.c:(.text+0x5ca): undefined reference to `ssl_ctx'
/usr/bin/ld: h_auth.c:(.text+0x691): undefined reference to `ssl_old_draft'
/usr/bin/ld: h_auth.c:(.text+0x740): undefined reference to `ssl_old_draft'
/usr/bin/ld: h_auth.c:(.text+0x806): undefined reference to `ssl_old_draft'
/usr/bin/ld: ssl_verify.o: in function `app_verify_cb':
ssl_verify.c:(.text+0x118): undefined reference to `ssl_auth_req'
/usr/bin/ld: ssl_verify.o: in function `ssl_set_verify':
ssl_verify.c:(.text+0x1ea): undefined reference to `ssl_auth_req'
/usr/bin/ld: h_ccc.o: in function `do_shutdown':
h_ccc.c:(.text+0x2f): undefined reference to `io_SSL_shutdown'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[2]: *** [/apps/tac_plus-ng/installation/event-driven-servers/ftpd/Makefile.obj:65: ftpd] Error 1
make[2]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/build/linux-5.10.0-9-amd64-x86_64/ftpd'
make[1]: *** [GNUmakefile:24: build] Error 2
make[1]: Leaving directory '/apps/tac_plus-ng/installation/event-driven-servers/ftpd'
make: *** [GNUmakefile:31: dirs] Error 1

Version:

make -v
GNU Make 4.3
gcc -v
gcc version 10.2.1 20210110 (Debian 10.2.1-6)

Some help would be much apreciated

tac_plus: Timeout for non-responding ldap-servers

We are using tac_plus with two defined ldap-servers:

        mavis module = external {
                setenv LDAP_SERVER_TYPE = "openldap"
                setenv LDAP_HOSTS = "ldap1 ldap2"
...
                exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
        }

How can we configure the timeout for tac_plus to try the second server when the first one is unreachable? The default seems too long for the routers to wait.

Thanks a lot.

tac_plus-ng script behaviour

I'm trying to get familiar with the new syntax. This is my minimal config for testing:

#!../../../sbin/tac_plus-ng

debug redirect = /dev/stdout

id = spawnd {
  listen = { port = 4949 }
  spawn = {
    instances min = 1
    instances max = 10
  }
  background = no
}

id = tac_plus-ng {
  log access {
    destination = /var/log/tac_plus-ng/access/%Y%m%d.log
  }

  log acct {
    destination = /var/log/tac_plus-ng/auth/%Y%m%d.log
  }

  log auth {
    destination = /var/log/tac_plus-ng/auth/%Y%m%d.log
  # todo
  # log = groups
  }

  log stdout {
    destination = /proc/1/fd/1
  }

  access log = access
  access log = stdout
  accounting log = acct
  accounting log = stdout
  authorization log = auth
  authorization log = stdout

  group healthcheck {
  }

  profile healthcheck {
    script {
      if (service == shell) {
        set priv-lvl = 15
        if (cmd =~ /^healthcheck.*/) {
          permit
        }
      }
    }
  }

  ruleset {
    rule healthcheck {
      enabled = yes
      script {
        if (member == healthcheck) {
        profile = healthcheck
        permit
        }
      }
    }
  }

  user healthcheck {
    password login = clear changeme
    member = healthcheck
  }

  host DEFAULT {
    address = 0.0.0.0/0
    key = changeme
  # todo:
  # failed authentication banner = "Password incorrect -OR- insufficient privileges"
  }
}

I'm expecting that the "healthcheck" command is allowed and all other commands are denied. However, it seems that tac_plus-ng (latest commit a1b922b69908e66e3e48027c40a0b4597b064315/PCRE) behaves the opposite way:

tac_plus-ng@tac_plus:/$ /usr/local/bin/tacacs_client   -H 127.0.0.1   -p 4949   -k ${HEALTHCHECK_SHARED_SECRET}   -u ${HEALTHCHECK_USER_NAME}   -v authorize   -c service=shell      cmd=healthcheck
status: FAIL
tac_plus-ng@tac_plus:/$ /usr/local/bin/tacacs_client   -H 127.0.0.1   -p 4949   -k ${HEALTHCHECK_SHARED_SECRET}   -u ${HEALTHCHECK_USER_NAME}   -v authorize   -c service=shell      cmd=somethingelse
status: PASS

When I go back to the version I compiled with the codebase from a few days ago, it works as expected. Is my syntax wrong or have there been recent changes that result in a new behavior?

Thanks for your amazing work!

tacplus-ng: Missing TACACS reply with status="Authentication Failed" if LDAP response resultCode="InvalidCredentials"

Hi Marc,

if external authentication module mavis_tacplus-ng_ldap.pl gets response from LDAP server bindResponse with resultCode="InvalidCredentials" (only wrong password is used), then tacplus-ng does not pass "Authentication Failed" into TACACS reply message.
Instead tacplus-ng is waiting until the NAS will send new TACACS authentication session. This is probably a bug. It causes very long delay for some nas devices (Fortigate, F5, ...) if an user does a mistake at writing password before he can write it again.
I think tacplus-ng should immediately reply TACACS packet with "Authentication Failed" if gets a response bindResponse with resultCode="InvalidCredentials" from mavis_tacplus-ng_ldap.pl module.
What fo you think?

In my configuration I uses multiple external authentication:
primary mavis_tacplus-ng_ldap.pl
secondary pammavis

I have also tested config with single external authentication (mavis_tacplus-ng_ldap.pl) and the issue persists.

Thank you in advanced.
Regards,
Filip

mavis external python module

Dear Marc,

I'm having some trouble to make ldaps setup work. The same server configuration using plain ldap works correctly. The checks I've been doing point to a sort of negotiation problem with openssl as the ldaps server expects tls1.2 while mavis_tacplus_ldap.pl is somehow stuck starting on tls1.0.

As a consequence, when using ldaps the mavistest returns "No answer from LDAP backend". Using TLS option yields "TLS negotiation failed." but I believe it's not working in the server.

I tested using a python script and it's working, probably because it uses openldap - gnutls libraries instead of openssl. Therefore, I would like to know whether I can develop a python module to work with mavis. I read the Mavis document and it comments external modules "write the processed list (plus a result code) to stdout" but I don't know the exact format of that output or how to check it.

May you tell me what the expected output should be like, please?

Thanks and regards,

LDAP SSL/TLS version

Hi,
In our company they are deprecating TLS v1.1 in our AD servers.
After reading through the mavis perl script i guess there is some negotiation with the LDAP server to decide on the version to use and Net::LDAP use the default ones that IO::Socket::SSL uses.
So i should be fine when the day comes when they decide to just disable v1.1.

Would it be possible to update the mavis perl script so that i could specify what versions are allowed myself?
https://metacpan.org/dist/perl-ldap/view/lib/Net/LDAP.pod#start_tls-(-OPTIONS-)

Can't get tactrace.pl working

I’m trying to port an old installation/config to the new tacacs_plus-ng and have been running into problems I THINK with the ruleset stuff.
I tried to run the tactrace.pl to better understand the problem and have been side bared into a a different issue.
I cannot get tactrace.pl to run

This is as far as I’ve gotten and am now rather lost.

[root@authtorls2 perl]# ./tactrace.pl --help
Can't load '/usr/local/lib64/perl5/5.32/auto/Scm/Scm.so' for module Scm: libmavis.so: cannot open shared object file: No such file or directory at /usr/lib64/perl5/DynaLoader.pm line 193.
at ./tactrace.pl line 12.
Compilation failed in require at ./tactrace.pl line 12.
BEGIN failed--compilation aborted at ./tactrace.pl line 12.

For reference, libmavis.so DOES exist.

[root@authtorls2 perl]# ls -al /usr/local/lib64/
total 228
drwxr-xr-x. 5 root root 106 Oct 17 16:38 .
drwxr-xr-x. 12 root root 131 Oct 13 12:49 ..
drwxr-xr-x. 2 root root 6 Jan 10 2022 bpf
lrwxrwxrwx 1 root root 13 Oct 13 13:10 libmavis.so -> libmavis.so.0
lrwxrwxrwx 1 root root 15 Oct 13 13:10 libmavis.so.0 -> libmavis.so.0.1
-rwxr-xr-x 1 root root 226568 Oct 13 13:10 libmavis.so.0.1
drwxr-xr-x 2 root root 4096 Oct 13 13:10 mavis
drwxr-xr-x 3 root root 18 Oct 17 16:38 perl5
[root@authtorls2 perl]#

At this point I have no clue how to further debug tactrace.pl
I’m going to return to the docs and try to figure out what might be happening with the ruleset without any tactrace.pl hints.

Worst case I’ll have to abandon tacacs_plus-ng and return to tasacs_plus.

Thanks,
-craig

OSLEVEL Detection Issues in Makefile.inc

I'm attempting to correct the following line of code; thus far, I can only confirm that this affects the following Linux platforms: CentOS, Ubuntu, Alpine.

In Makefile.inc

OSLEVEL        := $(shell printf "0x%.2x%.2x%.4x" `echo $(OSr) | env -i $(TR) -c "[:digit:]" "[ *]"` 0 0 0 | cut -c-10)

I'm attempting to reverse engineer the desired outputs, I cannot determine what the complementary pattern is for the middle "tr -c" section is supposed to be.

This currently causes "invalid number" errors like these below because the 'printf' command is expecting a number, not a string. At this time, the OSLEVEL function essentially strips the alpha characters and replaces them with ']'. Based on the '[ *]' set in the translate command, I assumed that the intent was to replace the alpha chars with either a space or asterisk, but both of these would still result in strings and cause the same errors.

Errors:

sh: invalid number '3]10]0]1160]66]1]]]7]]86]64]'
sh: invalid number ''
sh: invalid number ''

Strange --without-devpoll behaviour

On an Alpine Linux with build-base installed, I'm finding a strange behaviour with the configure --with-devpoll and --without-devpoll behavior.

  • --without-devpoll sets WITH_DEVPOLL to 1 (which seems strange)
/event-driven-servers # ./configure --without-devpoll tac_plus-ng && echo '### DEVPOLL STATUS' && grep -i DEVPOLL build/Makefile.inc.linux-5.15.0-39-generic-x86_64

The file

    build/Makefile.inc.linux-5.15.0-39-generic-x86_64

was just created. You may run "make" now. After that, you may wish to do a
"make install". Alternatively, you'll find the compiled binaries (plus some
ancillary scripts) in the

    build/linux-5.15.0-39-generic-x86_64/fakeroot/

directory structure. It's probably advisable to have a look there in any case,
as you may or may not like the particular file system layout, and this will
give you a chance to see it before installing.

Please direct support requests to the "Event-Driven Servers" Google Group at:

    [email protected]
    http://groups.google.com/group/event-driven-servers

Support requests sent to the author's private email address may be silently
ignored.

### DEVPOLL STATUS
WITH_DEVPOLL=1
  • --with-devpoll sets WITH_DEVPOLL to 1
/event-driven-servers # ./configure --with-devpoll tac_plus-ng && echo '### DEVPOLL STATUS' && grep -i DEVPOLL build/Makefile.inc.linux-5.15.0-39-generic-x86_64

The file

    build/Makefile.inc.linux-5.15.0-39-generic-x86_64

was just created. You may run "make" now. After that, you may wish to do a
"make install". Alternatively, you'll find the compiled binaries (plus some
ancillary scripts) in the

    build/linux-5.15.0-39-generic-x86_64/fakeroot/

directory structure. It's probably advisable to have a look there in any case,
as you may or may not like the particular file system layout, and this will
give you a chance to see it before installing.

Please direct support requests to the "Event-Driven Servers" Google Group at:

    [email protected]
    http://groups.google.com/group/event-driven-servers

Support requests sent to the author's private email address may be silently
ignored.

### DEVPOLL STATUS
WITH_DEVPOLL=1
  • Not setting the flag does not set WITH_DEVPOLL
/event-driven-servers # ./configure tac_plus-ng && echo '### DEVPOLL STATUS' && grep -i DEVPOLL build/Makefile.inc.linux-5.15.0-39-generic-x86_64

The file

    build/Makefile.inc.linux-5.15.0-39-generic-x86_64

was just created. You may run "make" now. After that, you may wish to do a
"make install". Alternatively, you'll find the compiled binaries (plus some
ancillary scripts) in the

    build/linux-5.15.0-39-generic-x86_64/fakeroot/

directory structure. It's probably advisable to have a look there in any case,
as you may or may not like the particular file system layout, and this will
give you a chance to see it before installing.

Please direct support requests to the "Event-Driven Servers" Google Group at:

    [email protected]
    http://groups.google.com/group/event-driven-servers

Support requests sent to the author's private email address may be silently
ignored.

### DEVPOLL STATUS

The configure documentation does say that it enables the option, maybe I am misunderstanding it.

This option enables /dev/poll support. You may use it on Linux
with /dev/poll patch (untested), or on a sufficiently recent Sun
Solaris system (7 onwards).
  --without-devpoll
  --with-devpoll

For my use case I do not need it so not setting it produces the correct behavior.

undefined reference to symbol 'crypt@@XCRYPT_2.0' on Rocky Linux v8

Hi Marc,

I'm experiencing the following error during the make step when compiling the current version on Rocky Linux v8. Would you be able to provide any guidance? Steps to reproduce below.

Error

clang -o tac_plus acct.o authen.o author.o buffer.o config.o dump.o main.o mavis.o packet.o report.o utils.o context.o -Wl,-rpath,$ORIGIN/../lib64 -L/root/rpmbuild/SOURCES/build/linux-4.18.0-425.3.1.el8.x86_64-x86_64/mavis -Wl,-rpath,/usr/local/lib64 -lmavis   -lcrypto -L/usr/lib -Wl,-rpath,/usr/lib -lpcre2-8
/usr/bin/ld: authen.o: undefined reference to symbol 'crypt@@XCRYPT_2.0'
//../lib64/libcrypt.so.1: error adding symbols: DSO missing from command line
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/root/rpmbuild/SOURCES/tac_plus/Makefile.obj:25: tac_plus] Error 1
make[2]: Leaving directory '/root/rpmbuild/SOURCES/build/linux-4.18.0-425.3.1.el8.x86_64-x86_64/tac_plus'
make[1]: *** [GNUmakefile:24: build] Error 2
make[1]: Leaving directory '/root/rpmbuild/SOURCES/tac_plus'
make: *** [GNUmakefile:31: dirs] Error 1

Observation

If I manually run the clang step with an extra "-lcrypt" it "appears" to work.

cd /root/rpmbuild/SOURCES/build/linux-4.18.0-425.3.1.el8.x86_64-x86_64/tac_plus
clang -o tac_plus acct.o authen.o author.o buffer.o config.o dump.o main.o mavis.o packet.o report.o utils.o context.o -Wl,-rpath,$ORIGIN/../lib64 -L/root/rpmbuild/SOURCES/build/linux-4.18.0-425.3.1.el8.x86_64-x86_64/mavis -Wl,-rpath,/usr/local/lib64 -lmavis -lcrypt  -lcrypto -L/usr/lib -Wl,-rpath,/usr/lib -lpcre2-8

Steps to Reproduce

Base Install of Rocky Linux v8

systemctl --now disable firewalld

Update to current

dnf -y update

Install EPEL Repositories

dnf -y install epel-release

Install Dependencies (to compile tac_plus-ng from source and package into RPM)

dnf -y install \
 c-ares-devel.x86_64 \
 clang.x86_64 \
 freeradius-client-devel.x86_64 \
 gcc.x86_64 \
 git.x86_64 \
 keyutils-libs-devel.x86_64 \
 krb5-devel.x86_64 \
 libcom_err-devel.x86_64 \
 libcurl-devel.x86_64 \
 libkadm5.x86_64 \
 libretls-devel.x86_64 \
 libselinux-devel.x86_64 \
 libsepol-devel.x86_64 \
 libverto-devel.x86_64 \
 libxcrypt-devel.x86_64 \
 lksctp-tools-devel.x86_64 \
 make.x86_64 \
 openssl-devel.x86_64 \
 openssl3.x86_64 \
 openssl3-devel.x86_64 \
 openssl3-libs.x86_64 \
 pam-devel.x86_64 \
 pcre.x86_64 \
 pcre2-devel.x86_64 \
 pcre2-utf16.x86_64 \
 pcre2-utf32.x86_64 \
 perl.x86_64 \
 perl-Net-SSLeay.x86_64 \
 radcli-devel.x86_64 \
 rng-tools.x86_64 \
 rpmdevtools.noarch \
 rpmlint.noarch \
 rpm-build.x86_64 \
 rsyslog.x86_64 \
 tree.x86_64 \
 zlib-devel.x86_64

Remove Previous Build

rm -rf ~/rpmbuild/

Create RPM tree

rpmdev-setuptree

Display RPM Build Tree

tree ~/rpmbuild

Environment Variables (derived from https://github.com/MarcJHuber/event-driven-servers/blob/master/Makefile.inc)

current=`date +"%Y_%m_%d"`
TR=/usr/bin/tr
OSs=$(uname -s | env -i $TR "[:upper:]/ " "[:lower:]--")
OSr=$(uname -r | sed "s/(.*)//" | env -i $TR "[:upper:]/ " "[:lower:]--")
OSm=$(uname -m | env -i $TR "[:upper:]/ " "[:lower:]--")
OS=$OSs-$OSr-$OSm

Disable Level 1 RPATH Errors

export QA_RPATHS=0x0001
# unset QA_RPATHS

Typically run within an RPM spec file but manually performed for this issue.

cd ~/rpmbuild/
rm -rf ~/rpmbuild/SOURCES/
mkdir -p ~/rpmbuild/SOURCES/
cd ~/rpmbuild/SOURCES/
git clone https://github.com/MarcJHuber/event-driven-servers/ .

## Configure and make
CFLAGS= ./configure \
 --with-pam \
 --with-pcre \
 --with-pcre2 \
 --without-ares

make

tac_plus-ng net objects parent/child relation in rule nas evaluation

First of all: Thank you for tac_plus and a great rewrite with tac_plus-ng. We really like the config structure that we can use with ng.

Unfortunately I have one issue though with net object config when evaluating nas by net object, there is either a bug regarding parent/child relationship of net objects or I simply do not understand how it is meant to work.

The issue:
When I check in a rule script block for nas==netObjectName I would expect it to only check if there is a match on IPs WITHIN that net object and its children, but apparently it also evaluates to true if the parent of that net object has a match on the nas ip.

Is that the intended behaviour or is this a bug?

Simple example config to illustrate the issue, used with the latest version of tac_plus-ng (cloned repo today and built):
### /etc/tac_plus/tac_plus-ng.cfg
id = spawnd {
	background = no
#	single process = yes
	listen { port = 49 }
	spawn {
		instances min = 1
		instances max = 32
	}
}

id = tac_plus-ng {
  include = /etc/tac_plus/logging.cfg

  net switches {
    address=172.20.3.0/24
    net access-switches {
      address = 172.20.3.100
      address = 172.20.3.101
    }
  }

  host all {
    address = 0.0.0.0/0
    key = tacacskey
  }

  group accessadmins

  user accessadmin {
    password pap = clear accessadmin
    member = accessadmins
  }

  ruleset {
    rule accessadmins {
      script {
        if( member == accessadmins && nas == access-switches ) permit
      }
    }      
  }
}
Tested with tactrace.pl with nad=172.20.3.10 which I expected to fail but evaluates to true
user@host:/# TACTRACEPASSWORD=accessadmin tactrace.pl --conf=/etc/tac_plus/tac_plus-ng.cfg --nad=172.20.3.20 --key=tacacskey --authentype=pap --mode=authc --username=accessadmin
172.20.3.20 ---<start packet>---
172.20.3.20 session id: 00000001, data length: 43
172.20.3.20 AUTHEN/START, priv_lvl=0
172.20.3.20 action=login (1)
172.20.3.20 authen_type=pap (2)
172.20.3.20 service=login (1)
172.20.3.20 user_len=11 port_len=4 rem_addr_len=9
172.20.3.20 data_len=11
172.20.3.20 user (len: 11): accessadmin
172.20.3.20 0000 61 63 63 65 73 73 61 64  6d 69 6e                 accessad min
172.20.3.20 port (len: 4): vty0
172.20.3.20 0000 76 74 79 30                                       vty0
172.20.3.20 rem_addr (len: 9): 127.0.0.1
172.20.3.20 0000 31 32 37 2e 30 2e 30 2e  31                       127.0.0. 1
172.20.3.20 ---<end packet>---
172.20.3.20 evaluating ACL accessadmins
172.20.3.20  line 42: [member] member 'accessadmins' => true
172.20.3.20  line 42: [nas] net 'access-switches' => true
172.20.3.20  line 42: [&&] => true
172.20.3.20  line 42: [permit]
172.20.3.20 ACL accessadmins: match
172.20.3.20 [email protected]: ACL accessadmins: permit (profile: n/a)
172.20.3.20 pap login for 'accessadmin' from 127.0.0.1 on vty0 succeeded
172.20.3.20 Writing AUTHEN/PASS size=18
172.20.3.20 ---<start packet>---
172.20.3.20 session id: 00000001, data length: 6
172.20.3.20 AUTHEN, status=1 (AUTHEN/PASS) flags=0x0
172.20.3.20 msg_len=0, data_len=0
172.20.3.20 msg (len: 0): 
172.20.3.20 data (len: 0): 
172.20.3.20 ---<end packet>---

FYI: The same tactrace.pl with for example nad=172.20.100.20 (outside of net switches definition) fails as expected.

Compile error since commit 5ed6cbc66be00d3cf090dbae88650a0038d8b1c6 (tac_plus-ng: add dns name logging)

Command "make" terminates with an error (see the attachments for details) since pull the latest commit 5ed6cbc
bug_compile_configure.log
bug_compile_make.log

My linux OS:
[cat /etc/os-release]
NAME="AlmaLinux"
VERSION="9.1 (Lime Lynx)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.1 (Lime Lynx)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"

ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9"
ALMALINUX_MANTISBT_PROJECT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"

Outdated tac_plus-ng documentation

Hello Marc,

I realize that in the last versions of tac_plus-ng, the syntax of the configuration has changed drastically.
I have difficulty using the various configuration attributes without documentation.

Could I have missed a new version of the documentation?
Is it planned to be updated?

Cheers

check change passwd tac-ng

Hi, Marc.
I've just figured out that your perl script hasn't checked the password complexity (I'm talking about the shadow backend).

curkanu.d@MacBook-Pro ~ % ssh test_box
Welcome
Password: "safely and long passwd"
Please change your password.
New password: "1"
Retype new password: "1"
Password change was successful.

Could you please fix it?

Regards,
D A

PAM headers not checked in security/ if --with-pam is set

If you explicitly set --with-pam when configuring, due to this WITH_PAM being set to 1 already, it will not process this section:

https://github.com/MarcJHuber/event-driven-servers/blob/master/Makefile.inc#L734-L739

ifeq ($(WITH_PAM),)
	ifneq ($(wildcard /usr/include/security/pam_appl.h),)
		DEF += -DHAVE_SECURITY_PAM_APPL_H
		WITH_PAM=1
	endif
endif
  • --with-pam
/event-driven-servers # ./configure --with-pam tac_plus-ng >/dev/null && echo '### PAM STATUS' && grep WITH_PAM build/Makefile.inc.linux-5.15.0-39-generic-x86_64
### PAM STATUS
WITH_PAM=1

/event-driven-servers # make clean 2>/dev/null && make 2>&1 | grep pam
cc  -Wall -W -Wno-strict-prototypes -Wno-implicit-fallthrough   -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DOSTYPE=linux -DOSLEVEL=0x00000000 -DOS="\"linux-5.15.0-39-generic-x86_64\"" -DWITH_EPOLL -DWITH_POLL -DWITH_SELECT -DWITH_IPC -I/event-driven-servers       -I/usr/include -c -o pammavis.o /event-driven-servers/mavis/pammavis.c
                 from /event-driven-servers/mavis/pammavis.c:9:
/event-driven-servers/mavis/pammavis.c:20:10: fatal error: pam/pam_appl.h: No such file or directory
   20 | #include <pam/pam_appl.h>
make[2]: *** [/event-driven-servers/Makefile.inc:876: pammavis.o] Error 1
  • Without a flag set
/event-driven-servers # ./configure tac_plus-ng >/dev/null && echo '### PAM STATUS' && grep WITH_PAM build/Makefile.inc.linux-5.15.0-39-generic-x86_64
### PAM STATUS

/event-driven-servers # make clean 2>/dev/null && make 2>&1 | grep pam
cc  -Wall -W -Wno-strict-prototypes -Wno-implicit-fallthrough   -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DOSTYPE=linux -DOSLEVEL=0x00000000 -DOS="\"linux-5.15.0-39-generic-x86_64\"" -DHAVE_SECURITY_PAM_APPL_H -DWITH_EPOLL -DWITH_POLL -DWITH_SELECT -DWITH_IPC -I/event-driven-servers        -c -o pammavis.o /event-driven-servers/mavis/pammavis.c
                 from /event-driven-servers/mavis/pammavis.c:9:
cc -o pammavis pammavis.o '-Wl,-rpath,$ORIGIN/../lib' "-L/event-driven-servers/build/linux-5.15.0-39-generic-x86_64/mavis" "-Wl,-rpath,/usr/local/lib" -lmavis  -lpam
cc  -Wall -W -Wno-strict-prototypes -Wno-implicit-fallthrough   -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DOSTYPE=linux -DOSLEVEL=0x00000000 -DOS="\"linux-5.15.0-39-generic-x86_64\"" -DHAVE_SECURITY_PAM_APPL_H -DWITH_EPOLL -DWITH_POLL -DWITH_SELECT -DWITH_IPC -I/event-driven-servers       -fPIC  -c -o libmavis_pam.o /event-driven-servers/mavis/libmavis_pam.c
                 from /event-driven-servers/mavis/libmavis_pam.c:40:
cc -shared -o libmavis_pam.so libmavis_pam.o -lpam
install -c -m 0755 libmavis_pam.so /event-driven-servers/build/linux-5.15.0-39-generic-x86_64/fakeroot/usr/local/lib/mavis/libmavis_pam.so
install -c -m 0755 pammavis /event-driven-servers/build/linux-5.15.0-39-generic-x86_64/fakeroot/usr/local/sbin/pammavis

FLAG_USE_MEMBEROF is being ignored

Hello,

I've been trying to make tac_plus-ng work with openldap for a while now but all my attempts to use group membership to assign user profiles have failed so far. We have memberof overlay enabled on the ldap side and I can see my groups membership returned when I run ldapsearch while requesting memberof attribute specifically or all atributes (+), however I'm not able to use memberof conditions in the rulesets and tactrace.pl doesn't show any groups being returned/used:

192.168.1.1 looking for user achurak in MAVIS backend
192.168.1.1 user found by MAVIS backend, av pairs:
  USER                achurak
  DN                  uid=achurak,ou=users,dc=example,dc=com
  IPADDR              1.2.3.4
  SERVERIP            192.168.1.1
  REALM               default
  IDENTITY_SOURCE     1
192.168.1.1 ACL from-localhost: no match
192.168.1.1 [email protected]: ACL from-localhost: <unknown> (profile: n/a)
192.168.1.1 [email protected]: svcname=shell protocol= denied

My config looks like this:

mavis module = groups {
        resolve gids = yes
        resolve gid = yes
        groups filter = /^(netadmins|guest|readonly|netops|devops)$/
        memberof filter = /^CN=tacacs_/ # use this as a prefix
    }

mavis module = external {
        setenv LDAP_SERVER_TYPE = "generic"
        setenv LDAP_HOSTS = "x.x.x.x:389 x.x.x.x:389"
        setenv LDAP_BASE = "dc=example,dc=com"
        setenv LDAP_SCOPE = sub
        setenv LDAP_USER = "cn=user,dc=example,dc=com"
        setenv LDAP_PASSWD = "secret"
        setenv FLAG_USE_MEMBEROF = 1
        setenv LDAP_FILTER = "(uid=%s)"
        setenv TACACS_GROUP_PREFIX = "tacacs_"
        setenv USE_TLS = 1
        exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
    }

    user backend = mavis
    login backend = mavis
    pap backend = mavis

profile readwrite {
    script {
        if (service == shell) {
            if (cmd == "") {
                set priv-lvl = 15
                permit
            }
        }
    }
}

group netadmins

ruleset {
    rule from-localhost {
        enabled = yes
        script {
            if (memberof =~ /^cn=tacacs_netadmins,/) {
                profile = readwrite
                permit
            }
        }
    }
}

What am I doing wrong? Most examples and documentation show MS AD as a MAVIS backend, so there's not a lot of information available around openldap integration unfortunately.

empty key not working

Hi Marc,

I inherited a lot of switches and routers without tacacs key and
the tac_plus software should be updated to the current version.

The installed tac_plus server (Version 202104181633/DES) works with empty key = ""

The current (just cloned and compiled,
Version "b5d4dada8a326f3e3a02690ad3cbd9fa67a0882b" ) does not.

When setting key in the config and on the device, everything seems to work.

The manual https://www.pro-bono-publico.de/projects/pdf/tac_plus.pdf states:

"The daemon will reject connections from hosts that have no encryption key defined."
but also
"During debugging, it may be convenient to temporarily switch off encryption by using an empty key:"

So i think it should function also with an empty key.

In the syslog, i find the following messages (for key = "")

2023-06-11T13:46:53.723240+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 New session

2023-06-11T13:46:53.728074+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 ---<start packet>---
2023-06-11T13:46:53.728176+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 key used:
2023-06-11T13:46:53.728291+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 version: 192, type: 1, seq no: 1, flags: encrypted
2023-06-11T13:46:53.728369+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 session id: ddd34512, data length: 26
2023-06-11T13:46:53.728462+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 Packet malformed, skipping detailed dump.
2023-06-11T13:46:53.728538+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 ---<end packet>---

2023-06-11T13:46:53.728612+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 Error 192.168.33.253 (null): Illegal packet (version=0xc0 type=0x01)
2023-06-11T13:46:53.728686+00:00 vulcan tac_plus[9813]: 192.168.33.253 Error 192.168.33.253 (null): Illegal packet (version=0xc0 type=0x01)
2023-06-11T13:46:53.728773+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 Writing AUTHEN/ERROR size=57

2023-06-11T13:46:53.728873+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 ---<start packet>---
2023-06-11T13:46:53.728943+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 key used:
2023-06-11T13:46:53.729011+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 version: 192, type: 1, seq no: 2, flags: unencrypted
2023-06-11T13:46:53.729085+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 session id: ddd34512, data length: 45
2023-06-11T13:46:53.729158+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 AUTHEN, status=7 (AUTHEN/ERROR) flags=0x0
2023-06-11T13:46:53.729272+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 msg_len=39, data_len=0
2023-06-11T13:46:53.729330+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 msg (len: 39): Illegal packet (version=0xc0 type=0x01)
2023-06-11T13:46:53.729382+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 data (len: 0):
2023-06-11T13:46:53.729444+00:00 vulcan tac_plus[9813]: 2/1245d3dd: 192.168.33.253 ---<end packet>---

2023-06-11T13:46:58.721693+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 New session

2023-06-11T13:46:58.721838+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 ---<start packet>---
2023-06-11T13:46:58.721902+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 key used:
2023-06-11T13:46:58.721968+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 version: 192, type: 2, seq no: 1, flags: encrypted
2023-06-11T13:46:58.722025+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 session id: 7d18c6db, data length: 47
2023-06-11T13:46:58.722083+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 Packet malformed, skipping detailed dump.
2023-06-11T13:46:58.722147+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 ---<end packet>---

2023-06-11T13:46:58.722205+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 Writing AUTHOR/ERROR size=57

2023-06-11T13:46:58.722262+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 ---<start packet>---
2023-06-11T13:46:58.722308+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 key used:
2023-06-11T13:46:58.722354+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 version: 192, type: 2, seq no: 2, flags: unencrypted
2023-06-11T13:46:58.722411+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 session id: 7d18c6db, data length: 45
2023-06-11T13:46:58.722474+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 AUTHOR/REPLY, status=17 (AUTHOR/ERROR)
2023-06-11T13:46:58.722555+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 msg_len=39, data_len=0, arg_cnt=0
2023-06-11T13:46:58.722620+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 msg (len: 39): Illegal packet (version=0xc0 type=0x02)
2023-06-11T13:46:58.722674+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 data (len: 0):
2023-06-11T13:46:58.722743+00:00 vulcan tac_plus[9813]: 3/dbc6187d: 192.168.33.253 ---<end packet>---

When using key = cisco, all shown pakets have "flags: unencrypted"
Shouldn't that be all encrypted since i am using a key ?

2023-06-12T15:44:17.899457+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 New session

2023-06-12T15:44:17.904615+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 ---<start packet>---
2023-06-12T15:44:17.904738+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 key used: cisco
2023-06-12T15:44:17.904828+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 version: 192, type: 1, seq no: 1, flags: unencrypted
2023-06-12T15:44:17.904915+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 session id: 084e4b8d, data length: 26
2023-06-12T15:44:17.904995+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 AUTHEN/START, priv_lvl=1
2023-06-12T15:44:17.905081+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 action=login (1)
2023-06-12T15:44:17.905164+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 authen_type=ascii (1)
2023-06-12T15:44:17.905229+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 service=login (1)
2023-06-12T15:44:17.905285+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 user_len=0 port_len=5 rem_addr_len=13
2023-06-12T15:44:17.905340+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 data_len=0
2023-06-12T15:44:17.905410+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 user (len: 0):
2023-06-12T15:44:17.905478+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 port (len: 5): tty10
2023-06-12T15:44:17.905534+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 rem_addr (len: 13): 192.168.33.99
2023-06-12T15:44:17.905603+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 ---<end packet>---

2023-06-12T15:44:17.905667+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 authen: hdr->seq_no: 1
2023-06-12T15:44:17.905735+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 Writing AUTHEN/GETUSER size=55

2023-06-12T15:44:17.905937+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 ---<start packet>---
2023-06-12T15:44:17.906051+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 key used: cisco
2023-06-12T15:44:17.906159+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 version: 192, type: 1, seq no: 2, flags: unencrypted
2023-06-12T15:44:17.906286+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 session id: 084e4b8d, data length: 43
2023-06-12T15:44:17.906399+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 AUTHEN, status=4 (AUTHEN/GETUSER) flags=0x0
2023-06-12T15:44:17.906511+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 msg_len=37, data_len=0
2023-06-12T15:44:17.906623+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 msg (len: 37): \nUser Access Verification\n\nUsername:
2023-06-12T15:44:17.906753+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 data (len: 0):
2023-06-12T15:44:17.906875+00:00 vulcan tac_plus[9852]: 6/8d4b4e08: 192.168.33.253 ---<end packet>---

[...]

Device here is a Cisco router with IOS 15.9(3)M5 .

What is going wrong ?

Thanks for looking at this.

Compile Failure on Alpine

Having issues with a simple "make" of the application on multiple Docker distro images. Both Ubuntu and Alpine are reporting errors with line 407 of 'Makefile.inc'

099047d7298d:/event-driven-servers# ./configure tac_plus-ng

The file

    build/Makefile.inc.linux-3.10.0-1160.66.1.el7.x86_64-x86_64

was just created. You may run "make" now. After that, you may wish to do a
"make install". Alternatively, you'll find the compiled binaries (plus some
ancillary scripts) in the

    build/linux-3.10.0-1160.66.1.el7.x86_64-x86_64/fakeroot/

directory structure. It's probably advisable to have a look there in any case,
as you may or may not like the particular file system layout, and this will
give you a chance to see it before installing.

Please direct support requests to the "Event-Driven Servers" Google Group at

    [email protected]
    https://groups.google.com/group/event-driven-servers

or file an issue at

    https://github.com/MarcJHuber/event-driven-servers

if you need help.

Support requests sent to the author's private email address may be silently
ignored.

099047d7298d:/event-driven-servers# 

099047d7298d:/event-driven-servers# make
sh: invalid number '3]10]0]1160]66]1]]]7]]86]64]'
sh: invalid number ''
sh: invalid number ''
Makefile.inc:407: *** invalid syntax in conditional.  Stop.
099047d7298d:/event-driven-servers# 

I feel like it's likely something as simple as a missing package but I can't find any comprehensive list of what's required. In my attempts to get a successful compile, here's the list of packages I have thus far:

    apk add build-base bzip2 perl perl-digest-md5 perl-ldap perl-io-socket-ssl bash git clang gcc flex bison pcre pcre2 && \
    apk add zlib curl make perl-regexp-tr

tac_plus issue if-clause / external module inclusion since Apr., 17 2023 (193d7513)

Hi,

this is a follow-up on the previous issue #54.

Our established use-case is as follows:

  1. Access-Requests with username <user>@test123 should be forwarded to customer's RADIUS server 1.2.3.4
  2. All other credentials should be validated against to our openldap.

Configuation snippet:

        #
        # users with realm @test123
        # testmb
        mavis module = external {
                script in  = { if ($USER !~ /^.*\@test123.*$/ ) skip }
                script out = {
                        if ($TYPE == TACPLUS) {
                                if ($TACTYPE == AUTH && $PASSWORD == $DBPASSWORD || $TACTYPE == INFO) {
                                        set $RESULT = ACK
                                        if ($USER =~ /^.*\@test123.*$/ ) {
                                                set $TACPROFILE = "{ member = RO_LIMITED }"
                                        }
                                }
                        }
                }
                exec = /usr/local/sbin/radmavis radmavis "authserver=1.2.3.4:1812:secret"
        }

        #
        # standard users
	mavis module = external {
		setenv LDAP_SERVER_TYPE = "openldap"
		setenv LDAP_HOSTS = "ldap"
                setenv LDAP_CONNECT_TIMEOUT = 2
		setenv LDAP_BASE = "dc=users,dc=com"
		setenv LDAP_FILTER = "(uid=%s)"
		setenv LDAP_FILTER_CHPW = "(uid=%s)"
                # ...
                # truncated - no issue with ldap
	}

Our setup works as expected before commit 193d751:

     1: io_poll (0x557787fe1080) timeout: 7860, res: 1
     1: fd 3 ctx 0x557787fe0c70
     1: fd 3 cb = 0x7f9c937d111c
     1: + spawnd_accepted
     1: - spawnd_accepted
     1: io_sched_exec (0x557787fe1080)
     1: poll_timeout = 3553ms
     1: io_poll (0x557787fe1080) timeout: 3553
    13: io_poll (0x56165a5c61a0) timeout: 60001, res: 1
    13: fd 3 ctx 0x56165a961a10
    13: fd 3 cb = 0x561658847fc8
    13:  io_register 4
    13: io_sched_add 0x56165a97bfe0 60.0
    13: io_sched_exec (0x56165a5c61a0)
    13: poll_timeout = 55118ms
    13: io_poll (0x56165a5c61a0) timeout: 55118
    13: io_poll (0x56165a5c61a0) timeout: 55118, res: 1
    13: fd 4 ctx 0x56165a97bfe0
    13: fd 4 cb = 0x56165884a3d3
    13: io_sched_exec (0x56165a5c61a0)
    13: poll_timeout = 55118ms
    13: io_poll (0x56165a5c61a0) timeout: 55118
    13: io_poll (0x56165a5c61a0) timeout: 55118, res: 1
    13: fd 4 ctx 0x56165a97bfe0
    13: fd 4 cb = 0x5616588499be
    13: io_sched_exec (0x56165a5c61a0)
    13: poll_timeout = 55118ms
    13: io_poll (0x56165a5c61a0) timeout: 55118
    13: io_poll (0x56165a5c61a0) timeout: 55118, res: 1
    13: fd 4 ctx 0x56165a97bfe0
    13: fd 4 cb = 0x56165884a3d3
    13:  av_set(TYPE) = TACPLUS             
    13:  av_set(USER) = test@test123        
    13:  av_set(TIMESTAMP) = -509973301          
    13:  av_set(TACTYPE) = AUTH                
    13:  av_set(SERVERIP) = 127.0.0.1           
    13:  av_set(REALM) = default             
    13:  av_set(PASSWORD) = test                
    13: + mavis_send
    13:   av_set(SERIAL) = jzz0SHFFKUzjRh2T/I1Kjw=
    13:  + external:Mavis_send
    13:    av_get(USER) = test@test123        
    13:    av_get(TYPE) = TACPLUS             
    13:    av_get(SERIAL) = jzz0SHFFKUzjRh2T/I1Kjw=
    13:   starting query on child 0 (jzz0SHFFKUzjRh2T/I1Kjw=)
    13:    av_get(TYPE) = TACPLUS             
    13:    av_get(TIMESTAMP) = -509973301          
    13:    av_get(USER) = test@test123        
    13:    av_get(PASSWORD) = test                
    13:    av_get(SERIAL) = jzz0SHFFKUzjRh2T/I1Kjw=
    13:    av_get(SERVERIP) = 127.0.0.1           
    13:    av_get(REALM) = default             
    13:    av_get(TACTYPE) = AUTH                
    13:   + external:write_to_child
    13:   - external:write_to_child
    13:   io_poll (0x56165a961de0) timeout: -1
     1: io_poll (0x557787fe1080) timeout: 3553, res: 0
     1: io_sched_exec (0x557787fe1080)
     1:  executing ...
     1: + periodics
     1:  io_sched_renew_proc 0x557787fe3590
     1:  to be fired at 649439c5:000dcda3
     1:  servers_cur: 10
     1:  servers_count: 10
     1:  servers_min: 10
     1: - periodics
     1: ... done.
     1:  rescheduled at 649439c5:000dcda3 (10s)
     1: poll_timeout = 10001ms
     1: io_poll (0x557787fe1080) timeout: 10001
    14: io_poll (0x56317bd691a0) timeout: 60001, res: 0
    14: io_sched_exec (0x56317bd691a0)
    14:  executing ...
    14: io_sched_renew_proc 0x56317c104bc0
    14: to be fired at 649439fb:0007a124
    14: ... done.
    14:  rescheduled at 649439fb:0007a124 (60s)
    14: poll_timeout = 60001ms
    14: io_poll (0x56317bd691a0) timeout: 60001
     1: io_poll (0x557787fe1080) timeout: 10001, res: 1
     1: fd 5 ctx 0x557787fe3980
     1: fd 5 cb = 0x7f9c937d4451
     1: io_sched_exec (0x557787fe1080)
     1: poll_timeout = 6405ms
     1: io_poll (0x557787fe1080) timeout: 6405

tcpdump:

root@tn-aaa-ceacs2:~# tcpdump -i any host 1.2.3.4
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
14:08:24.350936 veth53a2f73 P   IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:24.350960 br-295336a56b7f In  IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:24.350999 eth0  Out IP tn-aaa-ceacs2.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:29.356157 veth53a2f73 P   IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:29.356169 br-295336a56b7f In  IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:29.356199 eth0  Out IP tn-aaa-ceacs2.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:34.361417 veth53a2f73 P   IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:34.361430 br-295336a56b7f In  IP 172.35.199.100.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70
14:08:34.361461 eth0  Out IP tn-aaa-ceacs2.42425 > 1.2.3.4.radius: RADIUS, Access-Request (1), id: 0xa8 length: 70

(please ignore that there is no reply here, as there is no RADIUS in the testlab).

In newer commits (like 8c86061) it seems that the if-statement is skipped and the @test123 users are checked against the LDAP where they are not known:

     1: io_poll (0x55666fe1b080) timeout: 10001, res: 0
     1: io_sched_exec (0x55666fe1b080)
     1:  executing ...
     1: + periodics
     1:  io_sched_renew_proc 0x55666fe1d590
     1:  to be fired at 64944687:000281ae
     1:  servers_cur: 10
     1:  servers_count: 10
     1:  servers_min: 10
     1: - periodics
     1: ... done.
     1:  rescheduled at 64944687:000281ae (10s)
     1: poll_timeout = 10001ms
     1: io_poll (0x55666fe1b080) timeout: 10001
     1: io_poll (0x55666fe1b080) timeout: 10001, res: 1
     1: fd 3 ctx 0x55666fe1ac70
     1: fd 3 cb = 0x7f41123907f1
     1: + spawnd_accepted
     1: - spawnd_accepted
     1: io_sched_exec (0x55666fe1b080)
     1: poll_timeout = 6604ms
     1: io_poll (0x55666fe1b080) timeout: 6604
    13: io_poll (0x5645d72f3960) timeout: 58325, res: 1
    13: fd 3 ctx 0x5645d72fd060
    13: fd 3 cb = 0x5645d585cfdc
    13:  io_register 4
    13: io_sched_add 0x5645d76ab350 60.0
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28150ms
    13: io_poll (0x5645d72f3960) timeout: 28150
    13: io_poll (0x5645d72f3960) timeout: 28150, res: 1
    13: fd 4 ctx 0x5645d76ab350
    13: fd 4 cb = 0x5645d585f417
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28150ms
    13: io_poll (0x5645d72f3960) timeout: 28150
    13: io_poll (0x5645d72f3960) timeout: 28150, res: 1
    13: fd 4 ctx 0x5645d76ab350
    13: fd 4 cb = 0x5645d585ea02
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28150ms
    13: io_poll (0x5645d72f3960) timeout: 28150
    13: io_poll (0x5645d72f3960) timeout: 28150, res: 1
    13: fd 4 ctx 0x5645d76ab350
    13: fd 4 cb = 0x5645d585f417
    13:  av_set(TYPE) = TACPLUS             
    13:  av_set(USER) = test@test123        
    13:  av_set(TIMESTAMP) = 1695758164          
    13:  av_set(TACTYPE) = AUTH                
    13:  av_set(SERVERIP) = 127.0.0.1           
    13:  av_set(REALM) = default             
    13:  av_set(PASSWORD) = test                
    13: + mavis_send
    13:   av_set(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:  + external:Mavis_send
    13:    av_get(USER) = test@test123        
0/line 55: [!] => true
0/line 55: [skip]
    13:   + external:Mavis_send
    13:     av_get(TYPE) = TACPLUS             
    13:     av_get(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:    starting query on child 0 (6AOl22pt0ZHOK9kIzEMEcA=)
    13:     av_get(TYPE) = TACPLUS             
    13:     av_get(TIMESTAMP) = 1695758164          
    13:     av_get(USER) = test@test123        
    13:     av_get(PASSWORD) = test                
    13:     av_get(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:     av_get(SERVERIP) = 127.0.0.1           
    13:     av_get(REALM) = default             
    13:     av_get(TACTYPE) = AUTH                
    13:    + external:write_to_child
    13:    - external:write_to_child
    13:   - external:Mavis_send = 1
    13:  - external:Mavis_send = 1
    13: - mavis_send (1)
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28150ms
    13: io_poll (0x5645d72f3960) timeout: 28150
    13: io_poll (0x5645d72f3960) timeout: 28150, res: 1
    13: fd 18 ctx 0x7f81ba901010
    13: fd 18 cb = 0x7f81ba9b43cd
    13: + external:read_from_child
    13:  /tmp/event-driven-servers/mavis/libmavis_external.c:448 /usr/local/lib/mavis/mavis_tacplus_ldap.pl
    13:   av_get(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:  + av_clear
    13:  - av_clear
    13:   av_set(TYPE) = TACPLUS             
    13:   av_get(TYPE) = TACPLUS             
    13:   av_set(TIMESTAMP) = 1695758164          
    13:   av_get(TIMESTAMP) = 1695758164          
    13:   av_set(USER) = test@test123        
    13:   av_get(USER) = test@test123        
    13:   av_set(RESULT) = NFD                 
    13:   av_get(RESULT) = NFD                 
    13:   av_set(PASSWORD) = test                
    13:   av_get(PASSWORD) = test                
    13:   av_set(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:   av_get(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:   av_set(SERVERIP) = 127.0.0.1           
    13:   av_get(SERVERIP) = 127.0.0.1           
    13:   av_set(REALM) = default             
    13:   av_get(REALM) = default             
    13:   av_set(TACTYPE) = AUTH                
    13:   av_get(TACTYPE) = AUTH                
    13:   av_get(SERIAL) = 6AOl22pt0ZHOK9kIzEMEcA=
    13:  + mavis_recv
    13:   + external:Mavis_recv
    13:    + external:mavis_recv_in
    13:    - external:mavis_recv_in
    13:    + external:Mavis_recv
    13:     + external:mavis_recv_in
    13:       av_set(CURRENT_MODULE) = 1                   
    13:      + mavis_send
    13:        av_get(CURRENT_MODULE) = 1                   
    13:       + external:Mavis_send
    13:         av_get(CURRENT_MODULE) = 1                   
    13:        + external:Mavis_send
    13:          av_set(CURRENT_MODULE) = (NULL)              
    13:        - external:Mavis_send = 0
    13:         av_get(TYPE) = TACPLUS             
0/line 57: [<unknown>] $TYPE = 'TACPLUS' => true
    13:         av_get(TACTYPE) = AUTH                
0/line 58: [<unknown>] $TACTYPE = 'AUTH' => true
    13:         av_get(PASSWORD) = test                
0/line 58: [attribute] $PASSWORD = '$DBPASSWORD' => false
0/line 58: [&&] => false
    13:         av_get(TACTYPE) = AUTH                
0/line 58: [<unknown>] $TACTYPE = 'INFO' => false
0/line 58: [||] => false
    13:       - external:Mavis_send = 0
    13:      - mavis_send (0)
    13:     - external:mavis_recv_in
    13:    - external:Mavis_recv = 4
    13:   - external:Mavis_recv = 4
    13:  - mavis_recv
    13:   av_get(TYPE) = TACPLUS             
    13:   av_get(USER) = test@test123        
    13:   av_get(TIMESTAMP) = 1695758164          
    13:   av_get(RESULT) = NFD                 
    13:  + buffer_write
    13:   buffer_get = 0x5645d769a310
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:   buffer_get = 0x5645d76a2350
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
2023-06-22 15:02:56 +0200	127.0.0.1	test@test123	python_tty0	python_device	shell login failed (no such user)
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13:  + buffer_write
    13:  - buffer_write
    13: - external:read_from_child
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28081ms
    13: io_poll (0x5645d72f3960) timeout: 28081
    13: io_poll (0x5645d72f3960) timeout: 28081, res: 3
    13: fd 4 ctx 0x5645d76ab350
    13: fd 4 cb = 0x5645d585ea02
    13: fd 28 ctx 0x5645d7699210
    13: fd 28 cb = 0x5645d5861102
    13: buffer_release (0x5645d769a310, 109)
    13: buffer_free (0x5645d769a310)
    13: buffer_release = (nil)
    13: fd 30 ctx 0x5645d7699260
    13: fd 30 cb = 0x5645d5861102
    13: buffer_release (0x5645d76a2350, 109)
    13: buffer_free (0x5645d76a2350)
    13: buffer_release = (nil)
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28081ms
    13: io_poll (0x5645d72f3960) timeout: 28081
    13: io_poll (0x5645d72f3960) timeout: 28081, res: 1
    13: fd 4 ctx 0x5645d76ab350
    13: fd 4 cb = 0x5645d585f417
    13: + io_sched_pop
    13: - io_sched_pop
    13:  io_unregister 4
    13: io_sched_exec (0x5645d72f3960)
    13: poll_timeout = 28077ms
    13: io_poll (0x5645d72f3960) timeout: 28077
     1: io_poll (0x55666fe1b080) timeout: 6604, res: 1
     1: fd 4 ctx 0x55666fe1d890
     1: fd 4 cb = 0x7f4112393b26
     1: io_sched_exec (0x55666fe1b080)
     1: poll_timeout = 6531ms
     1: io_poll (0x55666fe1b080) timeout: 6531

No RADIUS requests are sent to 1.2.3.4 in this case.

What further output do you need to troubleshoot?

Thanks a lot.

Allowing certain commands

Hi Marc!

Please tell me if it is possible to make a profile in such a config in which all commands are prohibited, except for a few? For example, only commands are allowed: "ping x.x.x.x" and "sh run"

The config is a modified example of "tac_plus-ng.cfg-shadow":

#!/usr/local/sbin/tac_plus-ng

id = spawnd {
        listen = { port = 49 }
        spawn = { instances min = 1 instances max = 1 }
        background = no
}

id = tac_plus-ng {
        mavis module = external {
                        setenv SHADOWFILE = "/etc/shadow"
                        exec = /usr/local/lib/mavis/mavis_tacplus_shadow.pl
        }

        login backend = mavis chpass

        host world {
                        address = ...
                        welcome banner = "Welcome!\n\n"
                        key = secretKey
        }

        profile fullAccess {
                        script {
                                        if (service == shell) {
                                                        if (cmd == "") set priv-lvl = 15
                                                        permit
                                        }
                        }
        }
        
        profile lvl1Access {
                        script {
                                        if (service == shell) {
                                                        if (cmd == "") set priv-lvl = 1
                                                        permit
                                        }
                        }
        }

        group tacAdmins
        group observer

        user tacAdmin {
                        password login = mavis
                        member = tacAdmins
        }

        user observer {
                        password login = mavis
                        member = observer
        }

        ruleset {
                        rule {
                                        script {
                                                        if (member == tacAdmins) {profile = fullAccess permit}
                                                        if (member == observer) {profile = lvl1Access permit}
                                        }
                        }
        }
}

"prompt" keyword not recognised in tac_plus-ng.cfg

Hi Marc,

Thanks for yesterday's update, #153e906 compiles beautifully on Rocky 8 now.

Moving onto configuration I've run a problem with the prompt configurable, in that it get's rejected within the host block with tac-plus-ng. Advice welcomed!

Error message

Nov 24 15:14:32 rocky1 tac_plus-ng[7822]: Error /etc/tac_plus-ng/tac_plus-ng.cfg:62: Expected 'host', 'parent', 'authentication', 'permit', 'bug', 'pap', 'address', 'key', 'motd', 'welcome', 'reject', 'enable', 'anonymous-enable', 'augmented-enable', 'single-connection', 'debug', 'connection', 'context', 'rewrite' or 'script', but got 'prompt

Configuration (Sanitised)

[root@rocky1 log]# cat /etc/tac_plus-ng/tac_plus-ng.cfg 
id = spawnd {
    listen = { 
        address = {{ip_addr}}
        port = 49
    }

    spawn = {
        instances min = 1
        instances max = 10
    }

    # background = yes
}

id = tac_plus-ng {

    log acctlog  {
        destination = /var/log/tacplusng/acct/%Y/%m/%d.log
    }

    log authzlog {
        destination = /var/log/tacplusng/authz/%Y/%m/%d.log
    }

    log authnlog {
        destination = /var/log/tacplusng/authn/%Y/%m/%d.log
    }

    log connlog  {
        destination = /var/log/tacplusng/conn/%Y/%m/%d.log
    }

    accounting log = acctlog
    authentication log = authnlog
    authorization log = authzlog
    connection log = connlog

    mavis module = groups {
        groups filter = /^(tier3|tier2|tier1)$/ # these are defined below
        memberof filter = /^CN=tacacs_/ # use this as a prefix
    }

    mavis module = external {
        setenv LDAP_SERVER_TYPE = "microsoft"
        setenv LDAP_HOSTS = "ldaps://{{ip_addr}}:636"
        setenv LDAP_BASE = "dc=contoso,dc=com"
        setenv LDAP_FILTER = "(&(objectclass=user)(sAMAccountName=%s))"
        setenv LDAP_USER = "[email protected]"
        setenv LDAP_PASSWD = "{{password}}"
        setenv TACACS_GROUP_PREFIX = "tacacs_"
        setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
        #setenv REQUIRE_TACACS_GROUP_PREFIX = 1
        exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
    }

    login backend = mavis
    user backend = mavis
    pap backend = mavis

    host corporate {
        address = 0/0
        key = {{key}}
        prompt = "Prompt\n"
        motd banner = "MOTD\n"
        welcome banner = "Welcome\n"
    }


    profile tier1 {
        script {
            if (service == junos-exec) {
                set local-user-name = remote
                set deny-commands = "clear.*|configure.*|file.*|load.*|monitor.*|mtrace.*|op.*|request.*|restart.*|scp.*|set.*|ssh.*|start.*|telnet.*|test.*"
            }
            permit
        }
    }

    profile tier2 {
        script {
            if (service == junos-exec) {
                set local-user-name = remote
                set deny-commands = "clear.*|configure.*|file.*|load.*|op.*|request.*|restart.*|scp.*|set.*|ssh.*|start.*|telnet.*|test.*"
            }
            permit
        }
    }

    profile tier3 {
        script {
            if (service == junos-exec) {
                set local-user-name = remote
            }
            permit
        }
    }

    group tier1
    group tier2
    group tier3

    ruleset {
        rule {
            script { 
                    if (memberof =~ /^CN=tacacs_tier3,/) { profile = tier3 permit }
                    if (memberof =~ /^CN=tacacs_tier2,/) { profile = tier2 permit }
                    if (memberof =~ /^CN=tacacs_tier1,/) { profile = tier1 permit }
            }
        }
    }
}

tac_plus-ng stuck when checking group membership

My version:
872afa5

Server gets stuck when configuration file contains group membership check for user:

if (group == admins) 

My config file:

id = spawnd {
    listen { port = 49 }
}

id = tac_plus-ng {

        log authclog {
                destination = /var/log/tac_plus/authc/%Y/%m/%d.log
        }
        log authzlog {
                destination = /var/log/tac_plus/authz/%Y/%m/%d.log
        }
        log acctlog {
                destination = /var/log/tac_plus/acct/%Y/%m/%d.log
        }
        authentication log = authclog
        authorization log = authzlog
        accounting log = acctlog

        group testgroup

        user testuser {
                password {
                        login = clear asdfzxcv1234
                }
                member = testgroup
        }

        device test {
                address = 0.0.0.0/0
                key = labKey
        }

        profile readwrite {
                script {
                        if (service == shell) {
                                if (cmd == "") {
                                        set priv-lvl = 15
                                        permit
                                }
                        }
                }
        }

        ruleset {
                rule from-test {
                        script {
                                if (group == testgroup) {
                                        profile = readwrite
                                        permit
                                }
                                deny
                        }
                }
        }
}

debug = ALL USERINPUT

Starting this server provides output:

<OMMITED FOR BREVITY>
3637: file=tacdebug.conf line=36 sym=[=] buf='='
3637: file=tacdebug.conf line=36 sym=[<string>] buf=''
3637: file=tacdebug.conf line=36 sym=[)] buf=')'
3637: file=tacdebug.conf line=36 sym=[)] buf=')'
3637: file=tacdebug.conf line=36 sym=[)] buf=')'
3637: file=tacdebug.conf line=36 sym=[)] buf=')'
3637: file=tacdebug.conf line=36 sym=[)] buf=')'
3637: file=tacdebug.conf line=36 sym=[<end-of-file>] buf=''
3637: 11:21:42.681 0/00000000: - normalized condition: ((((( cmd  = = "")))))
3637: file=tacdebug.conf line=37 sym=[set] buf='set'
3637: file=tacdebug.conf line=37 sym=[priv-lvl] buf='priv-lvl'
3637: file=tacdebug.conf line=37 sym=[=] buf='='
3637: file=tacdebug.conf line=37 sym=[<string>] buf='priv-lvl='
3637: file=tacdebug.conf line=37 sym=[<end-of-file>] buf=''
3637: file=tacdebug.conf line=37 sym=[<string>] buf='15'
3637: file=tacdebug.conf line=38 sym=[permit] buf='permit'
3637: file=tacdebug.conf line=39 sym=[}] buf='}'
3637: file=tacdebug.conf line=40 sym=[}] buf='}'
3637: file=tacdebug.conf line=41 sym=[}] buf='}'
3637: file=tacdebug.conf line=42 sym=[}] buf='}'
3637: file=tacdebug.conf line=44 sym=[ruleset] buf='ruleset'
3637: file=tacdebug.conf line=44 sym=[{] buf='{'
3637: file=tacdebug.conf line=45 sym=[rule] buf='rule'
3637: file=tacdebug.conf line=45 sym=[<string>] buf='from-test'
3637: file=tacdebug.conf line=45 sym=[{] buf='{'
3637: file=tacdebug.conf line=46 sym=[script] buf='script'
3637: file=tacdebug.conf line=46 sym=[{] buf='{'
3637: file=tacdebug.conf line=47 sym=[if] buf='if'
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[group] buf='group'
3637: file=tacdebug.conf line=47 sym=[=] buf='='
3637: file=tacdebug.conf line=47 sym=[=] buf='='
3637: file=tacdebug.conf line=47 sym=[<string>] buf='testgroup'
3637: file=tacdebug.conf line=47 sym=[)] buf=')'
3637: file=tacdebug.conf line=47 sym=[{] buf='{'
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[(] buf='('
3637: file=tacdebug.conf line=47 sym=[group] buf='group'

Changing keyword from group to member fixes issue:

        ruleset {
                rule from-test {
                        script {
                                if (member == testgroup) {

this gives output and server works:

3662: file=tacdebug.conf line=37 sym=[<end-of-file>] buf=''
3662: file=tacdebug.conf line=37 sym=[<string>] buf='15'
3662: file=tacdebug.conf line=38 sym=[permit] buf='permit'
3662: file=tacdebug.conf line=39 sym=[}] buf='}'
3662: file=tacdebug.conf line=40 sym=[}] buf='}'
3662: file=tacdebug.conf line=41 sym=[}] buf='}'
3662: file=tacdebug.conf line=42 sym=[}] buf='}'
3662: file=tacdebug.conf line=44 sym=[ruleset] buf='ruleset'
3662: file=tacdebug.conf line=44 sym=[{] buf='{'
3662: file=tacdebug.conf line=45 sym=[rule] buf='rule'
3662: file=tacdebug.conf line=45 sym=[<string>] buf='from-test'
3662: file=tacdebug.conf line=45 sym=[{] buf='{'
3662: file=tacdebug.conf line=46 sym=[script] buf='script'
3662: file=tacdebug.conf line=46 sym=[{] buf='{'
3662: file=tacdebug.conf line=47 sym=[if] buf='if'
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[member] buf='member'
3662: file=tacdebug.conf line=47 sym=[=] buf='='
3662: file=tacdebug.conf line=47 sym=[=] buf='='
3662: file=tacdebug.conf line=47 sym=[<string>] buf='testgroup'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[{] buf='{'
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[(] buf='('
3662: file=tacdebug.conf line=47 sym=[member] buf='member'
3662: file=tacdebug.conf line=47 sym=[=] buf='='
3662: file=tacdebug.conf line=47 sym=[=] buf='='
3662: file=tacdebug.conf line=47 sym=[<string>] buf='testgroup'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[)] buf=')'
3662: file=tacdebug.conf line=47 sym=[<end-of-file>] buf=''
3662: 11:23:25.572 0/00000000: - normalized condition: ((((( member  = = testgroup)))))
3662: file=tacdebug.conf line=48 sym=[profile] buf='profile'
3662: file=tacdebug.conf line=48 sym=[=] buf='='
3662: file=tacdebug.conf line=48 sym=[<string>] buf='readwrite'
3662: file=tacdebug.conf line=49 sym=[permit] buf='permit'
3662: file=tacdebug.conf line=50 sym=[}] buf='}'
3662: file=tacdebug.conf line=51 sym=[deny] buf='deny'
3662: file=tacdebug.conf line=52 sym=[}] buf='}'
3662: file=tacdebug.conf line=53 sym=[}] buf='}'
3662: file=tacdebug.conf line=54 sym=[}] buf='}'
3662: file=tacdebug.conf line=55 sym=[}] buf='}'
3662: file=tacdebug.conf line=57 sym=[debug] buf='debug'
3662: file=tacdebug.conf line=57 sym=[=] buf='='
3662: file=tacdebug.conf line=57 sym=[ALL] buf='ALL'
3662: file=tacdebug.conf line=57 sym=[USERINPUT] buf='USERINPUT'
3662: file=tacdebug.conf line=58 sym=[<end-of-file>] buf=''
3662: 11:23:25.572 0/00000000: - Version 872afa5bc38267bd153b80f6bc0bbe4de467bed4 initialized

Issues here are:

  • documentation is misleading
  • config parser doesn't flag this config as invalid
  • server binary doesn't provide any feedback that it's not working

tac_plus or tac_plus-ng support dynamic keys

Hello.

I have a need to use unique keys for each individual host, at the moment I have to use freeradius with the dynamic-clients module (the keys are stored in the mysql database or in redis, and are compared relative to ip during authorization).
I would like a similar functionality in tac _plus, since the ability to share privileges is more convenient than in freeradius.
It is possible to consider a financial reward for this functionality.

p.s. sorry for bad english.

Best regards, Cryol.

tac_plus to docker logs

Hi,

I have the following in my configuration to write logs to stdout for them to be visible in docker logs as my tac_plus daemon runs in docker:

id = tac_plus {
  access log = /proc/1/fd/1
  accounting log = /proc/1/fd/1
  authorization log = /proc/1/fd/1

It works fine but timestamps are added to each entry:

2022-12-20 16:15:54 +0100	127.0.0.1	healthcheck	python_tty0	python_device	shell login succeeded
2022-12-20 16:15:54 +0100	127.0.0.1	healthcheck/INT_RO00_STANDARD_EXIT	python_tty0	python_device	permit	exit	
2022-12-20 16:15:54 +0100	127.0.0.1	healthcheck	python_tty0	python_device	start	heartbeat

What is the easiest way to get rid of those? Problem is that it messes up my syslog-parser when sending the docker logs via syslog to a collector.

Thanks a lot.

host condition missing in script

Hello Marc,

I was trying to set up this script:

rule two {
  enabled = yes
  script {
	if (member == admin ){
		profile = two
	}
	if (host == "10.1.2.3"){
		deny
	}
	permit
   }
}

But the parser is warning host is not a recognised filter.

Expected '(', '!', 'acl', 'time', 'arg', 'cmd', 'context', 'nac', 'nas', 'nas-name', 'nac-name', 'port', 'user', 'member', 'memberof', 'password', 'service', 'protocol', 'authen-action', 'authen-type', 'authen-service', 'authen-method', 'priv-lvl', 'vrf', 'dn', 'type', 'identity-source', 'tls-conn-version', 'tls-conn-cipher', 'tls-peer-cert-issuer', 'tls-peer-cert-subject', 'tls-conn-cipher-strength', 'tls-peer-cn' or 'tls-psk-identity', but got 'host'
52: Detected fatal configuration error. Exiting.

However, according to the railroad, it is. Actually the warning provides all filters present in the picture but host.
imaxe

Has been this option removed?

Thanks and regards.

tree_insert() allows duplicate entries, leading to usertable corruption and authentication failures

I recently noticed intermittent authentication failures that I tracked down to duplicate user entries in the usertable. For example, this mavis_lookup_final() logic often tries to add duplicates, which tree_insert() is intended to stop. The problem is that the duplicate checking doesn't happen until the new node is already positioned in the RB tree, by which time some duplicates could have already been missed. (e.g. insert A, B, A causes the duplicate A to be added).

Fortunately, the fix is simple -- just move the duplicate detection a few lines up to the positioning section. I'll submit a pull request.

/bin/sh: -v: command not found during make

Hi Mark,

We're experiencing multiple command not found errors when compiling (during make), maybe related to the following?

Makefile.inc:55
CCV = $(shell set $(CC); $$1 -v 2>&1)
CCV = $(shell set $(CC); -v 2>&1)

Excellent program BTW, thank you for your efforts.

Regards

tac_plus

Hello,
I think something wrong with the logic of password changing in case when I use shadow file as a backend.
When I force user to change the password during the next login:

test:$1$aINRlZ00$xqbEmgJNanAX.LhRiPVZZ/:1:1:0:99999:0:
Tacacs server is asking for password:

lst@lsts-MacBook-Pro ~ % ssh test@leaf3
(test@leaf3)
Hello user with ip: 192.168.11.110

Password:
(test@leaf3) Please change your password.
Old password:
Permission denied.

When I use the same password as it was before everything is fine, mavis_tacplus_shadow.pl is overwriting hash and lastChange in the users attributes in shadow file.

If it possible to fix it or not?

The password changing logic is broken

Hello Mark,

My Tacacs version is:
tac_plus-ng version cb3983dfac094e8e1aa39939c44ae2132cff1ee3/PCRE2
Before I faced an issue, I'd changed lastChange attribute to 0.
So the first time the server asked me to change the password. I canceled the dialogue and tried once again.
The second time I wasn't been asked to enter the new password.
OnPaste 20221214-151045

Regards,
Yaroslav

tac_plus-ng: Multiple External Authentication Sources ceased working since commit 193d7513a352ae7c70650fbdcba1002b982f9e2d

Multiple external module sources ceased working since the commit:

commit 193d7513a352ae7c70650fbdcba1002b982f9e2d (HEAD -> master)
Author: Marc Huber <[email protected]>
Date:   Mon Apr 17 18:01:40 2023 +0200

     mavis/tac_plus-ng/tac_plus: de-duplicate more script-related code

I have tested and used sucessfully multisource external module configuration (2x LDAP servers, PAM) till this problematic commit. Using multiple external sources with tac_plus-ng I have discussed with you here: tac_plus-ng: Multiple External Authentication Sources

My tested and worked configuration before applied the problematic commit:

    mavis module = external {
        script in {
            ### pass only specific usernames
            if ( $USER !~ /@fbe-test.local$/ )  {
                skip
            }
        }
        setenv LDAP_SERVER_TYPE = "microsoft"
        setenv LDAP_HOSTS = "test-ms-as.test:389"
        setenv LDAP_BASE = "dc=fbe-test,dc=local"
        setenv LDAP_USER = "[email protected]"
        setenv LDAP_PASSWD = *****
        setenv LDAP_FILTER = "(&(objectclass=user)(UserPrincipalName=%s))"
        setenv AD_GROUP_PREFIX = "tacacs_[-,a-z,A-Z,0-9]*_"
        setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
        exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
	}
	
    mavis module = external {
        script in {
			### pass only specific usernames
			if ( $USER !~ /@netw$/ )  {
				skip
            }
        }	
        setenv LDAP_SERVER_TYPE = "generic"	
        setenv LDAP_HOSTS = "test-openldap:389"
        setenv LDAP_BASE = "dc=netw"
        setenv LDAP_USER = "cn=manager,dc=netw"
        setenv LDAP_PASSWD = *****		
	setenv LDAP_FILTER = "(&(uid=%s))"
        setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
        setenv FLAG_USE_MEMBEROF = 1
        exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl	
	}
	
    mavis module = external {
        exec = /usr/local/sbin/pammavis pammavis -s sshd
	}	

Tacacs-ng h3c issue

Hi, Marc!
Could you please help me with the process of password changing on h3c.
As you can see tacacs-ng returns very strange replies to NAS in case of using h3c:

image

I've attached the log file from tacacs-ng server:
issue tacacs-ng debug.txt

Regards
D A

Command Authorization Failed

So I'm making good progress however seem to have hit another snag, Ive got an admin profile defined as per the below, now as I understand it that should allow all commands.

profile admin {
script {
if (service == shell) {
set priv-lvl = 15
permit
}
permit
}
}

I have a device that I can login to fine with tacacs however as soon as I enable command auth then all commands are denied

/dev/pts/1 cumulus deny shell nv config show

Below shows in /var/log/syslog that shows my user is properly mapped to the admin profile

shell login for 'testing' from 192.168.1.110 on ssh succeeded (profile=admin)

A bit stuck on where to look now again, the only other relevant log is again in /var/log/syslog with "192.168.1.194 Error 192.168.1.194: Illegal arg from NAS:"

groups_getlist() implementation of getgrouplist() doesn't match the libc implementation with sssd enabled

When sssd is enabled with default settings (sss is included for groups in /etc/nsswitch.conf and enumerate is set to False in /etc/sssd/sssd.conf), the libc implementation of getgrouplist() on Ubuntu 22.04 correctly returns all groups for a user. However, the mavis/groups.c implementation of this functionality in groups_getlist() does not. The reason is because it relies on getgrent() to iterate through all groups, which is presumably precluded by enumerate=False. Whereas the libc getgrouplist() function is able to return a user's groups without needing to enumerate all nonlocal groups.

Currently, I'm working around this by modifying misc/sysconf.h to unconditionally define these two symbols:

#define HAVE_GETGROUPLIST
#define GETGROUPLIST_ARG2_TYPE gid_t

It would be nice to be able to do this without modifying the code. One thought would be to change the #if 0 line in misc/sysconf.h that unconditionally disables HAVE_GETGROUPLIST, to something like #ifdef WITH_GETGROUPLIST. And then in configure, allow people to specify --with-getgrouplist to define that symbol. I'd be happy to submit a pull request if you want, let me know what you think.

config error

I updated my tac_plus to tac_plus_ng recently. When I used the old conf file, I got misstake like this:
group = g_en { default ../etc/tac_plus-ng.cfg.bak:43: Expected 'group' or 'parent', but got 'default' 61389: ../etc/tac_plus-ng.cfg.bak:43: Expected 'group' or 'parent', but got 'default' 61389: Detected fatal configuration error. Exiting.

i wanna how to convert configuration item below to new version
group = g_nen {
default service = permit
enable = deny
}

Thanks for your help

tac_plus-ng Illegal packet

Trying to test authenticating an ASAv in my lab and the only response I seem to be able to get from tac_plus-ng is an Illegal packet response, Ive captured and checked with wireshark and using the "Testing123" key that ive set I can decrypt the packet from the device to the tac_plus-ng server but the response from tac_plus show as a malformed packet.

40250: 16:16:06.381 0/9255de32: 192.168.1.44 New session
40250: 16:16:06.381 0/9255de32: 192.168.1.44 ------
40250: 16:16:06.381 0/9255de32: 192.168.1.44 key used: Testing123
40250: 16:16:06.381 0/9255de32: 192.168.1.44 version: 192, type: 1, seq no: 1, flags: unencrypted
40250: 16:16:06.381 0/9255de32: 192.168.1.44 session id: 32de5592, data length: 21
40250: 16:16:06.381 0/9255de32: 192.168.1.44 packet body (len: 21): \001\001\023\032Qk_��V�w��V0.��R
40250: 16:16:06.381 0/9255de32: 192.168.1.44 0000 01 01 13 1a 51 6b 5f ad a4 56 7e c1 77 e9 cc 56 ....Qk_. .V
.w..V
40250: 16:16:06.381 0/9255de32: 192.168.1.44 0010 30 2e 83 c9 52 0...R
40250: 16:16:06.381 0/9255de32: 192.168.1.44 Packet malformed, skipping detailed dump.
40250: 16:16:06.381 0/9255de32: 192.168.1.44 ------
40250: 16:16:06.381 0/9255de32: 192.168.1.44 192.168.1.44 (null): Illegal packet (version=0xc0 type=0x01)
40250: 16:16:06.381 0/9255de32: 192.168.1.44 Writing AUTHEN/ERROR size=57

Also if I use the example config here "https://www.pro-bono-publico.de/projects/unpacked/tac_plus-ng/sample/tac_plus-ng.cfg" and try and run tac_plus I get the error below thats after using the configure command of
"./configure --with-pcre2 tac_plus-ng"

"default.conf:35: You're using PCRE syntax, but this binary wasn't compiled with PCRE support.
41229: default.conf:35: You're using PCRE syntax, but this binary wasn't compiled with PCRE support.
41229: Detected fatal configuration error. Exiting."

configure tac_plus missing

Hello,
I get the following message when i configure with tac_plus option:
Development files were not found for: LIB-ARES, LIB-CURL, LIB-FREERADIUS, LIB-LWRES, LIB-PAM, LIB-PCRE2, LIB-RADCLI, LIB-SCTP, LIB-SSL, LIB-SSL_CRYPTO, LIB-TLS, LIB-ZLIB
Development files were found for: LIB-CRYPT, LIB-PCRE

My dist is Ubuntu 20.04
Linux host 5.4.0-122-generic #138-Ubuntu SMP Wed Jun 22 15:00:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

syslog format question

Hello, i have one question.

I did following configuration with latest commit from master branch for tac_plus-ng.

log dosyslog { 
        destination = 10.10.10.100:514
        syslog facility = local6
        syslog level = debug
        authentication format = "MARKER ${nas}|${user}|${port}|${nac}|${action} ${hint}"
}

authentication log = dosyslog

But I don't see on remote side | in syslog packets.
But if i change destination to destination = syslog in this case everything fine on local syslog.

Any hint of how solve my issue (I need to send logs just like tac_plus did) ?

Custom Logging destination in tac_plus

The documentation mentions custom logging destinations, but when I test the following with a freshly compiled binary, I get the following error:

scobb@tacacs-lab fakeroot]$ /usr/local/sbin/tac_plus -P -d 250  ~/tac_plus.cfg.2023 
###################################################
## THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY EDITED!
##
## This is the main configuration file for TACACS and uses a structure to load compononents
## in the proper order. The configuration is compartmentalized into seperate files to assist
## in keeping the structure intact over time with multiple administrators.


id = spawnd {
        listen = { port = 49 }
        spawn = {
                instances min = 1
                instances max = 10
        }
        background = yes
}

## BEGIN TACACS-SPECIFIC CONFIGURATION
id = tac_plus {

        ## access log appears to be the same as authentication log
        #access log = /var/log/tacacs/%Y/access-%Y-%m-%d.log


        #log separator = "\t"
        log = 
/home/scobb/tac_plus.cfg.2023:26: Expected 'separator', but got '='
7825: /home/scobb/tac_plus.cfg.2023:26: Expected 'separator', but got '='
7825: /home/scobb/tac_plus.cfg.2023:26: Expected 'separator', but got '='
7825: Detected fatal configuration error. Exiting.
7825: Detected fatal configuration error. Exiting.

It can parse the "log separator" line, and if I comment out the "log = " block, it can parse the config just fine.

is the custom destination still a feature? I was wanting to experiment with the RFC5424 format and send it to a host running fluentd.

The block it is trying to parse is:

        log = efkstack {
               destination = 10.0.0.1
               syslog compliance = RFC5424
               syslog facility = DAEMON
               syslog level = INFO
               log separator = "\t"
        }

Not able to use logging in tacacs-ng

Hi

When adding:
log authzlog { destination = /var/log/tac_plus/authz/%Y/%m/%d.log }
log authclog { destination = /var/log/tac_plus/authc/%Y/%m/%d.log }
log acctlog { destination = /var/log/tac_plus/acct/%Y/%m/%d.log }
accounting log = acctlog
authentication log = authclog
authorization log log = authzlog

to the config I get the following error message:
Invalid configuration file
7: /etc/tac_plus/tac_plus.cfg:16: Expected '=', but got 'log'
7: Detected fatal configuration error. Exiting.

authentication log configuration file issue

Hi,

I don’t seem to be able to complete the config line item for the authentication log specification.

 18     log authzlog { destination = /var/log/tac_plus/authz/%Y/%m/%d.log }
 19     log authclog { destination = /var/log/tac_plus/authc/%Y/%m/%d.log }
 20     log acctlog  { destination = /var/log/tac_plus/acct/%Y/%m/%d.log }
 21
 22     authentication log = authclog
 23     accounting log = acctlog
 24     authorization log = authzlog

When I start the process, the parser gives the following error message:

./tac_plus-ng.conf:22: Expected '=', but got 'log'

Am I overlooking something or could this be a bug?
(I’ve compiled on Debian 11.)

Thanks.

Cheers,
Jan

Local user and AD connection problem

Hello,
I've been trying to set up the Tac_plus-ng service for a few days now.
Unfortunately it's not working as expected. I've tried to consult all your documentation and forums to find a solution to my problem, but there's no way of solving it.

I tried to use your configuration available in the "MiniHowto tac_plus-ng" with modifications to match my Ad's information but it didn't work.

When I test the connection with this command :
/usr/local/bin/mavistest -d -1 /usr/local/etc/tac_plus-ng.cfg tac_plus-ng TAC_PLUS someusername
This one works: my user information is returned.

However, when I try to connect from a switch with a Tacacs+ configuration that should be functional (works with the basic tac_plus service).
I can't connect, here are the errors:

2023-06-14 08:47:31 -0400 (switch) demo tty1 (ip) shell login denied by ACL
2023-06-14 08:50:53 -0400 (switch) demo tty1 (ip) shell login denied by ACL
2023-06-14 09:11:11 -0400 (switch) demo tty1 (ip) shell login denied by ACL

Here is my configuration:

[09:13:54] root@tX:~# cat /usr/local/etc/tac_plus-ng.cfg
#!/usr/local/sbin/tac_plus-ng
id = spawnd {
        listen = { port = 49 }
        spawn = {
                instances min = 1
                instances max = 10
        }
        background = yes
}

id = tac_plus-ng {
        log connectlog {destination = /var/log/tac_plus/connecion.log}
        connection log = connectlog
        log accountlog {destination  = /var/log/tac_plus/accounting/%Y%m%d.log}
        log authlog {destination  = /var/log/tac_plus/authentication/%Y%m%d.log}
        log autorisationlog {destination  = /var/log/tac_plus/access/%Y%m%d.log}
        accounting log = accountlog
        authentication log = authlog
        authorization log = autorisationlog

        mavis module = external {
                setenv LDAP_SERVER_TYPE = "microsoft"
                setenv LDAP_HOSTS = "ldap://ip"
                setenv LDAP_BASE = "dc=x,dc=y,dc=z"
                setenv LDAP_USER = "[email protected]"
                setenv LDAP_PASSWD = "key"
                setenv TACACS_GROUP_PREFIX = ""
                setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
                setenv REQUIRE_TACACS_GROUP_PREFIX = 1
                exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
        }

#       login backend = mavis
#       user backend = mavis
#       pap backend = mavis

        host switch {
                address = ::/0
                welcome banner = "Welcome\n"
                key = x
        }

        profile admins {
                script {
                        if (service == shell) {
                                if (cmd == "")
                                        set priv-lvl = 15
                                permit
                        }
                }
        }

        group admins

        user X {
                password login = mavis
                member = admins
        }

        user demo {
                password login = clear demo
                member = admins
        }
}

I've tried to log in with the user 'demo' and the password 'demo' but it doesn't work, as the logs show.

I wanted to solve this problem first before considering logging in with my AD users.
I'm sorry if you've already answered this kind of question or documented it, but I did read your documentation and tried several different configurations but none of them gave me a positive result of a successful connection.

Thanks to you and thanks for this project which is really great.

Broken if-clause / external module inclusion since Apr., 17 2023 (193d7513)

We have a problem with the call of the externel radius request plugin based on the user login name.
The affected part of the tacacs config is:

        mavis module = external {
                script in  = { if ($USER !~ /^.*\@MYDOMAIN.*$/ ) skip }
                script out = {
                        if ($TYPE == TACPLUS) {
                                if ($TACTYPE == AUTH && $PASSWORD == $DBPASSWORD || $TACTYPE == INFO) {
                                        set $RESULT = ACK
                                        if ($USER =~ /^.*\@MYDOMAIN.*$/ ) {
                                                set $TACPROFILE = "{ member = MYDOMAIN_GROUP }"
                                        }
                                }
                        }
                }
                exec = /usr/local/sbin/radmavis radmavis "authserver=1.2.3.4:5678:mysecret"
        }

With the changes of 193d751 the application log returns:
...@MYDOMAIN ... shell login failed (no such user)
and there is no package being sent to the remote radius host.

With the state of previous d2f48d7 it successfully returns:
...@MYDOMAIN ... shell login succeeded

It seems like the if clause doesn't match anymore for some reason.
Unfortunately the debug logging does not give any hint about the processing or matching of the regex (level 1023).

The change statistics of the relevant commits are:

~/git/event-driven-servers$ git diff d2f48d7b 193d7513 --stat=80
 mavis/mavis.h         |  48 ++++++++++++-
 mavis/mavis_parse.c   | 184 +++++++++++++++-----------------------------------
 tac_plus-ng/config.c  | 151 ++++++++++-------------------------------
 tac_plus-ng/headers.h |   8 +--
 tac_plus/config.c     | 169 ++++++++++++++++++----------------------------
 5 files changed, 203 insertions(+), 357 deletions(-)

Tacacs-ng FortiGate issue

Hi, Marc!
It's me again.
Could you please help me with the process of password changing on FortiGate.
As you can see tacacs-ng is not returning replies:

image

I've attached the 2in1 config & log file from tacacs-ng server:
issue tacacs-ng debug FG.txt

Regards
D A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.