1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
libnss_tacplus v1.0.1
June 22, 2016
This NSS module has one and only one purpose. It allows getpwname lookups for
TACACS+ users that login without any
local account on the system (mapped to local tacacs0..15), when authenticated
with pam_tacplus. libnss_tacplus is not useful by itself. libnss_tacplus
uses libtacplus-map to lookup mappings, and libtac to communicate with TACACS+
servers.
libnss_tacplus provides only the getpwnam_r entry point, and uses
the libtac authenticate and accounting functions.
Normal use is to have tacplus as the last lookup method
for "passwd" in /etc/nsswitch.conf, although it will work
in any position:
passwd: compat tacplus
The above edit is made for debian packages via postinst at installation.
If the username is found, and is also found in the local password
file (via fgetpwent()), the local user passwd structure is returned
(that is, the plugin is basicly a NOP).
Otherwise, the plugin asks the TACACS+ server if the user is known, and then
asks for attributes, so it can determine the user's privilege level.
If the username is not found, a mapped lookup is performed using the
libtacplus_map.so exported functions. The lookup is done by the one or two
digit privilege level (0 by default) to "tacacs", and looking that name up
in the local password file; that is, privilege level 15 looks for local user
"tacacs15". If found, the password structure is filled in with the
information for that user, *except* that pw_name is filled in with the
original (login) name.
This code is based in the pam_tacplus plugin, written by
Pawel Krawczyk <pawel.krawczyk@hush.com> and Jeroen Nijhof
<jeroen@jeroennijhof.nl>, as well as others. It is based
on version pam_tacplus version 1.3.9. It uses the libtac
as found in pam_tacplus. A few minor changes have been made,
and libtac is built as a static archive library.
This library requires that the libpam_tacplus headers and shared libraries
be built and installed (my modified version, not the stock version) to
build, and to function.
All are performed using TACACS+ protocol [1], designed by Cisco Systems.
This is remote AAA protocol, supported by most Cisco hardware.
~~~~~~~~~~~~~~~~~~~
Recognized options in the configuration file are the same as the command line
arguments for libpam_tacplus, but not all pam_tacplus options are supported.
Option Description
--------------- ----------------------------------
debug output debugging information via
syslog(3); note, that the debugging
is heavy, including passwords!
secret=STRING can be specified more than once;
secret key used to encrypt/decrypt
packets sent/received from the server
server=HOSTNAME can be specified more than once;
server=IP_ADDR adds a TACACS+ server to the servers
list
default is 5 seconds
login=STRING TACACS+ authentication service,
this can be "pap", "chap" or "login"
at the moment. Default is pap.
service TACACS+ service for authorization
and accounting
protocol TACACS+ protocol for authorization
and accounting
min_uid min_uid is the minimum uid to lookup via tacacs.
Setting this to 0 means uid 0 (root) is never looked up,
good for robustness and performance.
Should not be greater than the local tacacs{0..15} uids
exclude_users This is a comma separated list of usernames that are never
looked up via tacacs. Should include system users such as
root.
The service and protocol items are widely described in TACACS+ draft [1].
They are required by the server, but it will work if they don't match the
real service authorized :)
See tacplus_nss.conf for an example configuration file.
See the libpam_tacplus README for more information on the tacacs
protocol, server_lists, etc.
On first call, we parse the configuration file (we only try once,
unless it can't be opened, in which case we'll keep trying on
every call). We then try to connect to a tacacs server.
After connecting we ask if the user is known (we send an authorization
request to the server). This function sends an encrypted packet to the
TACACS+ server. The packet contains username to verify. TACACS+ server
replied with either positive or negative response. If the reponse is
negative, the whole thing is over ;)
If the server responds that the user is valid (no authentication
exchange is done), we parse the returned attributes (if any)
looking for the privilege level (any string starting with "priv",
case independent), and then parse out the privilege level, and
construct the "tacacs##" username.
At this time, we make a new connection to the tacacs server on
every getpwnam_r(). Ideally, that would not be done, but it
appears that the linux tacplus server, at least, closes the
connection at it's end after the exchange, so subsequent requests
get SIGPIPE.
Limitations:
~~~~~~~~~~~~
This libnss_tacplus plugin has only been compiled and tested on
debian wheezy and jessie at this writing. The FreeBSD NSS interface
is somewhat different, and will require porting.
This plugin has only been tested with the unmodified linux tacacs+
server so far (using the debian wheezy package)
References:
~~~~~~~~~~~
TACACS+
1. ftp://ftpeng.cisco.com/pub/tacplus/tac_plus.rfc.1.76.txt
2. ftp://ftpeng.cisco.com/pub/tacplus/tac_plus.3.0.12.alpha.tar.Z
NSS plugin (glibc)
3. http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html
Author:
~~~~~~~
Dave Olson <olson@cumulusnetworks.com>
|