tac_plus with Active Directory backend


  1. Have winbind working, i.e. `wbinfo -u` gives valid AD output
  2. Have winbind working with PAM, i.e. `getent passwd` gives a combined view of local and AD users in passwd format
  3. Solution is geared towards Debian, however you should be able use these instructions to get it working on non-debian distros

The problem

tac_plus can work with PAM backend, however:

  1. You still need to include every user in the `tac_plus.conf`, because you cannot define a default user directive for the PAM backend. In other words the "default authentication = PAM" which is expected to work does not, in tac_plus.conf
  2. Authorization, i.e. who belongs to which group is also hardcoded in the `tac_plus.conf` file.


We will solve problem .1 by using a patched version of tac_plus. And we will solve .2 by delegating authorization such as which group gets which permissions to an external script. BTW, we're talking about AD-groups here, not tac_plus.conf groups which should've been called templates and nothing else.)

Patched tac_plus

Get patched tacacs+ by cloning through git:
`$ git clone https://github.com/mkouhei/tacacs-plus.git`

Cd into the repo:
`$ cd tacacs-plus`

You can now do a debian build of the package (make sure you have all dependencies to use the dpkg-buildpackage):
`$ dpkg-buildpackage`

If all went well and you had every dependency correctly installed the .deb packages are now created one directory above, so
`$ cd ..`

you can install the packages with:
`$ dpkg -i libtacacs+1_4.* tacacs+_4.*`

Setting up tac_plus.conf

To make authentication possible for AD users, we don't want to add every user which should have access to your tacacs-enabled devices to be added to the conf file, because - why would we want double administration if the info is already in AD.

So our approach is as follows: We authenticate every domain user by doing the following in tac_plus.conf and then check if the user is in a specific AD group

Let every PAM user authenticate

default authentication = PAM

Check this by restarting the tacacs+ service, if it succeeds you verified your patched tacacs+ version is working

Check if the authentication is valid in PAM

default authentication = PAM
user = DEFAULT  {
    login = PAM
    before authorization "/etc/tacacs+/authorization.sh '$user'"

the $user is supplied by tacacs+, check the manual for other variables if you'd need them.

Check the authorization

TACACSGROUP="your TACACS Group name"
userSid=$($WBINFO -n$user |cut -f1)
userGroupsSid=$($WBINFO --user-domgroups=$userSid)
for i in $userGroupsSid
        groupName=$($WBINFO -s $i)
        # very strange artifect in wbinfo SID->names, there's a trailing '2'
        if [ "$groupName" = "$DOMAIN\\$TACACSGROUP 2" ] || [ "$groupName" = "$TACACSGROUP 2" ]; then
                in=$(cat /dev/stdin)
                echo "$in"
                echo priv-lvl=15
                exit 2
exit 1

Now this example show what you can do if you have 1 group, however nothing stops you from adding more if-statements, and adding appropriate extra attribute-value pairs, like the `echo priv-lvl=15`, shown in the example.
You should read up on the man page for tac_plus.conf under the heading `authorization scripts`. Some notes

  1. exit code 2, signals that the user is authorized and that we will change some attribute-values
  2. exit code 1, signals that the user is not authorized
  3. if we were to change exit code 2 to 0, then it signals that the user is authorized, but any changes given through attribute-values are not picked up / discarded, by tac_plus.


Finally got around doing this myself, thanks for the pointers