summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Olson <olson@cumulusnetworks.com>2016-11-26 16:02:10 -0800
committerDave Olson <olson@cumulusnetworks.com>2016-11-28 15:16:21 -0800
commitcc571f7356bb42c5360e0e40b786b5c9b75c3d95 (patch)
tree6a2714373e6e62e4f2d10839b445deedf8003c22
parent50884445bbe311a630c4cc899bd79a39ecf81e3b (diff)
downloadlibnss-tacplus-cc571f7356bb42c5360e0e40b786b5c9b75c3d95.tar.gz
libnss-tacplus-cc571f7356bb42c5360e0e40b786b5c9b75c3d95.zip
Fixed bug in exclude handling. Added sshd and "*" to exclusion list
It turns out that I broke the exclusion handling early on. It was only looking up the first entry in the list. In debugging this, it turns out that user sshd is also looked up quite frequently for ssh logins, so added it to the list, so that a round trip to the tacacs server isn't needed when logging in as a local user. There also isn't a need to look the exclusion list user up in the /etc/passwd file, just skip the tacacs lookup. Finally, it turns out that bash filename completion can lookup username "*" (a single asterisk). Add that to the exclusion list as well. The reason for these fixes is primarily for TACACS servers that are down or otherwise unreachable. With these fixes and additions, logging in over ssh with a username in the exclusion list is only slightly affected by unreachable TACACS servers. Finally, added a warning to not add TACACS+ secrets to the tacplus_nss.conf config file, since it is world readable.
-rw-r--r--nss_tacplus.c43
-rw-r--r--tacplus_nss.conf34
2 files changed, 21 insertions, 56 deletions
diff --git a/nss_tacplus.c b/nss_tacplus.c
index cdc2c47..75cbdb7 100644
--- a/nss_tacplus.c
+++ b/nss_tacplus.c
@@ -405,34 +405,6 @@ find_pw_user(const char *logname, const char *tacuser, struct pwbuf *pb)
}
/*
- * Similar to the functions above, but used for the exlusion list.
- * to exclude explict users like root, or specific UIDs (if name == NULL)
- * No warnings, since it's primarily for performance.
- * We could optimize this for programs that do lots of lookups by leaving
- * the passwd file open and rewinding, but it doesn't seem worthwhile.
- */
-static bool
-lookup_local(char *name, uid_t uid)
-{
- FILE *pwfile;
- struct passwd *ent;
- bool ret = 0;
- pwfile = fopen("/etc/passwd", "r");
-
- if(!pwfile)
- return 0;
-
- while(!ret && (ent = fgetpwent(pwfile))) {
- if(!ent->pw_name)
- continue; /* shouldn't happen */
- if((name && !strcmp(ent->pw_name, name)) || uid == ent->pw_uid)
- ret = 1;
- }
- fclose(pwfile);
- return ret;
-}
-
-/*
* we got the user back. Go through the attributes, find their privilege
* level, map to the local user, fill in the data, etc.
* Returns 0 on success, 1 on errors.
@@ -517,19 +489,16 @@ lookup_tacacs_user(struct pwbuf *pb)
char *user, *list;
list = strdup(exclude_users);
if (list) {
+ static const char *delim = ", \t\n";
bool islocal = 0;
- user = strtok(list, ",");
+ user = strtok(list, delim);
list = NULL;
- while (user && !strcmp(user, pb->name)) {
- if(debug)
- syslog(LOG_DEBUG, "%s: check user=(%s)", nssname, user);
- if ((islocal = lookup_local(user, 0))) {
- if (debug)
- syslog(LOG_DEBUG, "%s: exclude_users match (%s),"
- " no lookup", nssname, user);
+ while (user) {
+ if(!strcmp(user, pb->name)) {
+ islocal = 1;
break;
}
- user = strtok(list, ",");
+ user = strtok(NULL, delim);
}
free(list);
if (islocal)
diff --git a/tacplus_nss.conf b/tacplus_nss.conf
index 50d639b..502a037 100644
--- a/tacplus_nss.conf
+++ b/tacplus_nss.conf
@@ -4,15 +4,7 @@
# where tacplus precede compat (or files), and depending on local policy can
# follow or precede ldap, nis, etc.
# passwd: tacplus compat
-# The server keyword should follow the secret keyword, and may be
-# given fewer times than the server keyword, if all servers have the same
-# shared secret.
-# is matched up with first secret line, etc. You can use any of the
-# following orders, or most other orders you can think of. There must be at
-# least as many secret lines as there are server lines. This file should be
-# kept as permisions 644, owned by root, since it must be readable by arbitrary
-# processes, even though the secret for the TACACS+ server is present as clear
-# text.
+#
# Servers are tried in the order listed, and once a server
# replies, no other servers are attempted in a given process instantiation
#
@@ -31,14 +23,25 @@
# than the local tacacs{0..15} uids
min_uid=1001
-# This is a comma separated list of usernames that we never lookup via tacacs
-# Cumulus Linux ships with our standard users in the list.
-exclude_users=root,cumulus,quagga,ntp
+# This is a comma separated list of usernames that are never sent to
+# a tacacs server, they cause an early not found return.
+#
+# "*" is not a wild card. While it's not a legal username, it turns out
+# that during pathname completion, bash can do an NSS lookup on "*"
+# To avoid server round trip delays, or worse, unreachable server delays
+# on filename completion, we include "*" in the exclusion list.
+exclude_users=root,cumulus,quagga,sshd,ntp,*
# The include keyword allows centralizing the tacacs+ server information
# including the IP address and shared secret
include=/etc/tacplus_servers
+# The server IP address can be optionally followed by a ':' and a port
+# number (server=1.1.1.1:49). It is strongly recommended that you NOT
+# add secret keys to this file, because it is world readable.
+#secret=SECRET1
+#server=1.1.1.1
+
# The connection timeout for an NSS library should be short, since it is
# invoked for many programs and daemons, and a failure is usually not
# catastrophic. Not set or set to a negative value disables use of poll().
@@ -48,10 +51,3 @@ include=/etc/tacplus_servers
# as in tacplus_servers, since tacplus_servers should not be readable
# by users other than root.
timeout=5
-
-# The server IP address can be optionally followed by a ':' and a port
-# number (server=1.1.1.1:49).
-#secret=SECRET1
-#server=1.1.1.1
-#secret=SECRET2
-#server=1.1.1.2