Rework against upstream version F4.0.4.28

- No longer need tacacs+/tacacs+6 split
- Change package name to 'tacacs' to make autoconf happy
- Port in changes from previous version
This commit is contained in:
JJ Crawford 2018-06-12 22:18:52 -07:00
parent ff94901988
commit 6aa67cba1c
112 changed files with 93724 additions and 47265 deletions

View File

@ -1,5 +1,5 @@
Project: tacacs+
Version: 4.0.19-fb
Version: 4.0.28-fb
Release date: 20140530
Website:
License: Cisco

View File

@ -20,28 +20,26 @@ RPMS Build on CentOS 7 x86_64 + SRC rpms avaliable here: http://cooperlees.com/r
- Syslog Logging
## Default Behavior
There are two spec files tested in CentOS 6. tacacs+6 depends on tacacs+ in order to not duplicate libraries etc.
- tacacs+ logs accounting to syslog and /var/log/tac_plus.acct
- tacacs+6 logs accounting to syslog and /var/log/tac_plus6.acct
- PIDS live in /var/run/tac_plus[6]
- Each binary binds to all addresses for its address family (AF_INET: 0.0.0.0 or AF_INET6: ::)
-- This is controlled in the unit file
- PIDS live in /var/run/tac_plus
## INSTALLING
Buid from source (./configure ; make ; make install)
- For IPv6 you will need CFLAGS="-DIPV6":
Build from source (./configure ; make ; make install)
or build an RPM
- rpmbuild -ba tacacs+[6].spec
-- tacacs+6 requires tacacs+ for libraries with default specfiles (easily changeable if you want IPV6 only)
- rpmbuild -ba tacacs.spec
Build from upstream source
- Grab 4.0.4.28 from Shrubbery (ftp://ftp.shrubbery.net/pub/tac_plus)
- Apply patches in patches/F4.0.4.28
- Run 'autoreconf' in source directory (this requires autoconf tools)
- Proceed with either building from source or building the RPM
### RPM Build
- git clone git@github.com:facebook/tac_plus.git
- cd tac_plus
- mkdir -p ~/rpmbuild/SOURCES
- tar cvzf ~/rpmbuild/SOURCES/tacacs+-FB4.0.4.19.1.tar.gz tacacs+-FB4.0.4.19.1
- tar cvzf ~/rpmbuild/SOURCES/tacacs-F4.0.4.28.tar.gz tacacs-F4.0.4.28
- echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
- sudo yum install rpm-build redhat-rpm-config gcc bison flex m4 pam-devel tcp_wrappers tcp_wrappers-devel
- rpmbuild -ba tacacs+.spec
- rpmbuild -ba tacacs+6.spec
- rpmbuild -ba tacacs.spec
- Have a beer

View File

@ -0,0 +1,58 @@
diff -u tacacs-F4.0.4.28-orig/default_fn.c tacacs-F4.0.4.28/default_fn.c
--- tacacs-F4.0.4.28-orig/default_fn.c 2012-06-11 09:01:45.000000000 -0700
+++ tacacs-F4.0.4.28/default_fn.c 2018-05-21 13:42:00.273620000 -0700
@@ -75,6 +75,8 @@
{
struct private_data *p;
char *name = data->NAS_id->username;
+ char *clientip = ((data->NAS_id->NAC_address) && data->NAS_id->NAC_address[0]) ?
+ data->NAS_id->NAC_address : "unknown";
p = (struct private_data *) data->method_data;
@@ -196,23 +198,32 @@
switch (data->status) {
case TAC_PLUS_AUTHEN_STATUS_ERROR:
- return(0);
+ return(0);
case TAC_PLUS_AUTHEN_STATUS_FAIL:
- if (session.peer)
- report(LOG_NOTICE, "login failure: %s %s (%s) %s",
- name == NULL ? "unknown" : name,
- session.peer, session.peerip, session.port);
- else
- report(LOG_NOTICE, "login failure: %s %s %s",
- name == NULL ? "unknown" : name,
- session.peerip, session.port);
+ if (session.peer)
+ report(LOG_NOTICE, "login failure: user=%s device=%s ip=%s port=%s client=%s",
+ name == NULL ? "unknown" : name,
+ session.peer, session.peerip, session.port, clientip);
+ else
+ report(LOG_NOTICE, "login failure: user=%s device=%s port=%s",
+ name == NULL ? "unknown" : name,
+ session.peerip, session.port);
+ return(0);
case TAC_PLUS_AUTHEN_STATUS_PASS:
- return(0);
+ if (session.peer)
+ report(LOG_NOTICE, "login success: user=%s device=%s ip=%s port=%s client=%s",
+ name == NULL ? "unknown" : name,
+ session.peer, session.peerip, session.port, clientip);
+ else
+ report(LOG_NOTICE, "login failure: user=%s device=%s port=%s",
+ name == NULL ? "unknown" : name,
+ session.peerip, session.port);
+ return(0);
default:
- report(LOG_ERR, "%s %s: default_fn set bogus status value %d",
- session.peer, session.port, data->status);
- data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
+ report(LOG_ERR, "%s %s: default_fn set bogus status value %d",
+ session.peer, session.port, data->status);
+ data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
return(0);
}
}

View File

@ -0,0 +1,89 @@
diff -u tacacs-F4.0.4.28-orig/pwlib.c tacacs-F4.0.4.28/pwlib.c
--- tacacs-F4.0.4.28-orig/pwlib.c 2013-08-01 09:05:20.000000000 -0700
+++ tacacs-F4.0.4.28/pwlib.c 2018-05-21 13:42:00.668605000 -0700
@@ -50,7 +50,7 @@
static int etc_passwd_file_verify(char *, char *, struct authen_data *);
static int des_verify(char *, char *);
#if HAVE_PAM
-static int pam_verify(char *, char *);
+static int pam_verify(char *, char *, struct authen_data *data);
#endif
static int passwd_file_verify(char *, char *, struct authen_data *, char *);
@@ -157,7 +157,7 @@
#if HAVE_PAM
if (strcmp(cfg_passwd, "PAM") == 0) {
/* try to verify the password via PAM */
- if (!pam_verify(name, passwd)) {
+ if (!pam_verify(name, passwd, data)) {
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return(0);
} else
@@ -596,9 +596,10 @@
* return 1 if verified, 0 otherwise.
*/
static int
-pam_verify(char *user, char *passwd)
+pam_verify(char *user, char *passwd, struct authen_data *data)
{
int err;
+ int acct;
int pam_flag;
struct pam_conv conv = { pam_tacacs, passwd };
pam_handle_t *pamh = NULL;
@@ -625,15 +626,47 @@
switch ((err = pam_authenticate(pamh, pam_flag))) {
case PAM_SUCCESS:
- pam_end(pamh, err);
- if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "pam_verify returns 1");
- return(1);
- break;
+ switch((acct = pam_acct_mgmt(pamh, pam_flag))) {
+ case PAM_SUCCESS:
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "pam_acct_mgmt returns PAM_SUCCESS");
+ pam_end(pamh, err);
+ if (debug & DEBUG_PASSWD_FLAG)
+ report (LOG_DEBUG, "pam_verify returns 1");
+ return(1);
+ break;
+ case PAM_NEW_AUTHTOK_REQD:
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "pam_acct_mgmt returns PAM_NEW_AUTHTOK_REQD");
+ if (data->server_msg)
+ free(data->server_msg);
+ data->server_msg = tac_strdup("Password will expire soon, please change it immediately");
+ break;
+ case PAM_AUTHTOK_EXPIRED:
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "pam_acct_mgmt returns PAM_AUTHTOK_EXPIRED");
+ if (data->server_msg)
+ free(data->server_msg);
+ data->server_msg = tac_strdup("Password has expired");
+ break;
+ case PAM_ACCT_EXPIRED:
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "pam_acct_mgmt returns PAM_ACCT_EXPIRED");
+ if (data->server_msg)
+ free(data->server_msg);
+ data->server_msg = tac_strdup("Account has expired");
+ break;
+ default:
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "pam_account_mgmt returned unknown value %d",
+ acct);
+ break;
+ }
+ break;
case PAM_USER_UNKNOWN:
- if (debug & DEBUG_PASSWD_FLAG)
- report(LOG_DEBUG, "Unknown user");
- break;
+ if (debug & DEBUG_PASSWD_FLAG)
+ report(LOG_DEBUG, "Unknown user");
+ break;
case PAM_AUTH_ERR:
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "Password is incorrect");

View File

@ -0,0 +1,815 @@
diff -u tacacs-F4.0.4.28-orig/config.c tacacs-F4.0.4.28/config.c
--- tacacs-F4.0.4.28-orig/config.c 2012-06-06 15:11:30.000000000 -0700
+++ tacacs-F4.0.4.28/config.c 2018-05-24 14:26:31.315047000 -0700
@@ -42,7 +42,9 @@
accounting file = <filename> |
accounting syslog |
key = <string> |
- logging = <syslog_fac>
+ logging = <syslog_fac> |
+ maxprocs = <maxprocs> |
+ maxprocsperclt = <maxprocsperclt>
<authen_default> := default authentication = file <filename>
@@ -132,6 +134,11 @@
static int sym_error = 0; /* a parsing error occurred */
static char *authen_default = NULL; /* top level authentication default */
static char *nopasswd_str = "nopassword";
+static long int maxprocs = TAC_MAX_PROCS; /* max procs to fork */
+static long int maxprocsperclt = TAC_MAX_PROCS_PER_CLIENT; /* max per client */
+static long int readtimeout = TAC_PLUS_READ_TIMEOUT; /* read timeout */
+static long int writetimeout = TAC_PLUS_WRITE_TIMEOUT; /* write timeout */
+static long int accepttimeout = TAC_PLUS_ACCEPT_TIMEOUT; /* accept timeout */
/*
* A host definition structure.
@@ -822,6 +829,66 @@
sym_get();
continue;
+ case S_maxprocs:
+ parse(S_maxprocs);
+ parse(S_separator);
+ errno = 0;
+ maxprocs = strtol(tac_strdup(sym_buf), NULL, 10);
+ if ((errno) || (maxprocs < 0)) {
+ parse_error("maxprocs must a valid positive integer");
+ return 1;
+ }
+ sym_get();
+ continue;
+
+ case S_maxprocsperclt:
+ parse(S_maxprocsperclt);
+ parse(S_separator);
+ errno = 0;
+ maxprocsperclt = strtol(tac_strdup(sym_buf), NULL, 10);
+ if ((errno) || (maxprocsperclt < 0)) {
+ parse_error("maxprocsperclt must a valid positive integer");
+ return 1;
+ }
+ sym_get();
+ continue;
+
+ case S_readtimeout:
+ parse(S_readtimeout);
+ parse(S_separator);
+ errno = 0;
+ readtimeout = strtol(tac_strdup(sym_buf), NULL, 10);
+ if ((errno) || (readtimeout < 0)) {
+ parse_error("readtimeout must a valid positive integer");
+ return 1;
+ }
+ sym_get();
+ continue;
+
+ case S_writetimeout:
+ parse(S_writetimeout);
+ parse(S_separator);
+ errno = 0;
+ writetimeout = strtol(tac_strdup(sym_buf), NULL, 10);
+ if ((errno) || (writetimeout < 0)) {
+ parse_error("writetimeout must a valid positive integer");
+ return 1;
+ }
+ sym_get();
+ continue;
+
+ case S_accepttimeout:
+ parse(S_accepttimeout);
+ parse(S_separator);
+ errno = 0;
+ accepttimeout = strtol(tac_strdup(sym_buf), NULL, 10);
+ if ((errno) || (accepttimeout < 0)) {
+ parse_error("accepttimeout must a valid positive integer");
+ return 1;
+ }
+ sym_get();
+ continue;
+
case S_host:
parse_host();
continue;
@@ -2156,7 +2223,7 @@
return(cfg_get_pvalue(user, TAC_IS_USER, S_login, recurse));
}
-#ifdef UENABLE
+#ifdef UENABLE
/*
* return value of the noenablepwd field. If none, try groups the user is a
* member of, and so on, recursively if recurse is non-zero.
@@ -2462,6 +2529,36 @@
}
}
+int
+cfg_get_maxprocs(void)
+{
+ return(maxprocs);
+}
+
+int
+cfg_get_maxprocsperclt(void)
+{
+ return(maxprocsperclt);
+}
+
+int
+cfg_get_readtimeout(void)
+{
+ return(readtimeout);
+}
+
+int
+cfg_get_writetimeout(void)
+{
+ return(writetimeout);
+}
+
+int
+cfg_get_accepttimeout(void)
+{
+ return(accepttimeout);
+}
+
char *
cfg_get_authen_default(void)
{
diff -u tacacs-F4.0.4.28-orig/hash.c tacacs-F4.0.4.28/hash.c
--- tacacs-F4.0.4.28-orig/hash.c 2009-07-30 11:17:55.000000000 -0700
+++ tacacs-F4.0.4.28/hash.c 2018-05-24 15:04:21.730920000 -0700
@@ -20,6 +20,9 @@
*/
#include "tac_plus.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
struct entry {
char *name;
@@ -27,22 +30,16 @@
};
typedef struct entry ENTRY;
-static int calculate_hash(char *);
-
-/* Calculate hash value from a string */
-static int
+/* djb hashing function */
+static unsigned long
calculate_hash(char *name)
{
- int i;
- int len = strlen(name);
- int hashval = 0;
+ unsigned long hash = 5381;
+ int c;
- for (i = 0; i < len; i++) {
- hashval += name[i] * (i + 1);
- }
- hashval += name[0];
- hashval = hashval > 0 ? hashval : -hashval;
- return(hashval);
+ while (c = *name++)
+ hash = ((hash >> 5) + hash) + c; /* hash * 33 + c */
+ return hash;
}
/* Lookup a name in a hash table. Return its node if it exists, else NULL */
@@ -50,15 +47,15 @@
hash_lookup(void **hashtab, char *name)
{
ENTRY *entry;
- int hashval = calculate_hash(name);
-
- entry = hashtab[hashval % HASH_TAB_SIZE];
+ unsigned long hashval = calculate_hash(name);
+ int hashslot = hashval % HASH_TAB_SIZE;
+ entry = hashtab[hashslot];
while (entry) {
- if (STREQ(name, entry->name))
+ if (STREQ(name, entry->name))
/* Node exists in table. return it */
- return(entry);
- entry = entry->hash;
+ return(entry);
+ entry = entry->hash;
}
return(NULL);
}
@@ -68,19 +65,55 @@
hash_add_entry(void **hashtab, struct entry *newentry)
{
ENTRY *entry;
- int hashval;
+ unsigned long hashval;
+ int hashslot;
entry = hash_lookup(hashtab, newentry->name);
if (entry)
- return(entry);
+ return(entry);
/* Node does not exist in table. Add it */
hashval = calculate_hash(newentry->name);
- newentry->hash = hashtab[hashval % HASH_TAB_SIZE];
- hashtab[hashval % HASH_TAB_SIZE] = newentry;
+ hashslot = hashval % HASH_TAB_SIZE;
+ newentry->hash = hashtab[hashslot];
+ hashtab[hashslot] = newentry;
return(NULL);
}
+void * hash_delete_entry(void **hashtab, char *entry_name) {
+ ENTRY *entry;
+ ENTRY *tentry;
+ unsigned long hashval = calculate_hash(entry_name);
+ int hashslot = hashval % HASH_TAB_SIZE;
+ struct entry *last_entry = NULL;
+
+ entry = hashtab[hashslot];
+ while (entry) {
+ if (STREQ(entry_name, entry->name)) {
+ if ((last_entry == NULL) && (entry->hash == NULL)) {
+ /* the hash slot is empty so we can set it to null */
+ hashtab[hashslot] = NULL;
+ } else if ((last_entry != NULL) && (entry->hash != NULL)) {
+ /* we need to attach the previous entry to the next one
+ * so we can remove this one */
+ last_entry->hash = entry->hash;
+ } else if (last_entry == NULL) {
+ /* first entry so we need to advance the hash slot to the next one*/
+ hashtab[hashslot] = entry->hash;
+ } else if (entry->hash == NULL) {
+ /* last entry in bucket so we need to null the next pointer in the previous entry */
+ last_entry->hash = NULL;
+ }
+ entry->hash = NULL;
+ return entry;
+ }
+ last_entry = entry;
+ entry = entry->hash;
+ }
+ /* we didn't find the entry */
+ return NULL;
+}
+
/* Return an array of pointers to all the entries in a hash table */
void **
hash_get_entries(void **hashtab)
diff -u tacacs-F4.0.4.28-orig/Makefile.am tacacs-F4.0.4.28/Makefile.am
--- tacacs-F4.0.4.28-orig/Makefile.am 2014-12-29 15:38:56.000000000 -0800
+++ tacacs-F4.0.4.28/Makefile.am 2018-05-24 14:19:35.805801000 -0700
@@ -10,8 +10,8 @@
bin_PROGRAMS = tac_pwd
sbin_PROGRAMS = tac_plus
tac_pwd_SOURCES = tac_pwd.c
-tac_plus_SOURCES = acct.c authen.c author.c choose_authen.c config.c \
- default_fn.c default_v0_fn.c do_acct.c do_author.c dump.c enable.c \
+tac_plus_SOURCES = acct.c authen.c author.c choose_authen.c client_count.c \
+ config.c default_fn.c default_v0_fn.c do_acct.c do_author.c dump.c enable.c \
encrypt.c expire.c hash.c maxsessint.c parse.c programs.c pw.c pwlib.c \
report.c sendauth.c sendpass.c tac_plus.c utils.c
if TACSKEY
@@ -95,4 +95,3 @@
rm -f users_guide users_guide.tmp; \
$(auto_edit) $(srcdir)/users_guide.in >users_guide.tmp; \
mv users_guide.tmp users_guide
-
diff -u tacacs-F4.0.4.28-orig/tacacs.h tacacs-F4.0.4.28/tacacs.h
--- tacacs-F4.0.4.28-orig/tacacs.h 2013-08-04 06:51:47.000000000 -0700
+++ tacacs-F4.0.4.28/tacacs.h 2018-05-24 14:58:35.469663000 -0700
@@ -29,10 +29,11 @@
#define TAC_PLUS_PORTSTR "49"
#endif
-#define TAC_PLUS_READ_TIMEOUT 180 /* seconds */
-#define TAC_PLUS_WRITE_TIMEOUT 180 /* seconds */
-#define TAC_PLUS_ACCEPT_TIMEOUT 15 /* seconds */
-
+#define TAC_PLUS_READ_TIMEOUT 180 /* seconds */
+#define TAC_PLUS_WRITE_TIMEOUT 180 /* seconds */
+#define TAC_PLUS_ACCEPT_TIMEOUT 180 /* seconds */
+#define TAC_MAX_PROCS 1024
+#define TAC_MAX_PROCS_PER_CLIENT 32
/*
* All tacacs+ packets have the same header format
*
@@ -341,7 +342,7 @@
extern char *wtmpfile;
extern int wtmpfd;
-#define HASH_TAB_SIZE 157 /* user and group hash table sizes */
+#define HASH_TAB_SIZE 65539 /* user and group hash table sizes */
struct acct {
u_char flags;
diff -u tacacs-F4.0.4.28-orig/tac_plus.c tacacs-F4.0.4.28/tac_plus.c
--- tacacs-F4.0.4.28-orig/tac_plus.c 2014-12-30 11:58:49.000000000 -0800
+++ tacacs-F4.0.4.28/tac_plus.c 2018-05-24 14:53:45.317635000 -0700
@@ -60,6 +60,9 @@
int wtmpfd; /* for wtmp file logging */
char *opt_Q;
char *opt_U;
+int total_child_count = 0;
+volatile sig_atomic_t dump_client_table = 0;
+volatile sig_atomic_t reap_children = 0;
char *wtmpfile = NULL;
char *bind_address = NULL;
@@ -69,6 +72,8 @@
#define PIDSZ 75
static char pidfilebuf[PIDSZ]; /* holds current name of the pidfile */
+#define MSGBUFSZ 1024
+static char msgbuf[MSGBUFSZ];
static RETSIGTYPE die(int);
static int get_socket(int **, int *);
@@ -131,31 +136,49 @@
#endif
}
+static RETSIGTYPE
+dump_clients_handler(int signum)
+{
+ dump_client_table = 1;
+#ifdef REARMSIGNAL
+ signal(SIGUSR2, dump_clients_handler);
+#endif
+}
+
#if defined(REAPCHILD) && defined(REAPSIGIGN)
-static
+
RETSIGTYPE
reapchild(int notused)
{
+ reap_children = 1;
+}
+#endif
+void
+reapchildren()
+{
#ifdef UNIONWAIT
- union wait status;
+ union wait status;
#else
- int status;
+ int status;
#endif
#if HAVE_PID_T
- pid_t pid;
+ pid_t pid;
#else
- int pid;
+ int pid;
#endif
+ int procs_for_client;
- for (;;) {
- pid = wait3(&status, WNOHANG, 0);
- if (pid <= 0)
- return;
- if (debug & DEBUG_FORK_FLAG)
- report(LOG_DEBUG, "%ld reaped", (long)pid);
- }
+ for (;;) {
+ pid = waitpid(-1, &status, WNOHANG);
+ if (pid <= 1)
+ return;
+ snprintf(msgbuf, MSGBUFSZ, "Clening up session for pid %lu", pid);
+ report(LOG_DEBUG, msgbuf);
+ procs_for_client = decrement_client_count_for_proc(pid);
+ total_child_count--;
+ }
+ reap_children = 0;
}
-#endif /* REAPCHILD */
/*
* Return a socket bound to an appropriate port number/address. Exits
@@ -294,6 +317,9 @@
memset(&session, 0, sizeof(session));
session.peer = tac_strdup("unknown");
+#if defined(REAPCHILD) && defined(REAPSIGIGN)
+ client_count_init();
+#endif
open_logfile();
if (argc <= 1) {
@@ -380,6 +406,7 @@
signal(SIGUSR1, handler);
signal(SIGHUP, handler);
+ signal(SIGUSR2, dump_clients_handler);
signal(SIGTERM, die);
signal(SIGPIPE, SIG_IGN);
@@ -624,10 +651,22 @@
socklen_t from_len;
int newsockfd = -1;
int flags, status;
+ int procs_for_client;
+
+#if defined(REAPCHILD) && defined(REAPSIGIGN)
+ if (reap_children)
+ reapchildren();
+#endif
if (reinitialize)
init();
+ if (dump_client_table) {
+ report(LOG_ALERT, "Dumping Client Tables");
+ dump_client_tables();
+ dump_client_table = 0;
+ }
+
status = poll(pfds, ns, TAC_PLUS_ACCEPT_TIMEOUT * 1000);
if (status == 0)
continue;
@@ -678,11 +717,32 @@
session.peer, newsockfd);
if (!single) {
+#if defined(REAPCHILD) && defined(REAPSIGIGN)
+ /* first we check the tocal process count to see if we are at the limit */
+ if (total_child_count >= cfg_get_maxprocs()) {
+ report(LOG_ALERT, "refused connection from %s [%s] at global max procs [%d]",
+ session.peer, session.peerip, total_child_count);
+ shutdown(newsockfd, 2);
+ close(newsockfd);
+ continue;
+ }
+ /* no we check the process count per client */
+ procs_for_client = get_client_count(session.peerip);
+ report(LOG_ALERT, "connection [%d] from %s [%s]", procs_for_client + 1, session.peer, session.peerip);
+ if (procs_for_client >= cfg_get_maxprocsperclt()) {
+ report(LOG_ALERT, "refused connection from %s [%s] at client max procs [%d]",
+ session.peer, session.peerip, procs_for_client);
+ shutdown(newsockfd, 2);
+ close(newsockfd);
+ continue;
+ }
+#endif
+
pid = fork();
if (pid < 0) {
- report(LOG_ERR, "fork error");
- tac_exit(1);
+ report(LOG_ERR, "fork error");
+ tac_exit(1);
}
} else {
pid = 0;
@@ -723,6 +783,13 @@
if (debug & DEBUG_FORK_FLAG)
report(LOG_DEBUG, "forked %ld", (long)pid);
/* parent */
+#if defined(REAPCHILD) && defined(REAPSIGIGN)
+ total_child_count++;
+ procs_for_client = increment_client_count_for_proc(pid, session.peerip);
+ snprintf(msgbuf, MSGBUFSZ, "forked %lu for %s, procs %d, procs for client %d",
+ (long)pid, session.peerip, total_child_count, procs_for_client);
+ report(LOG_DEBUG, msgbuf);
+#endif
close(newsockfd);
}
}
diff -u tacacs-F4.0.4.28-orig/tac_plus.h tacacs-F4.0.4.28/tac_plus.h
--- tacacs-F4.0.4.28-orig/tac_plus.h 2012-04-10 12:38:45.000000000 -0700
+++ tacacs-F4.0.4.28/tac_plus.h 2018-05-24 14:57:35.983468000 -0700
@@ -217,7 +217,7 @@
extern char *wtmpfile;
extern int wtmpfd;
-#define HASH_TAB_SIZE 157 /* user and group hash table sizes */
+#define HASH_TAB_SIZE 65539 /* user and group hash table sizes */
struct acct {
u_char flags;
@@ -361,9 +361,38 @@
/* hash.c */
struct entry;
void *hash_add_entry(void **, struct entry *);
+void *hash_update_entry(void**, struct entry *);
+void *hash_delete_entry(void**, char *);
void **hash_get_entries(void **);
void *hash_lookup(void **, char *);
+/* client_count.c */
+void client_count_init(void);
+int get_client_count(char* client_ip);
+int increment_client_count(char*);
+int decrement_client_count(char*);
+int decrement_client_count_for_proc(pid_t);
+int increment_client_count_for_proc(pid_t, char *);
+void remove_client_entry(char*);
+void remove_proc_entry(char*);
+void create_proc_client_map(pid_t, char*);
+void delete_proc_client_map(pid_t);
+void dump_client_tables();
+
+struct client_st {
+ char *name; /* host name */
+ void *hash; /* hash table next pointer */
+ int con_count; /* count of connections from this peer */
+};
+typedef struct client_st CLIENT;
+
+struct proc_st {
+ char *name; /* host name */
+ void *hash; /* hash table next pointer */
+ char *client_ip; /* client ipv4 or ipv6 address */
+};
+typedef struct proc_st PROC_CLIENT;
+
/* config.c */
#ifdef ACLS
int cfg_acl_check(char *, char *);
--- tacacs-F4.0.4.28-orig/client_count.c 1969-12-31 16:00:00.000000000 -0800
+++ tacacs-F4.0.4.28/client_count.c 2018-05-24 14:17:13.000000000 -0700
@@ -0,0 +1,178 @@
+#include "tac_plus.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#define MSGBUFSZ 1024
+static char msgbuf[MSGBUFSZ];
+static void *client_table[HASH_TAB_SIZE]; /* Table of client declarations */
+static void *proc_table[HASH_TAB_SIZE]; /* Table of proc declarations */
+
+/* initialize the client table proc tables
+ * The client table stores the number of connections for
+ * each client ip.
+ * The proc table stores the link between process id and
+ * client ip. When a tacacs process dies, the parent only
+ * get the process id, so we need to link the two */
+
+void client_count_init(void) {
+ memset(proc_table, 0, sizeof(proc_table));
+ memset(client_table, 0, sizeof(client_table));
+}
+
+void remove_client_entry(char* client_ip)
+{
+ CLIENT *entry = (CLIENT *)hash_delete_entry(client_table, client_ip);
+ if (entry) {
+ if (entry->name)
+ free(entry->name);
+ free(entry);
+ }
+}
+
+void remove_proc_entry(char* proc_id)
+{
+ PROC_CLIENT *entry = (PROC_CLIENT *)hash_delete_entry(proc_table, proc_id);
+ if (entry) {
+ if (entry->name)
+ free(entry->name);
+ if (entry->client_ip)
+ free(entry->client_ip);
+ free(entry);
+ }
+}
+
+/* Map a process id to client IP address */
+void create_proc_client_map(pid_t process_id, char* client_ip)
+{
+ /* max size of a 64bit number is 19 chars */
+ char pid_str[20];
+ snprintf(pid_str, 20, "%d", process_id);
+ PROC_CLIENT *pc = (PROC_CLIENT *)tac_malloc(sizeof(PROC_CLIENT));
+ memset(pc, 0, sizeof(PROC_CLIENT));
+ pc->name = tac_strdup(pid_str);
+ pc->hash = NULL;
+ pc->client_ip = tac_strdup(client_ip);
+ hash_add_entry(proc_table, (void*)pc);
+}
+
+/* delete the mapping between process id and IP address */
+void delete_proc_client_map(pid_t process_id)
+{
+ char pid_str[20];
+ snprintf(pid_str, 20, "%d", process_id);
+ remove_proc_entry(pid_str);
+}
+
+/* get the client count for a given client ip */
+int get_client_count(char* client_ip)
+{
+ int count = 0;
+ /* now we see if there is a hash entry for this client_ip
+ * returns 0 if the client does not yet exist */
+ CLIENT *c = hash_lookup(client_table, client_ip);
+ if (c)
+ count = c->con_count;
+
+ return count;
+}
+
+/* increment the client counter for a client */
+int increment_client_count(char* client_ip)
+{
+ int count = get_client_count(client_ip);
+ /* create a new hash entry add it to the hash table */
+ CLIENT *nc = (CLIENT *)tac_malloc(sizeof(CLIENT));
+ memset(nc, 0, sizeof(CLIENT));
+ nc->name = tac_strdup(client_ip);
+ nc->hash = NULL;
+ nc->con_count = count + 1;
+ if (count) {
+ /* the hash does not support update, so we need to delete + add */
+ remove_client_entry(client_ip);
+ }
+ hash_add_entry(client_table, (void *)nc);
+ return nc->con_count;
+}
+
+char * get_client_ip_from_pid(pid_t process_id)
+{
+ char pid_str[20];
+ /* hashing only works in strings, so we convert here */
+ snprintf(pid_str, 20, "%d", process_id);
+ PROC_CLIENT *pc = hash_lookup(proc_table, pid_str);
+ if (pc) {
+ return pc->client_ip;
+ }
+}
+
+/* derement the client counter for a given client IP */
+int decrement_client_count(char* client_ip) {
+ CLIENT *nc;
+ int count = get_client_count(client_ip);
+ if (! count) {
+ return 0;
+ }
+ count--;
+ if (count >= 1) {
+ /* we update the existing hash entry if the count is still positive
+ * but the hash does not support update so we have to delete
+ * and then add */
+ CLIENT *nc = (CLIENT *)tac_malloc(sizeof(CLIENT));
+ memset(nc, 0, sizeof(CLIENT));
+ nc->name = tac_strdup(client_ip);
+ nc->hash = NULL;
+ nc->con_count = count;
+ remove_client_entry(client_ip);
+ hash_add_entry(client_table, (void *)nc);
+ } else if (count == 0) {
+ /* if it was the last client, we delete the entry */
+ remove_client_entry(client_ip);
+ }
+ return count;
+}
+
+int decrement_client_count_for_proc(pid_t process_id)
+{
+ int proc_count = 0;
+ char* client_ip = get_client_ip_from_pid(process_id);
+ if (client_ip) {
+ proc_count = decrement_client_count(client_ip);
+ snprintf(msgbuf, MSGBUFSZ, "Pid %lu Lowered Count for %s to %d",
+ process_id, client_ip, proc_count);
+ report(LOG_ALERT, msgbuf);
+ delete_proc_client_map(process_id);
+ } else {
+ snprintf(msgbuf, MSGBUFSZ, "Failed to find client ip for pid %lu", process_id);
+ report(LOG_ALERT, msgbuf);
+ }
+ return proc_count;
+}
+
+
+int increment_client_count_for_proc(pid_t process_id, char* client_ip)
+{
+ /* first we need to map pid to client_ip */
+ create_proc_client_map(process_id, client_ip);
+ /* now we inrement */
+ return increment_client_count(client_ip);
+}
+
+void dump_client_tables()
+{
+ CLIENT *cl;
+ PROC_CLIENT *pc;
+ CLIENT **clients = (CLIENT **) hash_get_entries(client_table);
+ PROC_CLIENT **procs = (PROC_CLIENT **) hash_get_entries(proc_table);
+ CLIENT **c;
+ PROC_CLIENT **p;
+
+ for (p = procs; *p; p++) {
+ pc = *p;
+ report(LOG_ALERT, "Proc: %s, IP: %s", pc->name, pc->client_ip);
+ }
+ for (c = clients; *c; c++) {
+ cl = *c;
+ report(LOG_ALERT, "Client: %s, Count: %d", cl->name, cl->con_count);
+ }
+}
--- tacacs-F4.0.4.28-orig/hash_test.c 1969-12-31 16:00:00.000000000 -0800
+++ tacacs-F4.0.4.28/hash_test.c 2018-05-24 14:18:15.000000000 -0700
@@ -0,0 +1,52 @@
+#include "tac_plus.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int debug = 0;
+int console = 0;
+int single = 0;
+int inner_loop = 100000;
+int outer_loop = 10;
+
+int main (int argc, char **argv) {
+ int i, j;
+ int counter;
+ unsigned int lipaddr;
+ struct sockaddr_in sa;
+ char memcmd[1024];
+ char ip1[INET6_ADDRSTRLEN];
+ time_t t;
+ client_count_init();
+
+ srand((unsigned) time(&t));
+ setvbuf(stdout, NULL, _IONBF, 0);
+ snprintf(memcmd, 1024, "cat /proc/%d/statm", getpid());
+ printf("CMD: %s\n", memcmd);
+
+ for (i = 0; i < outer_loop; i++) {
+ printf ("Loop %d\nMemory: ", i);
+ system(memcmd);
+ for (j = 1; j <= inner_loop; j++) {
+ lipaddr = rand();
+ if (rand() % 2) {
+ inet_ntop(AF_INET, &lipaddr, ip1, sizeof(ip1));
+ } else {
+ inet_ntop(AF_INET6, &lipaddr, ip1, sizeof(ip1));
+ }
+ debug && printf("Increment %s, %d\n", ip1, j);
+ counter = increment_client_count_for_proc((pid_t)j, ip1);
+ debug && printf("Post Inc Count: %s, %d\n", ip1, counter);
+ }
+ for (j = inner_loop; j >= 1; j--) {
+ debug && printf("Decrement for proc %d\n", j);
+ counter = decrement_client_count_for_proc((pid_t)j);
+ debug && printf("Post Dec Counter: %d\n", counter);
+ }
+ dump_client_tables();
+ }
+ exit(0);
+}
--- tacacs-F4.0.4.28-orig/parse.h 2018-05-24 15:23:53.754893000 -0700
+++ tacacs-F4.0.4.28/parse.h 2018-05-24 14:40:24.397619000 -0700
@@ -91,3 +91,8 @@
#endif
#define S_syslog 50
#define S_aceclnt 51
+#define S_maxprocs 52
+#define S_maxprocsperclt 53
+#define S_readtimeout 54
+#define S_writetimeout 55
+#define S_accepttimeout 56
--- ../tacacs-F4.0.4.28-orig/parse.c 2018-05-29 11:13:17.881390000 -0700
+++ tacacs-F4.0.4.28/parse.c 2018-05-29 12:12:40.027352000 -0700
@@ -121,6 +121,12 @@
declare("PAM", S_pam);
#endif
declare("syslog", S_syslog);
+ declare("maxprocs", S_maxprocs);
+ declare("maxprocsperclt", S_maxprocsperclt);
+ declare("readtimeout", S_readtimeout);
+ declare("writetimeout", S_writetimeout);
+ declare("accepttimeout", S_accepttimeout);
+
}
/* Return a keyword code if a keyword is recognized. 0 otherwise */
@@ -266,5 +272,15 @@
#endif
case S_syslog:
return("syslog");
+ case S_maxprocs:
+ return("maxprocs");
+ case S_maxprocsperclt:
+ return("maxprocsperclt");
+ case S_readtimeout:
+ return("readtimeout");
+ case S_writetimeout:
+ return("writetimeout");
+ case S_accepttimeout:
+ return("accepttimeout");
}
}

View File

@ -0,0 +1,28 @@
--- tacacs-F4.0.4.28-orig/configure.ac 2018-05-24 17:58:58.464108000 -0700
+++ tacacs-F4.0.4.28/configure.ac 2018-05-29 10:52:43.580186000 -0700
@@ -925,25 +925,6 @@
AC_SUBST(INST_PROGS)
INST_PROGS=$progs
-dnl locate perl 5
-AC_PROG_INSTALL
-AC_PATH_PROG(PERLV_PATH,perl5,no)
-if test $PERLV_PATH = no; then
- unset ac_cv_path_PERLV_PATH
- AC_PATH_PROG(PERLV_PATH,perl,no)
- if test $PERLV_PATH = no; then
- AC_MSG_ERROR([can't locate a suitable perl5.])
- exit 1
- else
- $PERLV_PATH -e 'require 5;'
- if test $? -ne 0 ; then
- AC_MSG_ERROR([can't locate a suitable perl5.])
- exit 1
- fi
- fi
-fi
-AC_SUBST(PERLV_PATH)
-
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)

View File

@ -0,0 +1,25 @@
--- tacacs-F4.0.4.28-orig/tac_plus.service 1969-12-31 16:00:00.000000000 -0800
+++ tacacs-F4.0.4.28/tac_plus.service 2018-05-29 10:44:53.003596000 -0700
@@ -0,0 +1,22 @@
+[Unit]
+Description=TACACS+ IPv4 Daemon
+After=network.target
+After=crond.service
+ConditionPathExists=/etc/tac_plus.conf
+
+[Service]
+LimitCORE=16G
+StandardOutput=null
+
+ExecStartPre=/usr/sbin/tac_plus \
+ -C /etc/tac_plus.conf \
+ -P
+
+ExecStart=/usr/sbin/tac_plus \
+ -C /etc/tac_plus.conf \
+ -G
+
+Restart=always
+
+[Install]
+WantedBy=multi-user.target

View File

@ -0,0 +1,60 @@
--- tacacs-F4.0.4.28-orig/tac_plus.sysvinit 1969-12-31 16:00:00.000000000 -0800
+++ tacacs-F4.0.4.28/tac_plus.sysvinit 2018-05-29 10:45:09.406416000 -0700
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# /etc/rc.d/init.d/tac_plus
+#
+# chkconfig: 2345 86 14
+# description: TACACS+ Daemon
+
+# Define variables
+CORE_DUMP=1 # Lets always coredump
+TACPLUS_BIN=/usr/sbin/tac_plus
+TACPLUS_OPTS=""
+TACPLUS_CONF=/etc/tac_plus.conf
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+if [ $CORE_DUMP -ne 0 ]; then
+ ulimit -c unlimited
+ export DAEMON_COREFILE_LIMIT='unlimited'
+fi
+
+RETVAL=0
+prog="tac_plus"
+
+case "$1" in
+ start)
+ # Got Config File?
+ [ -f /etc/tac_plus.conf ] || exit 69
+
+ echo -n $"Starting $prog: "
+ daemon $TACPLUS_BIN -C $TACPLUS_CONF $TACPLUS_OPTS
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
+ echo
+ ;;
+ stop)
+ echo -n $"Shutting down $prog: "
+ killproc $prog
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
+ echo
+ ;;
+ restart|reload)
+ $0 stop
+ $0 start
+ RETVAL=$?
+ ;;
+ status)
+ status $prog
+ RETVAL=$?
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|reload|status}"
+ exit 2
+esac
+
+exit $RETVAL

View File

@ -0,0 +1,26 @@
--- configure.ac 2018-05-29 10:56:13.746325000 -0700
+++ tacacs-F4.0.4.28/configure.ac 2018-05-29 10:54:40.184600000 -0700
@@ -6,10 +6,9 @@
dnl VERSION needs to be updated in version.h.in such that 'make dist'
dnl uses the correct filename for the directory name and tarball and binaries
dnl get the right version numbers.
-PACKAGE=`sh ./aconf/package.sh`
-VERSION=`sh ./aconf/version.sh`
-AC_INIT(m4_esyscmd(sh ./aconf/package.sh),
- m4_esyscmd(sh ./aconf/version.sh))
+AC_INIT([tacacs],
+ m4_esyscmd_s([sed -n 's/.*version.*"\(.*\)".*/\1/p' version.h.in]))
+
AC_CONFIG_AUX_DIR([aconf])
AC_CONFIG_MACRO_DIR([aconf])
AM_INIT_AUTOMAKE
--- tacacs-F4.0.4.28-orig/version.h.in 2018-05-24 15:23:53.706925000 -0700
+++ tacacs-F4.0.4.28/version.h.in 2018-05-24 15:49:55.279005000 -0700
@@ -3,6 +3,6 @@
#define VERSION_H
char package[] = "tacacs+";
-char version[] = "F4.0.4.28";
+char version[] = "F4.0.4.28-1fb";
#endif

View File

@ -1,48 +0,0 @@
This is a modified version of Cisco's tacacs+ (tac_plus) "developer's
kit."
Quick Installation Guide (an example):
1) ./configure [--prefix=<basedir>]
By default, All tac_plus crud will be installed under /usr/local.
This can be overridden with the --prefix option. E.g.:
./configure --prefix=/usr/pkg
see ./configure --help for other configure options.
2) make install
3) it may be necessary, or you may want to, add tacacs to your /etc/services
file in order for tacacs to work properly. eg:
tacacs tcp/49
4) read the tac_plug(8) manual page
5) Send any bugs, suggestions or updates to tac_plus@shrubbery.net.
See the web page at http://www.shrubbery.net/tac_plus.
Misc info:
There is also a list called TACPLUS-L, run by disaster.com, created for
the purpose of information exchange between TACACS+ Users and aiding
TACACS+ users and prospective users in many issues including but not
limited to technical support, bug reports and workarounds, configuration
information, recommendations for future versions of TACACS+, and general
talk about TACACS+ development, implementation, administration, etc.
To subscribe to the TACPLUS-L list, send a message to
tacplus-l-request@disaster.com
In the body of the letter, enter
SUBSCRIBE TACPLUS-L your Name
to be automatically added, or visit their web page at
http://www.disaster.com/tacplus/.
Also, Robert Kiessling maintains a TACACS+ FAQ at
http://www.easynet.de/tacacs-faq.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,349 +0,0 @@
#!/usr/bin/python
# Program I am writing to do the things tac_plus won't
# It will allow very granular control.
# Version 1.1
# Simple typo - a stray 's' botched a deny statement
# Version 1.2
# Did you know a firewall doesn't send a cmd-arg=<cr>?
'''
do_auth.py [-options]
Version 1.2
do_auth is a python program I wrote to work as an authorization script for
tacacs to allow greater flexability in tacacs authentication. It allows
a user to be part of many predefined groups that can allow different
access to different devices based on ip, user, and source address.
Do not play with do_auth untill you have a firm grasp on tac_plus!
-u Username. Mandatory. $user
-i Ip address of user. Optional. If not specified, all host_ entries
are ignored and can be omitted. $address
-d Device address. Optional. If not specified, all device_ entries
are ignored and can be omitted. $name
-f Config Filename. Default is do_auth.ini.
-l Logfile. Default is log.txt.
-D Debug mode. Allows you to call the program without reading
from stdin. Useful to test your configuration before going
live. Sets a default command of "show users wides".
Groups are assigned to users in the [users] section. A user must
be assigned to one or more groups, one per line. Groups are defined
in brackets, but can be any name. Each group can have up to 6 options
as defined below.
host_deny Deny any user coming from this host. Optional.
host_allow Allow users from this range. Mandatory if
-i is specified.
device_deny Deny any device with this IP. Optional.
device_permit Allow this range. Mandatory if -d is specified
command_deny Deny these commands. Optional.
command_permit Allow these commands. Mandatory.
The options are parsed in order till a match is found. Obviously,
for login, the commands section is not parsed. If a match is not
found, or a deny is found, we move on to the next group. At the
end, we have an implicit deny if no groups match. All tacacs keys
passed on login to do_auth are returned. (except cmd*) It is
possible to modify them, but I haven't implemented this yet as
I don't need it. Future versions may have an av_pair &
append_av_pair option.
An simple example is as follows.
[users]
homer =
simpson_group
television_group
stimpy =
television_group
[simpson_group]
host_deny =
1.1.1.1
1.1.1.2
host_allow =
1.1.1.*
device_allow =
10.1.1.*
command_permit =
.*
[television_group]
host_allow =
.*
device_allow =
.*
command_permit =
show.*
Example tacacs line: after authorization "/usr/bin/python
/root/do_auth.pyc -i $address -u $user -d $name -l /root/log.txt
-f /root/do_auth.ini"
(that's one line)
BUGS: You must know your regular expressions. If you enter a bad
expression, such as *. instead of .*, python re will freak out and
not evaluate the expression. Designed for exec - I don't have
any ppp/ect equipment to test, or rather I do, but I don't have
time to mess with it.
CAVEATS: One group can not take away what another group grants. If
a match is not found, it will go on to the next group. If a deny is
matched, it will go on to the next group.
Order is crucial - the groups should go from more specific to less
specific. In the above example, if television_group was put before
simpson_group, simpson_group would never be called because
televsion_group catches everything in device_allow.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 or any
later version as published by the Free Software Foundation,
http://www.gnu.org/
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Written by Dan Schmidt
'''
import sys,re,getopt,ConfigParser
from time import strftime
# I really don't want to deal with these exceptions more than once
# filename is only used in log statements
def get_attribute(config, the_section, the_option, log_file, filename):
if not config.has_section(the_section):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Section '%s' does not exist in %s\n"
% (the_section, filename))
sys.exit(1)
if not config.has_option(the_section, the_option):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Option '%s' does not exist in section %s in file %s\n"
% (the_option, the_section, filename))
sys.exit(1)
#Should not have any exceptions - BUT, just in case
try:
attributes = config.get(the_section, the_option)
except ConfigParser.NoSectionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Section '%s' Doesn't Exist!\n"
% (the_section))
sys.exit(1)
except ConfigParser.DuplicateSectionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Duplicate section '%s'\n"
% (the_section))
sys.exit(1)
except ConfigParser.NoOptionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: '%s' not found in section '%s\n'"
% (the_option, the_section))
sys.exit(1)
#To do: finish exceptions.
except ConfigParser.ParsingError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Can't parse file '%s'! (You got me)\n"
% (filename))
sys.exit(1)
attributes = attributes.split('\n')
#Strip empty lines
attributes2 = []
for line in attributes:
if line:
attributes2.append(line)
return attributes2
# If match item in our_list, true, else false
# Example - if deny section has a match for 10.1.1.1,
# return True, else False
# If the section doesn't exist, we assume an
# impicity deny/false
def match_it(the_section, the_option, match_item, config, log_file, filename):
if config.has_option(the_section,the_option):
our_list = get_attribute(config, the_section, the_option, log_file, filename)
for item in our_list:
#p = re.compile(item) Not necessary - we're only using it once
if re.match(item,match_item):
return True
return False
def main():
#Defaults
filename = "do_auth.ini"
log_name = "log.txt"
user_name = ""
ip_addr = ""
device = ""
is_debug = False
argv = sys.argv
try:
optlist, args = getopt.getopt(sys.argv[1:], 'i:u:f:l:d:?:D', ['?', '-?', 'help', 'Help'])
except getopt.GetoptError, err:
print str(err) # will print something like "option -a not recognized"
print __doc__
sys.exit(1)
for (i, j) in optlist:
if i == '-i':
ip_addr = j
elif i == '-u':
user_name = j
elif i == '-f':
filename = j
elif i == '-l':
log_name = j
elif i == '-d':
device = j
elif i in ('?', '-?', 'help', 'Help'):
print __doc__
sys.exit(1)
elif i == '-D':
is_debug = True
else:
print 'Unknown option:', i
sys.exit(1)
if len(argv) < 7:
print __doc__
sys.exit(1)
log_file = open (log_name, "a")
#read AV pairs
av_pairs = []
if not (is_debug):
for line in sys.stdin:
av_pairs.append(line)
else:
#Default Debug command is "show users wide"
#Later versions will allow this to be set
av_pairs.append("service=shell\n")
av_pairs.append("cmd=show\n")
av_pairs.append("cmd-arg=users\n")
av_pairs.append("cmd-arg=wide\n")
av_pairs.append("cmd-arg=<cr>\n")
#DEBUG
# for item in av_pairs:
# log_file.write(item)
# Function to make cmd's readable
# Not very good, but will do for now
# I don't use any other service other than shell to test!
the_command = ""
return_pairs = ""
if (av_pairs[0] == "service=shell\n"):
#Commands - Concatenate to a readable command
if av_pairs[1].startswith("cmd="):
our_command = av_pairs[1].split("=")
the_command = our_command[1].strip('\n')
if len(av_pairs) > 2:
i = 2
our_command = av_pairs[i].split("=")
while not (our_command[1] == "<cr>\n"):
the_command = the_command + " " + our_command[1].strip('\n')
i = i + 1
if i == len(av_pairs): # Firewalls don't give a <cr>!!
break
our_command = av_pairs[i].split("=")
#DEBUG
#log_file.write(the_command + '\n')
#Login - Get av_pairs to pass back to tac_plus
if av_pairs[1].startswith("cmd*"): #Anybody know why it's "cmd*"?
return_pairs = av_pairs[2:] #You have to strip the "cmd*" av-pair
if not user_name:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: No username entered!\n")
sys.exit(1)
config = ConfigParser.SafeConfigParser()
if not (filename in config.read(filename)):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Can't open/parse '%s'\n"
% (filename))
sys.exit(1)
the_section = "users"
groups = get_attribute(config, "users", user_name, log_file, filename)
for this_group in groups:
if ip_addr:
if match_it(this_group, "host_deny", ip_addr, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied from source '%s' in '%s'->'%s'\n"
% (user_name, ip_addr, this_group, "host_deny"))
sys.exit(1)
else:
# HUM... afterthought. We need it to continue if more groups exist
continue
if not match_it(this_group, "host_allow", ip_addr, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed from source '%s' in '%s'->'%s'\n"
% (user_name, ip_addr, this_group, "host_allow"))
sys.exit(1)
else:
continue
if device:
if match_it(this_group, "device_deny", device, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied access to device '%s' in '%s'->'%s'\n"
% (user_name, device, this_group, "device_deny"))
sys.exit(1)
else:
continue
if not match_it(this_group, "device_permit", device, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed access to device '%s' in '%s'->'%s'\n"
% (user_name, device, this_group, "device_permit"))
sys.exit(1)
else:
continue
# The previous 4 statements are to deny, it we passed them, proceed
# If we are logging in, return pairs, if not, go no to check the command
# Yes, simply printing them is how you return them
if not len(the_command) > 0:
for item in return_pairs:
print item.strip('\n')
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' granted access to device '%s' in group '%s' from '%s'\n"
% (user_name, device, this_group, ip_addr))
sys.exit(2)
else: # Check command
if match_it(this_group, "command_deny", the_command, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied command '%s' to device '%s' in '%s'->'%s'\n"
% (user_name, the_command, device, this_group, "command_deny"))
sys.exit(1)
else:
continue
elif match_it(this_group, "command_permit", the_command, config, log_file, filename):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' allowed command '%s' to device '%s' in '%s'->'%s'\n"
% (user_name, the_command, device, this_group, "command_permit"))
sys.exit(0)
else: #exit & log if last group
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed command '%s' to device '%s' in any group\n"
% (user_name, the_command, device))
#Hum... this only works if it's the last group/only group.
sys.exit(1)
else:
continue
#implicit deny at the end
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed access to device '%s' from '%s' in any group\n"
% (user_name, device, ip_addr))
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -1,291 +0,0 @@
#!/bin/sh
#
# $NetBSD: install-sh.in,v 1.4 2007/07/12 18:32:50 jlam Exp $
# This script now also installs multiple files, but might choke on installing
# multiple files with spaces in the file names.
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
awkprog="${AWKPROG-awk}"
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
instcmd="$mvprog"
pathcompchmodcmd="$chmodprog 755"
chmodcmd="$chmodprog 755"
chowncmd=""
chgrpcmd=""
stripcmd=""
stripflags=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
msrc=""
dst=""
dir_arg=""
suffix=""
suffixfmt=""
while [ x"$1" != x ]; do
case $1 in
-b) suffix=".old"
shift
continue;;
-B) suffixfmt="$2"
shift
shift
continue;;
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-S) stripcmd="$stripprog"
stripflags="-S $2 $stripflags"
shift
shift
continue;;
*) if [ x"$msrc" = x ]
then
msrc="$dst"
else
msrc="$msrc $dst"
fi
src="$dst"
dst="$1"
shift
continue;;
esac
done
if [ x"$dir_arg" = x ]
then
dstisfile=""
if [ ! -d "$dst" ]
then
if [ x"$msrc" = x"$src" ]
then
dstisfile=true
else
echo "install: destination is not a directory"
exit 1
fi
fi
else
msrc="$msrc $dst"
fi
if [ x"$msrc" = x ]
then
echo "install: no destination specified"
exit 1
fi
for srcarg in $msrc; do
if [ x"$dir_arg" != x ]; then
dstarg="$srcarg"
else
dstarg="$dst"
# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$srcarg" ]
then
doinst="$instcmd"
elif [ -d "$srcarg" ]
then
echo "install: $srcarg: not a regular file"
exit 1
elif [ "$srcarg" = "/dev/null" ]
then
doinst="$cpprog"
else
echo "install: $srcarg does not exist"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d "$dstarg" ]
then
dstarg="$dstarg"/`basename "$srcarg"`
fi
fi
## this sed command emulates the dirname command
dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$doit $mkdirprog "${pathcomp}"
if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
if [ -d "$dstarg" ]; then
true
else
$doit $mkdirprog "$dstarg" &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
fi
else
if [ x"$dstisfile" = x ]
then
file=$srcarg
else
file=$dst
fi
dstfile=`basename "$file"`
dstfinal="$dstdir/$dstfile"
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Make a backup file name in the proper directory.
case x$suffixfmt in
*%*) suffix=`echo x |
$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
{ cnt = 0;
do {
sfx = sprintf(fmt, cnt++);
name = bname sfx;
} while (system("test -f " name) == 0);
print sfx; }' -`;;
x) ;;
*) suffix="$suffixfmt";;
esac
dstbackup="$dstfinal$suffix"
# Move or copy the file name to the temp name
$doit $doinst $srcarg "$dsttmp" &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
# Now rename the file to the real destination.
if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
then
$doit $mvcmd "$dstfinal" "$dstbackup"
else
$doit $rmcmd -f "$dstfinal"
fi &&
$doit $mvcmd "$dsttmp" "$dstfinal"
fi
done &&
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -1,376 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar*)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,179 +0,0 @@
.TH REGEXP 3 local
.DA 2 April 1986
.SH NAME
regcomp, regexec, regsub, regerror \- regular expression handler
.SH SYNOPSIS
.ft B
.nf
#include <regexp.h>
regexp *regcomp(exp)
char *exp;
int regexec(prog, string)
regexp *prog;
char *string;
regsub(prog, source, dest)
regexp *prog;
char *source;
char *dest;
regerror(msg)
char *msg;
.SH DESCRIPTION
These functions implement
.IR egrep (1)-style
regular expressions and supporting facilities.
.PP
.I Regcomp
compiles a regular expression into a structure of type
.IR regexp ,
and returns a pointer to it.
The space has been allocated using
.IR malloc (3)
and may be released by
.IR free .
.PP
.I Regexec
matches a NUL-terminated \fIstring\fR against the compiled regular expression
in \fIprog\fR.
It returns 1 for success and 0 for failure, and adjusts the contents of
\fIprog\fR's \fIstartp\fR and \fIendp\fR (see below) accordingly.
.PP
The members of a
.I regexp
structure include at least the following (not necessarily in order):
.PP
.RS
char *startp[NSUBEXP];
.br
char *endp[NSUBEXP];
.RE
.PP
where
.I NSUBEXP
is defined (as 10) in the header file.
Once a successful \fIregexec\fR has been done using the \fIregexp\fR,
each \fIstartp\fR-\fIendp\fR pair describes one substring
within the \fIstring\fR,
with the \fIstartp\fR pointing to the first character of the substring and
the \fIendp\fR pointing to the first character following the substring.
The 0th substring is the substring of \fIstring\fR that matched the whole
regular expression.
The others are those substrings that matched parenthesized expressions
within the regular expression, with parenthesized expressions numbered
in left-to-right order of their opening parentheses.
.PP
.I Regsub
copies \fIsource\fR to \fIdest\fR, making substitutions according to the
most recent \fIregexec\fR performed using \fIprog\fR.
Each instance of `&' in \fIsource\fR is replaced by the substring
indicated by \fIstartp\fR[\fI0\fR] and
\fIendp\fR[\fI0\fR].
Each instance of `\e\fIn\fR', where \fIn\fR is a digit, is replaced by
the substring indicated by
\fIstartp\fR[\fIn\fR] and
\fIendp\fR[\fIn\fR].
To get a literal `&' or `\e\fIn\fR' into \fIdest\fR, prefix it with `\e';
to get a literal `\e' preceding `&' or `\e\fIn\fR', prefix it with
another `\e'.
.PP
.I Regerror
is called whenever an error is detected in \fIregcomp\fR, \fIregexec\fR,
or \fIregsub\fR.
The default \fIregerror\fR writes the string \fImsg\fR,
with a suitable indicator of origin,
on the standard
error output
and invokes \fIexit\fR(2).
.I Regerror
can be replaced by the user if other actions are desirable.
.SH "REGULAR EXPRESSION SYNTAX"
A regular expression is zero or more \fIbranches\fR, separated by `|'.
It matches anything that matches one of the branches.
.PP
A branch is zero or more \fIpieces\fR, concatenated.
It matches a match for the first, followed by a match for the second, etc.
.PP
A piece is an \fIatom\fR possibly followed by `*', `+', or `?'.
An atom followed by `*' matches a sequence of 0 or more matches of the atom.
An atom followed by `+' matches a sequence of 1 or more matches of the atom.
An atom followed by `?' matches a match of the atom, or the null string.
.PP
An atom is a regular expression in parentheses (matching a match for the
regular expression), a \fIrange\fR (see below), `.'
(matching any single character), `^' (matching the null string at the
beginning of the input string), `$' (matching the null string at the
end of the input string), a `\e' followed by a single character (matching
that character), or a single character with no other significance
(matching that character).
.PP
A \fIrange\fR is a sequence of characters enclosed in `[]'.
It normally matches any single character from the sequence.
If the sequence begins with `^',
it matches any single character \fInot\fR from the rest of the sequence.
If two characters in the sequence are separated by `\-', this is shorthand
for the full list of ASCII characters between them
(e.g. `[0-9]' matches any decimal digit).
To include a literal `]' in the sequence, make it the first character
(following a possible `^').
To include a literal `\-', make it the first or last character.
.SH AMBIGUITY
If a regular expression could match two different parts of the input string,
it will match the one which begins earliest.
If both begin in the same place but match different lengths, or match
the same length in different ways, life gets messier, as follows.
.PP
In general, the possibilities in a list of branches are considered in
left-to-right order, the possibilities for `*', `+', and `?' are
considered longest-first, nested constructs are considered from the
outermost in, and concatenated constructs are considered leftmost-first.
The match that will be chosen is the one that uses the earliest
possibility in the first choice that has to be made.
If there is more than one choice, the next will be made in the same manner
(earliest possibility) subject to the decision on the first choice.
And so forth.
.PP
For example, `(ab|a)b*c' could match `abc' in one of two ways.
The first choice is between `ab' and `a'; since `ab' is earlier, and does
lead to a successful overall match, it is chosen.
Since the `b' is already spoken for,
the `b*' must match its last possibility\(emthe empty string\(emsince
it must respect the earlier choice.
.PP
In the particular case where no `|'s are present and there is only one
`*', `+', or `?', the net effect is that the longest possible
match will be chosen.
So `ab*', presented with `xabbbby', will match `abbbb'.
Note that if `ab*' is tried against `xabyabbbz', it
will match `ab' just after `x', due to the begins-earliest rule.
(In effect, the decision on where to start the match is the first choice
to be made, hence subsequent choices must respect it even if this leads them
to less-preferred alternatives.)
.SH SEE ALSO
egrep(1), expr(1)
.SH DIAGNOSTICS
\fIRegcomp\fR returns NULL for a failure
(\fIregerror\fR permitting),
where failures are syntax errors, exceeding implementation limits,
or applying `+' or `*' to a possibly-null operand.
.SH HISTORY
Both code and manual page were
written at U of T.
They are intended to be compatible with the Bell V8 \fIregexp\fR(3),
but are not derived from Bell code.
.SH BUGS
Empty branches and empty regular expressions are not portable to V8.
.PP
The restriction against
applying `*' or `+' to a possibly-null operand is an artifact of the
simplistic implementation.
.PP
Does not support \fIegrep\fR's newline-separated branches;
neither does the V8 \fIregexp\fR(3), though.
.PP
Due to emphasis on
compactness and simplicity,
it's not strikingly fast.
It does give special attention to handling simple cases quickly.

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
/*
* $Id: regexp.h,v 1.5 2006-12-13 00:51:19 heas Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Definitions etc. for regexp(3) routines.
*
* Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#define NSUBEXP 10
typedef struct regexp {
char *startp[NSUBEXP];
char *endp[NSUBEXP];
char regstart; /* Internal use only. */
char reganch; /* Internal use only. */
char *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
char program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
regexp *regcomp(char *);
int regexec(register regexp *, register char *);
void regsub();
void regerror(char *);

View File

@ -1,26 +0,0 @@
/*
* $Id: regmagic.h,v 1.3 2002-11-27 21:21:21 heas Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* The first byte of the regexp internal "program" is actually this magic
* number; the start node begins in the second byte.
*/
#define MAGIC 0234

View File

@ -1,23 +0,0 @@
[Unit]
Description=TACACS+ IPv6 Daemon
After=network.target
After=crond.service
ConditionPathExists=/etc/tac_plus.conf
[Service]
LimitCORE=16G
StandardOutput=null
ExecStartPre=/usr/bin/tac_plus6 \
-C /etc/tac_plus.conf \
-P
ExecStart=/usr/bin/tac_plus6 \
-C /etc/tac_plus.conf \
-B :: \
-G
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -1,57 +0,0 @@
#!/bin/bash
#
# /etc/rc.d/init.d/tac_plus6
#
# chkconfig: 2345 86 14
# description: TACACS+ v6 Daemon
# Define variables
CORE_DUMP=1 # Lets always coredump
TACPLUS_BIN=/usr/bin/tac_plus6
TACPLUS_OPTS="-B ::"
TACPLUS_CONF=/etc/tac_plus.conf
# Source function library.
. /etc/rc.d/init.d/functions
if [ $CORE_DUMP -ne 0 ]; then
ulimit -c unlimited
export DAEMON_COREFILE_LIMIT='unlimited'
fi
RETVAL=0
prog="tac_plus6"
case "$1" in
start)
# Got Config File?
[ -f /etc/tac_plus.conf ] || exit 69
echo -n $"Starting $prog: "
daemon $TACPLUS_BIN -C $TACPLUS_CONF $TACPLUS_OPTS
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
;;
stop)
echo -n $"Shutting down $prog: "
killproc $prog
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
echo
;;
restart|reload)
$0 stop
$0 start
RETVAL=$?
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,75 +0,0 @@
Summary: TACACS+6 Daemon
Name: tacacs+6
Group: Networking/Servers
Version: FB4.0.4.19.1
Release: 18fb
License: Cisco
Packager: Cooper Lees <cooper@fb.com>
Vendor: Facebook Inc.
Source: tacacs+-%{version}.tar.gz
BuildRoot: %{_tmppath}/tacacs+-%{version}-%{release}-root
BuildRequires: gcc, bison, flex, m4, pam-devel, tcp_wrappers, tcp_wrappers-devel, systemd
Requires: pam, tcp_wrappers, tcp_wrappers-devel, tcp_wrappers-libs, tacacs+
%define _unpackaged_files_terminate_build 0
%description
IPv6 Tacacs+ Daemon for Linux
%debug_package
%prep
umask 022
%{__rm} -rf %{_tmppath}/tacacs+-%{version}-%{release}-root/*
%{__rm} -rf %{_builddir}/tacacs+-%{version}
cd %{_builddir}
tar xvzf %{_sourcedir}/tacacs+-%{version}.tar.gz
if [ ! -L %{name}-%{version} ]; then
ln -s tacacs+-%{version} %{name}-%{version}
fi
%build
pwd
export CFLAGS="-DHAVE_PAM -DIPV6"
cd tacacs+-%{version}
%configure --enable-acls --enable-uenable --with-pidfile=/var/run/tac_plus6.pid --with-acctfile=/var/log/tac_plus6.acct --with-logfile=/var/log/tac_plus6.log --program-suffix=6
%{__make}
%install
export DONT_STRIP=1
%{__rm} -rf %{buildroot}
cd tacacs+-%{version}
%makeinstall
%{__install} -Dp -m0755 tac_plus6.sysvinit %{buildroot}%{_initrddir}/tac_plus6
%{__install} -Dp -m0644 tac_plus6.service %{buildroot}%{_unitdir}/tac_plus6.service
### Clean up buildroot
%{__rm} -f %{buildroot}%{_infodir}/dir
%post
%systemd_post tac_plus6.service
%preun
%systemd_preun tac_plus6.service
%postun
%systemd_postun_with_restart tac_plus6.service
%clean
%{__rm} -rf %{buildroot}
%files
%{_unitdir}/tac_plus6.service
/usr/bin/tac_pwd6
/usr/bin/tac_plus6
/etc/rc.d/init.d/tac_plus6
/usr/share/man/man3/regexp6.3.gz
/usr/share/man/man5/tac_plus.conf6.5.gz
/usr/share/man/man8/tac_plus6.8.gz
/usr/share/man/man8/tac_pwd6.8.gz
%changelog

View File

@ -1,4 +1,4 @@
>Changes from Release 0.0 to release 0.1
Changes from Release 0.0 to release 0.1
---------------------------------------
You must now say "default attribute = permit" instead of
@ -394,9 +394,90 @@ F4.0.4.19
- add authorization script example - from Daniel Schmidt
- add partial support for single-connection mode
- convert select()s to poll()s
F4.04.19-fb - aka fb-tac_plus 1.0
- IPv6 Socket + ensure seperate .acct + PID files be used
- Use AF_INET6 supported functions
- Fix some seg faults + other bugs
- Add PAM patch
- Add appropriate logging to go to syslog re: auth success and fail
F4.0.4.20
- remove stupid error message about running as root
- Drop the private regex library in favor of libc's. A system w/o a
regex is one I dont care about.
- finally remove config parsing for 'default authorization = permit'
- apply ACLs to pap, chap, arap and ms-chap authentication too
- change accounting log time format to match syslog
- do_auth.py fix from Daniel Schmidt
- import fdes from David G. Koontz (1991) for ARAP/MSCHAP_DES
- move MSCHAP define to autoconf; --enable-mschap
- use the fdes code for ARAP_DES and MSCHAP_DES. NOTE: I have no way to
test this. lmk if it does not work.
- increase NAC address array size. affects the format of the tacacs
wholog file (TACPLUS_WHOLOGFILE); existing file should be removed.
- add comments to tac_plus.conf.5 about cipher algorithms in
password_spec
- do_auth.py - Fixed reression, Support for replacing av pairs - from
Daniel Schmidt
F4.0.4.21
- do_auth.py - better Nexus support, better AV replacement, and only
send roles to Nexus - from Daniel Schmidt
- fix bug in checking the return value of regexec() for login and enable
ACLs.
- do_auth.py - better Nexus support, better AV replacement, and only
F4.0.4.22
- check of regexec() return value inverted - from Ignas Kazlauskas
F4.0.4.23
- fix build on netbsd
- update PAM includes for OSX - YiJia Zhang
F4.0.4.24
- allow PAM for pap authentication - Jeroen Nijhof
- replace home-grown vprintf in report() with vsnprintf - Robert Swiecki
- dont use report in signal handler, since report uses syslog which uses
malloc - Robert Swiecki
- use volatile sig_atomic_t 'reinitialize' variable - Robert Swiecki
- use snprintf in get_authen_continue() and send_authen_error() and
check return - Robert Swiecki
- make snprintf buffers of get_authen_continue() and send_authen_error()
at least NI_MAXHOST bytes - Robert Swiecki
F4.0.4.25
- add -m (md5) option to tac_pwd. XXX could use better salt generation
- use random() in tac_pwd if available and generate 4 bytes of salt for
md5.
- sprintf -> snprintf - Robert Swiecki
- more pkt size checking in acct.c, authen.c, author.c - Robert Swiecki
- free(pak) in start_session() not in account(), for consistency
F4.0.4.26
- add optional securid support via aceclient library - Matt Addison
- use localtime instead of gmtime for log messages so that the timezone
is inheritted.
- allow file authentication for PAP authorization
F4.0.4.27
- add "port" to clarify log messages of default_fn.c
- use program name (filename) instead of hard-coded "tac_plus" for
name given to PAM
- change socket binding to allow an IPv6 address with the -B argument
- bind v4 and v6 sockets if system claims its has addresses for the AFs
- fix command authorization debug message logic for match/no match -
reported by Dereck Chan
F4.0.4.28
- Fix buffer length argument to ntop() - Muhammad Muquit
- Fix two missing free()s
- Fix segfault from incorrect pointer returned from value(). Reported
here:
http://www.shrubbery.net/pipermail/tac_plus/2014-January/001384.html
- update autoconf bits for autoconf 2.69
- put tac_plus daemon in sbin, where it ought to be
- fix hdr->datalength handling in dump_nas_pak()
- add -m option to specify the client listen queue max and increase
the default to 64 if the O/S does not define SOMAXCONN
- fix config.h include syntax - David M. Syzdek
- added -U and -Q flags to allow runtime setuid/setgid change - from
from Robert Drake with some alteration
- Make implicit time_t conversions explicit in expire.c - from David M.
Syzdek
- initialize newsockfd in main() - from David M. Syzdek
- recent changes in autoconf are causing the + of the package name to
become -, so just drop it from the tarball name.

View File

@ -601,18 +601,18 @@ A). Version F4.X contains mschap support. Mschap is configured the
requires a key from Microsoft which is not public domain, but this can
also be done on the NAS too, so you can live without it.
To compile the daemon with MSCHAP support, uncomment the MSCHAP line
in the Makefile. This will add the MSCHAP code to your daemon. You can
leave MSCHAP_DES undefined, in which case the MSCHAP DES calculation
will be done by NAS, and no special MSCHAP key will be required.
To compile the daemon with MSCHAP support, give configured the
--enable-mschap option. This will add the MSCHAP code to your daemon.
You can leave MSCHAP_DES undefined (see configure --enable-mschapdes),
in which case the MSCHAP DES calculation will be done by NAS, and no
special MSCHAP key will be required.
If you have a DES library and want to use it with MSCHAP (this is more
efficient for authentication), then you can also uncomment the
MSCHAP_DES and MSCHAP_MD4_SRC lines in the Makefile. This will ensure
that the DES calculation done in the daemon. A key will need to be
obtained from Microsoft and used to replace the definition of
MSCHAP_KEY in the file mschap.h. If you're thinking by now that this
is all too much trouble, I can't say I blame you....
If want to use DES with MSCHAP (this is more efficient for
authentication), then you also give configure the --enable-mschapdes
option. This will ensure that the DES calculation is done in the daemon.
A key will need to be obtained from Microsoft and used to replace the
definition of MSCHAP_KEY in the file mschap.h. If you're thinking by now
that this is all too much trouble, you're right.
Q). Can I do wtmp-style logging like xtacacd used to do?
A). Wtmp file logging is supported. The "-u <wtmpfilename>" command
@ -630,3 +630,16 @@ A). Wtmp file logging is supported. The "-u <wtmpfilename>" command
aaa accounting exec stop-only tacacs+
aaa accounting network stop-only tacacs+
aaa accounting system start-stop tacacs+
Q) How does TACACS compare to RADIUS?
A) Cisco provided a good summary in general and somewhat specific to Cisco
products here:
http://www.cisco.com/en/US/tech/tk59/technologies_tech_note09186a0080094e99.shtml#comparing
Q) Cisco WLC (Wireless Lan Controller) does not autheticate with tacacs.
A) WLC uses roles and must have the appropriate service configuration:
service = ciscowlc {
role1 = ALL
}
http://www.cisco.com/c/en/us/td/docs/wireless/controller/7-5/config_guide/b_cg75/b_cg75_chapter_0101001.html

27
tacacs-F4.0.4.28/INSTALL Normal file
View File

@ -0,0 +1,27 @@
This is a modified version of Cisco's tacacs+ (tac_plus) "developer's
kit."
Quick Installation Guide (an example):
1) ./configure [--prefix=<basedir>]
By default, All tac_plus crud will be installed under /usr/local.
This can be overridden with the --prefix option. E.g.:
./configure --prefix=/usr/pkg
see ./configure --help for other configure options.
2) make install
3) it may be necessary, or you may want to, add tacacs to your /etc/services
file in order for tacacs to work properly. eg:
tacacs tcp/49
4) read the tac_plus(8) manual page
5) Send any bugs, suggestions or updates to tac_plus@shrubbery.net.
See the web page at http://www.shrubbery.net/tac_plus.
Prerequisites for building:
- Wietse Venema's TCP wrappers library

View File

@ -3,41 +3,47 @@
#AUTOMAKE_OPTIONS=foreign no-dependencies
AUTOMAKE_OPTIONS=foreign
ACLOCAL_AMFLAGS=-I aconf
@SET_MAKE@
bin_PROGRAMS = tac_pwd tac_plus
tac_pwd_SOURCES = md5.c tac_pwd.c
tac_plus_SOURCES = acct.c authen.c author.c choose_authen.c config.c \
default_fn.c default_v0_fn.c do_acct.c do_author.c dump.c enable.c \
encrypt.c expire.c hash.c maxsess.c parse.c programs.c pw.c pwlib.c \
regexp.c report.c sendauth.c sendpass.c tac_plus.c utils.c
bin_PROGRAMS = tac_pwd
sbin_PROGRAMS = tac_plus
tac_pwd_SOURCES = tac_pwd.c
tac_plus_SOURCES = acct.c authen.c author.c choose_authen.c client_count.c \
config.c default_fn.c default_v0_fn.c do_acct.c do_author.c dump.c enable.c \
encrypt.c expire.c hash.c maxsessint.c parse.c programs.c pw.c pwlib.c \
report.c sendauth.c sendpass.c tac_plus.c utils.c
if TACSKEY
tac_plus_SOURCES += skey_fn.c
endif
if TACACECLNT
tac_plus_SOURCES += aceclnt_fn.c
endif
tac_plus_LDFLAGS = -L$(top_srcdir)
tac_plus_LDADD = $(WRAPLIBS) -ltacacs
lib_LTLIBRARIES = libtacacs.la
libtacacs_la_SOURCES = md4.c md5.c packet.c
libtacacs_la_SOURCES = fdes.c maxsess.c md4.c md5.c packet.c
libtacacs_la_CFLAGS = @CFLAGS@ $(WARN) $(DBG) @PROFLAGS@
#libtacacs_la_LIBADD = -lrib -lctsdb
#libtacacs_la_LIBADD = -lxxx
libtacacs_la_LDFLAGS = -version-info 1:0:0 -version-number 1:0:0
libtacacs_la_LDFLAGS += @LDFLAGS@ @PROFLIBS@
BUILT_SOURCES =
# profiling
CFLAGS += $(WARN) $(DBG) $(PROFLAGS)
CFLAGS += $(WARN) $(DBG) $(PROFLAGS) $(WRAPINCS)
LDADD = $(PROFLIBS)
INCLUDES = $(WRAPINCS)
# CPPFLAGS += @PG_CPPFLAGS@
# INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@
AM_CPPFLAGS = $(WRAPINCS)
# AM_CPPFLAGS += -I$(top_srcdir)/include @PG_CPPFLAGS@
include_HEADERS = tacacs.h
noinst_HEADERS= md4.h mschap.h regexp.h tac_plus.h \
expire.h md5.h parse.h pathsl.h regmagic.h
noinst_HEADERS= fdes.h des_iip.h des_ip.h des_key.h des_s_p.h md4.h mschap.h \
tac_plus.h expire.h md5.h parse.h pathsl.h
man_gen_MANS = tac_plus.8 tac_plus.conf.5
man_nogen_MANS = regexp.3 tac_pwd.8
man_nogen_MANS = tac_pwd.8
man_MANS = $(man_gen_MANS) $(man_nogen_MANS)
@ -49,7 +55,7 @@ pkgdata_SCRIPTS = $(static_scripts) $(build_scripts)
pkgdata_DATA= do_auth.py users_guide
EXTRA_DIST = CHANGES COPYING FAQ INSTALL $(build_scripts:%=%.in) \
$(man_nogen_MANS) do_auth.py users_guide.in
$(man_nogen_MANS) do_auth.py tacacs+.spec users_guide.in
# '.' is here (and at the front) so that distclean-recursive
# will run make distclean in . after the other dirs
@ -58,7 +64,7 @@ EXTRA_DIST = CHANGES COPYING FAQ INSTALL $(build_scripts:%=%.in) \
# DIST_COMMON = Makefile.am Makefile.in TODO aclocal.m4
# no idea why automake screws up cleaning these targets
DISTCLEANFILES= config.status $(build_scripts)
DISTCLEANFILES= config.status $(build_scripts) users_guide
# CLEANFILES = Makefile $(man_gen_MANS)
# auto_edit does the autoconf variable substitution. This allows the
@ -89,4 +95,3 @@ users_guide: Makefile $(srcdir)/users_guide.in
rm -f users_guide users_guide.tmp; \
$(auto_edit) $(srcdir)/users_guide.in >users_guide.tmp; \
mv users_guide.tmp users_guide

View File

@ -41,6 +41,14 @@ accounting(u_char *pak)
acct_pak = (struct acct *)(pak + TAC_PLUS_HDR_SIZE);
/* Do some sanity checking on the packet */
/* Check if there's at least sizeof(struct acct) of useful data */
if (ntohl(hdr->datalength) < TAC_ACCT_REQ_FIXED_FIELDS_SIZE) {
report(LOG_ERR, "%s: acct minimum payload length: %zu, got: %u",
session.peer, TAC_ACCT_REQ_FIXED_FIELDS_SIZE,
ntohl(hdr->datalength));
send_error_reply(TAC_PLUS_ACCT, NULL);
return;
}
/* arg counts start here */
p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
@ -49,6 +57,17 @@ accounting(u_char *pak)
len = TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
len += acct_pak->user_len + acct_pak->port_len +
acct_pak->rem_addr_len + acct_pak->arg_cnt;
/* Is there enough space for acct_pak->length arguments */
if (ntohl(hdr->datalength) <
(TAC_ACCT_REQ_FIXED_FIELDS_SIZE + acct_pak->arg_cnt)) {
report(LOG_ERR, "%s: acct minimum payload: %zu, got: %u",
session.peer, TAC_ACCT_REQ_FIXED_FIELDS_SIZE + acct_pak->arg_cnt,
ntohl(hdr->datalength));
send_error_reply(TAC_PLUS_ACCT, NULL);
return;
}
for (i = 0; i < (int)acct_pak->arg_cnt; i++) {
len += p[i];
}

View File

@ -0,0 +1,246 @@
/*
* $Id: aceclnt_fn.c,v 1.00 2012-02-24 18:40:20 maddison Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "tac_plus.h"
#include "expire.h"
/* internal state variables */
#define STATE_AUTHEN_START 0 /* no requests issued */
#define STATE_AUTHEN_GETUSER 1 /* username has been requested */
#define STATE_AUTHEN_GETPASS 2 /* password has been requested */
#include <acexport.h>
struct private_data {
SDI_HANDLE SdiHandle;
char password[MAX_PASSWD_LEN + 1];
int state;
};
/*
* Use aceclnt to verify a supplied password using state set up earlier
* when the username was supplied.
*/
static int
aceclnt_verify(char *name, char *passwd, struct authen_data *data)
{
struct private_data *p = data->method_data;
SDI_HANDLE SdiHandle = p->SdiHandle;
int acmRet;
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
/*
if (aceclntverify(aceclntp, passwd) == 0) {
*//* S/Key authentication succeeded *//*
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
if (aceclntp->n < 5) {
data->server_msg = tac_strdup("Password will expire soon");
return(1);
}
} */
acmRet = SD_Check(SdiHandle, passwd, name);
if (acmRet == ACM_OK)
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
return(0);
}
/*
* aceclnt tacacs login authentication function. Wants a username
* and a password, and tries to verify them via aceclnt.
*
* Choose_authen will ensure that we already have a username before this
* gets called.
*
* We will query for a password and keep it in the method_data.
*
* Any strings returned via pointers in authen_data must come from the
* heap. They will get freed by the caller.
*
* Return 0 if data->status is valid, otherwise 1
*/
int
aceclnt_fn(struct authen_data *data)
{
#define ACEBUFSZ 256
char buf[ACEBUFSZ];
char *name, *passwd;
struct private_data *p;
char *prompt;
int pwlen, acmRet;
p = (struct private_data *)data->method_data;
/* An abort has been received. Clean up and return */
if (data->flags & TAC_PLUS_CONTINUE_FLAG_ABORT) {
if (p->SdiHandle) {
SD_Close(p->SdiHandle);
}
if (data->method_data)
free(data->method_data);
data->method_data = NULL;
return(1);
}
/* Initialise method_data if first time through */
if (!p) {
p = (struct private_data *)tac_malloc(sizeof(struct private_data));
memset(p, 0, sizeof(struct private_data));
data->method_data = p;
p->state = STATE_AUTHEN_START;
p->SdiHandle = SDI_HANDLE_NONE;
acmRet = SD_Init(&(p->SdiHandle));
if (acmRet != ACM_OK) {
report(LOG_ERR, "%s: aceclnt_fn unable to contact ACE %d",
session.peer, p->state);
if (p->SdiHandle) {
SD_Close(p->SdiHandle);
}
return(1);
}
}
/* Unless we are enabling, we need a username */
if (data->service != TAC_PLUS_AUTHEN_SVC_ENABLE &&
(char)data->NAS_id->username[0] == '\0') {
switch (p->state) {
case STATE_AUTHEN_GETUSER:
/* we have previously asked for a username but none came back.
* This is a gross error */
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
report(LOG_ERR, "%s: No username supplied after GETUSER",
session.peer);
return(0);
case STATE_AUTHEN_START:
/* No username. Try requesting one */
data->status = TAC_PLUS_AUTHEN_STATUS_GETUSER;
if (data->service == TAC_PLUS_AUTHEN_SVC_LOGIN) {
prompt = "\nUser Access Verification\n\nUsername: ";
} else {
prompt = "Username: ";
}
data->server_msg = tac_strdup(prompt);
p->state = STATE_AUTHEN_GETUSER;
return(0);
default:
/* something awful has happened. Give up and die */
report(LOG_ERR, "%s: aceclnt_fn bad state %d",
session.peer, p->state);
SD_Close(p->SdiHandle);
return(1);
}
}
/* we now have a username if we needed one */
name = data->NAS_id->username;
/* Do we have a password? */
passwd = p->password;
if (passwd[0] == '\0') {
/* no password yet. Either we need to ask for one and expect to get
* called again, or we asked but nothing came back, which is fatal
*/
switch (p->state) {
case STATE_AUTHEN_GETPASS:
/* We already asked for a password. This should be the reply */
if (data->client_msg) {
pwlen = MIN(strlen(data->client_msg), MAX_PASSWD_LEN);
} else {
pwlen = 0;
}
strncpy(passwd, data->client_msg, pwlen);
passwd[pwlen] = '\0';
break;
default:
/* Request a password */
passwd = cfg_get_login_secret(name, TAC_PLUS_RECURSE);
if (!passwd && !STREQ(passwd, "aceclnt")) {
report(LOG_ERR, "Cannot find aceclnt password declaration for"
" %s", name);
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
SD_Close(p->SdiHandle);
return(1);
}
/* lock the ACE User */
acmRet = SD_Lock(p->SdiHandle, name);
if (acmRet != ACM_OK) {
report(LOG_ERR, "ACE Server name lock failed for %s", name);
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
SD_Close(p->SdiHandle);
return(1);
}
snprintf(buf, ACEBUFSZ, "Enter PASSCODE: ");
data->server_msg = tac_strdup(buf);
data->status = TAC_PLUS_AUTHEN_STATUS_GETPASS;
p->state = STATE_AUTHEN_GETPASS;
return(0);
}
}
/* We have a username and password. Try validating */
/* Assume the worst */
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
switch (data->service) {
case TAC_PLUS_AUTHEN_SVC_LOGIN:
case TAC_PLUS_AUTHEN_SVC_ENABLE:
aceclnt_verify(name, passwd, data);
if (debug)
report(LOG_INFO, "login/enable query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
data->NAS_id->NAS_port && data->NAS_id->NAS_port[0] ?
data->NAS_id->NAS_port : "unknown",
session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
"accepted" : "rejected");
break;
default:
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
report(LOG_ERR, "%s: Bogus service value %d from packet",
session.peer, data->service);
break;
}
if (p->SdiHandle)
SD_Close(p->SdiHandle);
if (data->method_data)
free(data->method_data);
data->method_data = NULL;
switch (data->status) {
case TAC_PLUS_AUTHEN_STATUS_ERROR:
case TAC_PLUS_AUTHEN_STATUS_FAIL:
case TAC_PLUS_AUTHEN_STATUS_PASS:
return(0);
default:
report(LOG_ERR, "%s: aceclnt_fn couldn't set recognizable status %d",
session.peer, data->status);
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
return(1);
}
}

1099
tacacs-F4.0.4.28/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

347
tacacs-F4.0.4.28/aconf/compile Executable file
View File

@ -0,0 +1,347 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2008-09-28'
timestamp='2013-05-16'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@ -17,26 +15,22 @@ timestamp='2008-09-28'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
# Originally written by Per Bothner.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
me=`echo "$0" | sed -e 's,.*/,,'`
@ -56,8 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@ -170,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@ -300,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@ -324,14 +345,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
eval $set_cc_for_build
SUN_ARCH="i386"
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH="x86_64"
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@ -532,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[456])
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@ -640,7 +680,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep __LP64__ >/dev/null
grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@ -769,21 +809,21 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
UNAME_PROCESSOR=`/usr/bin/uname -p`
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
@ -791,12 +831,12 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:[3456]*)
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd | genuineintel)
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
@ -806,6 +846,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@ -826,100 +869,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
fi
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@ -931,105 +895,125 @@ EOF
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^LIBC/{
s: ::g
p
}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
}
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@ -1058,7 +1042,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@ -1102,8 +1086,11 @@ EOF
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
@ -1141,6 +1128,16 @@ EOF
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@ -1153,7 +1150,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@ -1219,6 +1216,9 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@ -1245,9 +1245,21 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@ -1261,7 +1273,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@ -1327,11 +1342,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_

View File

@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2008-09-08'
timestamp='2013-04-24'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@ -72,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -120,12 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@ -148,10 +149,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@ -214,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@ -226,7 +236,7 @@ case $os in
-psos*)
os=-psos
;;
-freemint | -mint | -mint[0-9]*)
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
@ -238,19 +248,27 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@ -268,31 +286,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| or32 \
| open8 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@ -302,6 +334,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@ -316,24 +363,30 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@ -351,28 +404,34 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
@ -414,12 +473,6 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@ -443,6 +496,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@ -459,6 +516,19 @@ case $basic_machine in
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
@ -495,7 +565,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@ -653,7 +723,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@ -711,6 +780,13 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
@ -747,10 +823,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@ -815,6 +899,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@ -897,9 +987,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@ -924,7 +1015,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
@ -993,6 +1088,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@ -1049,20 +1147,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@ -1132,6 +1218,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@ -1182,7 +1271,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@ -1232,6 +1321,9 @@ case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@ -1252,21 +1344,23 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@ -1274,7 +1368,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1398,15 +1492,14 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@ -1447,6 +1540,18 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@ -1465,9 +1570,6 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
@ -1481,6 +1583,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
@ -1604,7 +1709,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-aix*)
-cnk*|-aix*)
vendor=ibm
;;
-beos*)

View File

@ -1,10 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2009-04-28.21; # UTC
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
# Software Foundation, Inc.
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -28,7 +27,7 @@ scriptversion=2009-04-28.21; # UTC
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
@ -40,11 +39,11 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
@ -57,6 +56,66 @@ EOF
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
@ -69,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
@ -90,10 +152,24 @@ if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u="sed s,\\\\\\\\,/,g"
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
@ -114,8 +190,7 @@ gcc3)
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@ -123,13 +198,17 @@ gcc3)
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
@ -137,31 +216,31 @@ gcc)
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well.
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@ -179,8 +258,7 @@ sgi)
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@ -188,43 +266,41 @@ sgi)
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
@ -237,9 +313,7 @@ aix)
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
@ -248,44 +322,100 @@ aix)
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
"$@" -MD -MF "$tmpdepfile"
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
if test $stat -eq 0; then :
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@ -297,8 +427,8 @@ icc)
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@ -309,9 +439,8 @@ hp2)
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
@ -322,8 +451,7 @@ hp2)
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
@ -333,8 +461,8 @@ hp2)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
@ -342,67 +470,97 @@ hp2)
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
echo "#dummy" > "$depfile"
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
@ -422,7 +580,7 @@ dashmstdout)
shift
fi
# Remove `-o $object'.
# Remove '-o $object'.
IFS=" "
for arg
do
@ -442,18 +600,18 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@ -503,12 +661,15 @@ makedepend)
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
@ -525,7 +686,7 @@ cpp)
shift
fi
# Remove `-o $object'.
# Remove '-o $object'.
IFS=" "
for arg
do
@ -544,10 +705,10 @@ cpp)
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
@ -594,8 +755,8 @@ msvisualcpp)
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;

527
tacacs-F4.0.4.28/aconf/install-sh Executable file
View File

@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

7982
tacacs-F4.0.4.28/aconf/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

384
tacacs-F4.0.4.28/aconf/ltoptions.m4 vendored Normal file
View File

@ -0,0 +1,384 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

123
tacacs-F4.0.4.28/aconf/ltsugar.m4 vendored Normal file
View File

@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
tacacs-F4.0.4.28/aconf/ltversion.m4 vendored Normal file
View File

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 3337 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.2])
m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.2'
macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

98
tacacs-F4.0.4.28/aconf/lt~obsolete.m4 vendored Normal file
View File

@ -0,0 +1,98 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

215
tacacs-F4.0.4.28/aconf/missing Executable file
View File

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -38,6 +38,15 @@ authen(u_char *pak)
hdr = (HDR *)pak;
start = (struct authen_start *)(pak + TAC_PLUS_HDR_SIZE);
/* Must be at least sizeof(struct authen_start) in size */
if (ntohl(hdr->datalength) < TAC_AUTHEN_START_FIXED_FIELDS_SIZE) {
report(LOG_ERR, "%s: authen minimum payload length: %zu, got: %u",
session.peer, TAC_AUTHEN_START_FIXED_FIELDS_SIZE,
ntohl(hdr->datalength));
send_authen_error("Invalid AUTHEN/START packet (too short)");
return;
}
if ((hdr->seq_no != 1) ||
(ntohl(hdr->datalength) != TAC_AUTHEN_START_FIXED_FIELDS_SIZE +
start->user_len + start->port_len + start->rem_addr_len +
@ -53,7 +62,8 @@ authen(u_char *pak)
do_start(pak);
return;
default:
sprintf(msg, "Invalid AUTHEN/START action=%d", start->action);
snprintf(msg, sizeof(msg), "Invalid AUTHEN/START action=%d",
start->action);
send_authen_error(msg);
return;
}
@ -166,6 +176,9 @@ do_start(u_char *pak)
}
free(identity.username);
free(identity.NAS_name);
#ifdef ACLS
free(identity.NAS_ip);
#endif
free(identity.NAS_port);
free(identity.NAC_address);
return;

View File

@ -51,12 +51,32 @@ author(u_char *pak)
return;
}
/* Check if there's at least sizeof(struct author) of useful data */
if (ntohl(hdr->datalength) < TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE) {
report(LOG_ERR, "%s: author minimum payload length: %zu, got: %u",
session.peer, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE,
ntohl(hdr->datalength));
send_error_reply(TAC_PLUS_AUTHOR, NULL);
return;
}
/* arg counts start here */
p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
/* Length checks */
len = TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
len += apak->user_len + apak->port_len + apak->rem_addr_len + apak->arg_cnt;
/* Is there enough space for apak->arg_cnt arguments? */
if (ntohl(hdr->datalength) <
(TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE + apak->arg_cnt)) {
report(LOG_ERR, "%s: author minimum payload length: %zu, got: %u",
session.peer, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE + apak->arg_cnt,
ntohl(hdr->datalength));
send_error_reply(TAC_PLUS_AUTHOR, NULL);
return;
}
for (i = 0; i < (int)apak->arg_cnt; i++) {
len += p[i];
}
@ -124,26 +144,23 @@ author(u_char *pak)
#ifdef ACLS
authen_data.NAS_id = &identity;
if (verify_host(author_data.id->username,
&authen_data, S_acl, TAC_PLUS_RECURSE) != S_permit) {
if (verify_host(author_data.id->username, &authen_data, S_acl,
TAC_PLUS_RECURSE) != S_permit) {
author_data.status = AUTHOR_STATUS_FAIL;
} else
#endif
if (do_author(&author_data)) {
report(LOG_ERR, "%s: do_author returned an error", session.peer);
send_author_reply(AUTHOR_STATUS_ERROR,
author_data.msg,
author_data.admin_msg,
author_data.msg, author_data.admin_msg,
author_data.num_out_args,
author_data.output_args);
return;
}
/* Send a reply packet */
send_author_reply(author_data.status,
author_data.msg,
author_data.admin_msg,
author_data.num_out_args,
send_author_reply(author_data.status, author_data.msg,
author_data.admin_msg, author_data.num_out_args,
author_data.output_args);
if (debug)
@ -183,6 +200,9 @@ author(u_char *pak)
free(identity.username);
free(identity.NAS_name);
#ifdef ACLS
free(identity.NAS_ip);
#endif
free(identity.NAS_port);
free(identity.NAC_address);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,273 @@
# This file was generated.
# It contains the lists of macros which have been traced.
# It can be safely removed.
@request = (
bless( [
'0',
1,
[
'/usr/share/autoconf'
],
[
'/usr/share/autoconf/autoconf/autoconf.m4f',
'-',
'/usr/share/aclocal-1.13/internal/ac-config-macro-dirs.m4',
'/usr/share/aclocal-1.13/amversion.m4',
'/usr/share/aclocal-1.13/auxdir.m4',
'/usr/share/aclocal-1.13/cond.m4',
'/usr/share/aclocal-1.13/depend.m4',
'/usr/share/aclocal-1.13/depout.m4',
'/usr/share/aclocal-1.13/init.m4',
'/usr/share/aclocal-1.13/install-sh.m4',
'/usr/share/aclocal-1.13/lead-dot.m4',
'/usr/share/aclocal-1.13/lex.m4',
'/usr/share/aclocal-1.13/maintainer.m4',
'/usr/share/aclocal-1.13/make.m4',
'/usr/share/aclocal-1.13/missing.m4',
'/usr/share/aclocal-1.13/options.m4',
'/usr/share/aclocal-1.13/runlog.m4',
'/usr/share/aclocal-1.13/sanity.m4',
'/usr/share/aclocal-1.13/silent.m4',
'/usr/share/aclocal-1.13/strip.m4',
'/usr/share/aclocal-1.13/substnot.m4',
'/usr/share/aclocal-1.13/tar.m4',
'aconf/acx_pthread.m4',
'aconf/libtool.m4',
'aconf/ltoptions.m4',
'aconf/ltsugar.m4',
'aconf/ltversion.m4',
'aconf/lt~obsolete.m4',
'configure.ac'
],
{
'AM_ENABLE_STATIC' => 1,
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
'_LT_AC_SHELL_INIT' => 1,
'AC_DEFUN' => 1,
'_LT_AC_LANG_CXX_CONFIG' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AM_SUBST_NOTMAKE' => 1,
'AM_MISSING_PROG' => 1,
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
'_LT_AC_LANG_C_CONFIG' => 1,
'AM_PROG_INSTALL_STRIP' => 1,
'_m4_warn' => 1,
'AC_LIBTOOL_OBJDIR' => 1,
'AM_SANITY_CHECK' => 1,
'LTOBSOLETE_VERSION' => 1,
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
'LT_LIB_M' => 1,
'_LT_AC_CHECK_DLFCN' => 1,
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
'LTSUGAR_VERSION' => 1,
'_LT_PROG_LTMAIN' => 1,
'_AM_PROG_TAR' => 1,
'AC_LIBTOOL_GCJ' => 1,
'_LT_WITH_SYSROOT' => 1,
'_LT_AC_LANG_F77' => 1,
'AC_LIBTOOL_CONFIG' => 1,
'AC_CONFIG_MACRO_DIR' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'_AM_AUTOCONF_VERSION' => 1,
'AM_DISABLE_SHARED' => 1,
'_LT_PROG_ECHO_BACKSLASH' => 1,
'_LT_AC_LANG_CXX' => 1,
'AM_PROG_LIBTOOL' => 1,
'_LT_AC_FILE_LTDLL_C' => 1,
'AM_PROG_LD' => 1,
'AU_DEFUN' => 1,
'AC_PROG_NM' => 1,
'AC_LIBTOOL_DLOPEN' => 1,
'AC_PROG_LD' => 1,
'AC_ENABLE_FAST_INSTALL' => 1,
'AC_PROG_LD_GNU' => 1,
'AC_LIBTOOL_FC' => 1,
'_AM_SET_OPTION' => 1,
'AC_LTDL_PREOPEN' => 1,
'_LT_LINKER_BOILERPLATE' => 1,
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
'AC_LIBTOOL_PROG_CC_C_O' => 1,
'LT_SUPPORTED_TAG' => 1,
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'LT_PROG_RC' => 1,
'AC_DEFUN_ONCE' => 1,
'_LT_AC_LANG_GCJ' => 1,
'AC_LTDL_OBJDIR' => 1,
'_LT_PATH_TOOL_PREFIX' => 1,
'AC_LIBTOOL_RC' => 1,
'AC_DISABLE_FAST_INSTALL' => 1,
'AM_SILENT_RULES' => 1,
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
'include' => 1,
'_LT_AC_SYS_LIBPATH_AIX' => 1,
'_LT_AC_TRY_DLOPEN_SELF' => 1,
'LT_AC_PROG_SED' => 1,
'AM_ENABLE_SHARED' => 1,
'_LT_AC_LANG_GCJ_CONFIG' => 1,
'AC_ENABLE_SHARED' => 1,
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
'AC_ENABLE_STATIC' => 1,
'_LT_AC_TAGVAR' => 1,
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
'AM_CONDITIONAL' => 1,
'LTVERSION_VERSION' => 1,
'_LT_PROG_F77' => 1,
'_LT_PROG_CXX' => 1,
'AM_PROG_INSTALL_SH' => 1,
'm4_include' => 1,
'AC_PROG_EGREP' => 1,
'AC_PATH_MAGIC' => 1,
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
'AM_MAKE_INCLUDE' => 1,
'_LT_AC_TAGCONFIG' => 1,
'LT_CMD_MAX_LEN' => 1,
'm4_pattern_forbid' => 1,
'_LT_LINKER_OPTION' => 1,
'AC_LIBTOOL_COMPILER_OPTION' => 1,
'AC_DISABLE_SHARED' => 1,
'_LT_COMPILER_BOILERPLATE' => 1,
'AC_LIBTOOL_WIN32_DLL' => 1,
'AC_LIBTOOL_SETUP' => 1,
'AC_PROG_LD_RELOAD_FLAG' => 1,
'AM_MISSING_HAS_RUN' => 1,
'LT_LANG' => 1,
'LT_OUTPUT' => 1,
'AC_LIBTOOL_DLOPEN_SELF' => 1,
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
'_AM_CONFIG_MACRO_DIRS' => 1,
'AC_LIBTOOL_LINKER_OPTION' => 1,
'AC_LIBTOOL_CXX' => 1,
'LT_AC_PROG_RC' => 1,
'LT_INIT' => 1,
'LT_SYS_DLOPEN_SELF' => 1,
'LT_AC_PROG_GCJ' => 1,
'AM_DISABLE_STATIC' => 1,
'AM_DEP_TRACK' => 1,
'_LT_AC_PROG_CXXCPP' => 1,
'_AC_PROG_LIBTOOL' => 1,
'_AM_IF_OPTION' => 1,
'AC_PATH_TOOL_PREFIX' => 1,
'm4_pattern_allow' => 1,
'AC_LIBTOOL_F77' => 1,
'AM_SET_LEADING_DOT' => 1,
'LT_AC_PROG_EGREP' => 1,
'_LT_PROG_FC' => 1,
'_AM_DEPENDENCIES' => 1,
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
'LTOPTIONS_VERSION' => 1,
'_LT_AC_SYS_COMPILER' => 1,
'AM_PROG_NM' => 1,
'AC_DEPLIBS_CHECK_METHOD' => 1,
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
'AC_LTDL_ENABLE_INSTALL' => 1,
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
'LT_PROG_GCJ' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_DISABLE_STATIC' => 1,
'LT_PATH_NM' => 1,
'AM_MAINTAINER_MODE' => 1,
'_LT_AC_LOCK' => 1,
'_LT_AC_LANG_RC_CONFIG' => 1,
'LT_PROG_GO' => 1,
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
'AM_AUX_DIR_EXPAND' => 1,
'_LT_AC_LANG_F77_CONFIG' => 1,
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
'_LT_COMPILER_OPTION' => 1,
'_AM_SET_OPTIONS' => 1,
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
'AM_RUN_LOG' => 1,
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
'AC_LIBTOOL_PICMODE' => 1,
'AM_PROG_LEX' => 1,
'AC_CHECK_LIBM' => 1,
'LT_PATH_LD' => 1,
'ACX_PTHREAD' => 1,
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
'_AM_MANGLE_OPTION' => 1,
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
'AM_SET_DEPDIR' => 1,
'_LT_CC_BASENAME' => 1
}
], 'Autom4te::Request' ),
bless( [
'1',
1,
[
'/usr/share/autoconf'
],
[
'/usr/share/autoconf/autoconf/autoconf.m4f',
'aclocal.m4',
'configure.ac'
],
{
'AM_PROG_F77_C_O' => 1,
'_LT_AC_TAGCONFIG' => 1,
'AC_INIT' => 1,
'm4_pattern_forbid' => 1,
'AC_CANONICAL_TARGET' => 1,
'_AM_COND_IF' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_SUBST' => 1,
'AM_EXTRA_RECURSIVE_TARGETS' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_FC_SRCEXT' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_PROG_MKDIR_P' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_PATH_GUILE' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_CONFIG_LINKS' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'LT_SUPPORTED_TAG' => 1,
'm4_sinclude' => 1,
'AM_MAINTAINER_MODE' => 1,
'AM_NLS' => 1,
'AC_FC_PP_DEFINE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'_m4_warn' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'AM_PROG_CXX_C_O' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'_AM_COND_ENDIF' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AM_SILENT_RULES' => 1,
'AM_PROG_MOC' => 1,
'AC_CONFIG_FILES' => 1,
'include' => 1,
'LT_INIT' => 1,
'AM_GNU_GETTEXT' => 1,
'AM_PROG_AR' => 1,
'AC_LIBSOURCE' => 1,
'AC_CANONICAL_BUILD' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_FC_FREEFORM' => 1,
'AC_FC_PP_SRCEXT' => 1,
'AH_OUTPUT' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'm4_pattern_allow' => 1,
'AM_PROG_CC_C_O' => 1,
'sinclude' => 1,
'AM_CONDITIONAL' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_XGETTEXT_OPTION' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AM_POT_TOOLS' => 1,
'm4_include' => 1,
'_AM_COND_ELSE' => 1,
'AC_SUBST_TRACE' => 1
}
], 'Autom4te::Request' )
);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ static int choose_sendauth(struct authen_data *, struct authen_type *);
int
choose_authen(struct authen_data *data, struct authen_type *type)
{
#ifdef SKEY
#if defined(SKEY) || defined(ACECLNT)
char *cfg_passwd;
#endif
char *name = data->NAS_id->username;
@ -54,15 +54,24 @@ choose_authen(struct authen_data *data, struct authen_type *type)
/* must be version 0 */
break;
}
#ifdef SKEY
#if defined(SKEY) || defined(ACECLNT)
if (name[0] == '\0')
return(CHOOSE_GETUSER);
cfg_passwd = cfg_get_enable_secret(name, TAC_PLUS_RECURSE);
#endif
#ifdef SKEY
if (cfg_passwd != NULL && STREQ(cfg_passwd, "skey")) {
type->authen_func = skey_fn;
strcpy(type->authen_name, "skey_fn");
return(CHOOSE_OK);
}
#endif
#ifdef ACECLNT
if (cfg_passwd != NULL && STREQ(cfg_passwd, "aceclnt")) {
type->authen_func = aceclnt_fn;
strcpy(type->authen_name, "aceclnt_fn");
return(CHOOSE_OK);
}
#endif
type->authen_func = enable_fn;
strcpy(type->authen_name, "enable_fn");
@ -127,7 +136,29 @@ choose_login(struct authen_data *data, struct authen_type *type)
#endif /* SKEY */
}
/* Not an skey user. Must be none, des, cleartext or file password */
/* Does this user require aceclnt */
cfg_passwd = cfg_get_login_secret(name, TAC_PLUS_RECURSE);
if (cfg_passwd && STREQ(cfg_passwd, "aceclnt")) {
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "%s %s: user %s requires aceclnt",
session.peer, session.port, name);
#ifdef ACECLNT
type->authen_func = aceclnt_fn;
strcpy(type->authen_name, "aceclnt_fn");
return(CHOOSE_OK);
#else /* ACECLNT */
report(LOG_ERR,
"%s %s: user %s aceclnt support has not been compiled in",
name ? name : "<unknown>",
session.peer, session.port);
return(CHOOSE_FAILED);
#endif /* ACECLNT */
}
/*
* Not an skey or aceclnt user. Must be none, des, cleartext or file
* password
*/
type->authen_func = default_fn;
strcpy(type->authen_name, "default_fn");
return(CHOOSE_OK);
@ -170,8 +201,9 @@ choose_login(struct authen_data *data, struct authen_type *type)
return(CHOOSE_OK);
}
/* Version 1 login/[pap|chap|arap].
* The username must in the initial START packet
/*
* Version 1 login/[pap|chap|arap].
* The username must be in the initial START packet
*/
if (!name[0]) {
report(LOG_ERR, "%s %s: No user in START packet for PAP/CHAP/ARAP",

View File

@ -20,7 +20,14 @@
*/
#include "tac_plus.h"
#include "regexp.h"
#include <regex.h>
#ifndef REG_OK
# ifdef REG_NOERROR
# define REG_OK REG_NOERROR
# else
# define REG_OK 0
# endif
#endif
/*
<config> := <decl>*
@ -34,7 +41,6 @@
<top_level_decl> := <authen_default> |
accounting file = <filename> |
accounting syslog |
default authorization = <permission> |
key = <string> |
logging = <syslog_fac> |
maxprocs = <maxprocs> |
@ -54,8 +60,9 @@
<host_decl> := host = <string> {
key = <string>
prompt = <string>
enable = (file|skey|cleartext|des|
nopassword) <filename/string>
enable = aceclnt|cleartext|des|
file <filename/string>|
nopassword|skey
}
<user_decl> := user = <string> {
@ -64,14 +71,17 @@
<svc>*
}
<password_spec> := file <filename> |
skey |
<password_spec> := nopassword |
#ifdef ACECLNT
aceclnt|
#endif
cleartext <password> |
des <password> |
file <filename> |
#ifdef HAVE_PAM
PAM |
#endif
nopassword
skey
<user_attr> := name = <string> |
login = <password_spec> |
@ -101,8 +111,12 @@
<cmd-match> := <permission> <string>
<svc_auth> := service = ( exec | arap | slip |
ppp protocol = <string>) {
<proto> := XXX define this
<svc_auth> := service = ( arap | connection | exec |
ppp protocol = <proto> | shell |
slip | system | tty-daemon |
<client defined> ) {
[ default attribute = permit ]
<attr_value_pair>*
}
@ -118,14 +132,13 @@ static int sym_code; /* parser output */
static int sym_line = 1; /* current line number */
static FILE *cf = NULL; /* config file pointer */
static int sym_error = 0; /* a parsing error occurred */
static int no_user_dflt = 0; /* default if user doesn't exist */
static char *authen_default = NULL; /* top level authentication default */
static long int maxprocs = TAC_MAX_PROCS; /* max procs to fork */
static long int maxprocsperclt = TAC_MAX_PROCS_PER_CLIENT; /* max procs to fork per client */
static long int readtimeout = TAC_PLUS_READ_TIMEOUT;
static long int writetimeout = TAC_PLUS_WRITE_TIMEOUT;
static long int accepttimeout = TAC_PLUS_ACCEPT_TIMEOUT;
static char *nopasswd_str = "nopassword";
static long int maxprocs = TAC_MAX_PROCS; /* max procs to fork */
static long int maxprocsperclt = TAC_MAX_PROCS_PER_CLIENT; /* max per client */
static long int readtimeout = TAC_PLUS_READ_TIMEOUT; /* read timeout */
static long int writetimeout = TAC_PLUS_WRITE_TIMEOUT; /* write timeout */
static long int accepttimeout = TAC_PLUS_ACCEPT_TIMEOUT; /* accept timeout */
/*
* A host definition structure.
@ -191,39 +204,35 @@ typedef struct user {
int maxsess; /* Max sessions/user */
#endif /* MAXSESS */
} USER;
typedef USER GROUP;
#ifdef ACLS
struct filter {
typedef struct filter {
int isdeny;
char *string;
regexp *string_reg;
regex_t *string_reg;
struct filter *next;
};
typedef struct filter FILTER;
} FILTER;
struct acl {
typedef struct acl {
char *name; /* acl name */
void *hash; /* hash table next pointer */
int line; /* line number defined on */
NODE *nodes; /* list of entrys */
};
typedef struct acl ACL;
} ACL;
#endif
/*
* Only the first 2 fields (name and hash) are used by the hash table
* routines to hash structures into a table.
*/
union hash {
typedef union hash {
struct user u;
#ifdef ACLS
struct acl a;
#endif
struct host h;
};
typedef union hash HASH;
} HASH;
void *grouptable[HASH_TAB_SIZE];/* Table of group declarations */
void *usertable[HASH_TAB_SIZE]; /* Table of user declarations */
@ -648,8 +657,10 @@ parse_opt_attr_default(void)
static int
insert_acl_entry(ACL *acl, int isdeny)
{
char buf[256];
NODE *next = acl->nodes;
NODE *entry = (NODE *)tac_malloc(sizeof(NODE));
int ecode;
memset(entry, 0, sizeof(NODE));
@ -658,9 +669,13 @@ insert_acl_entry(ACL *acl, int isdeny)
entry->line = sym_line;
/* compile the regex */
entry->value1 = (void *) regcomp((char *) entry->value);
if (!entry->value1) {
entry->value1 = tac_malloc(sizeof(regex_t));
ecode = regcomp((regex_t *)entry->value1, (char *)entry->value,
(REG_EXTENDED | REG_NOSUB));
if (ecode) {
regerror(ecode, (regex_t *)entry->value1, buf, 256);
report(LOG_ERR, "in regex %s on line %d", sym_buf, sym_line);
report(LOG_ERR, "regex compile failed: %s", buf);
tac_exit(1);
}
@ -738,7 +753,6 @@ parse_acl(void)
static int
parse_decls()
{
no_user_dflt = 0; /* default if user doesn't exist */
sym_code = 0;
rch();
@ -783,8 +797,8 @@ parse_decls()
sym_get();
switch (sym_code) {
default:
parse_error("Expecting default authorization/authentication "
"on lines %d", sym_line);
parse_error("Expecting default authentication on line %d",
sym_line);
return(1);
case S_authentication:
@ -799,15 +813,6 @@ parse_decls()
authen_default = tac_strdup(sym_buf);
sym_get();
continue;
case S_authorization:
parse(S_authorization);
parse(S_separator);
parse(S_permit);
no_user_dflt = S_permit;
report(LOG_NOTICE, "default authorization = permit is now "
"deprecated. Please use user = DEFAULT instead");
continue;
}
case S_key:
@ -1128,7 +1133,6 @@ parse_user(void)
case S_svc:
case S_cmd:
if (user->svcs) {
/*
* Already parsed some services/commands. Thanks to Gabor Kiss
@ -1160,6 +1164,12 @@ parse_user(void)
break;
#endif
#ifdef ACECLNT
case S_aceclnt:
user->login = tac_strdup(sym_buf);
break;
#endif
#ifdef HAVE_PAM
case S_pam:
user->login = tac_strdup(sym_buf);
@ -1184,22 +1194,18 @@ parse_user(void)
user->login = tac_strdup(buf);
break;
case S_md5:
sprintf(buf, "%s ", sym_buf);
sym_get();
strcat(buf, sym_buf);
user->login = tac_strdup(buf);
break;
default:
parse_error("expecting 'file', 'cleartext', 'nopassword', "
#ifdef SKEY
"'skey', "
#endif
#ifdef ACECLNT
"'aceclnt', "
#endif
#ifdef HAVE_PAM
"'PAM', "
#endif
" 'md5', or 'des' keyword after 'login =' on line %d",
"or 'des' keyword after 'login =' on line %d",
sym_line);
}
sym_get();
@ -1216,6 +1222,13 @@ parse_user(void)
parse(S_separator);
switch(sym_code) {
#ifdef HAVE_PAM
case S_pam:
user->pap = tac_strdup(sym_buf);
break;
#endif
case S_file:
case S_cleartext:
case S_des:
sprintf(buf, "%s ", sym_buf);
@ -1224,27 +1237,13 @@ parse_user(void)
user->pap = tac_strdup(buf);
break;
case S_md5:
sprintf(buf, "%s ", sym_buf);
sym_get();
strcat(buf, sym_buf);
user->login = tac_strdup(buf);
break;
#ifdef HAVE_PAM
case S_pam:
user->pap = tac_strdup(sym_buf);
break;
#endif
default:
parse_error(
parse_error("expecting 'cleartext', "
#ifdef HAVE_PAM
"expecting 'cleartext', 'PAM,' 'md5', or 'des' keyword after 'pap =' on line %d",
#else
"expecting 'cleartext' 'md5', or 'des' keyword after 'pap =' on line %d",
"'PAM', "
#endif
sym_line);
"or 'des' keyword after "
"'pap =' on line %d", sym_line);
}
sym_get();
continue;
@ -1283,11 +1282,19 @@ parse_user(void)
user->enable = tac_strdup(sym_buf);
break;
#endif
#ifdef ACECLNT
case S_aceclnt:
user->enable = tac_strdup(sym_buf);
break;
#endif
default:
parse_error("expecting 'file', 'cleartext', 'nopassword', "
#ifdef SKEY
"'skey', "
#endif
#ifdef ACECLNT
"'aceclnt', "
#endif
"or 'des' keyword after 'enable =' on line %d",
sym_line);
@ -1428,14 +1435,9 @@ parse_svcs(void)
parse(S_svc);
parse(S_separator);
switch (sym_code) {
default:
parse_error("expecting service type but found %s on line %d",
sym_buf, sym_line);
return(NULL);
case S_string:
result->type = N_svc;
/* should perhaps check that this is an allowable service name */
/* XXX should perhaps check that this is an allowable service name */
result->value1 = tac_strdup(sym_buf);
break;
case S_exec:
@ -1452,9 +1454,13 @@ parse_svcs(void)
parse(S_ppp);
parse(S_protocol);
parse(S_separator);
/* Should perhaps check that this is a known PPP protocol name */
/* XXX Should perhaps check that this is a known PPP protocol name */
result->value1 = tac_strdup(sym_buf);
break;
default:
parse_error("expecting service type but found %s on line %d",
sym_buf, sym_line);
return(NULL);
}
sym_get();
parse(S_openbra);
@ -1469,7 +1475,9 @@ parse_svcs(void)
static NODE *
parse_cmd_matches(void)
{
char buf[256];
NODE *result;
int ecode;
if (sym_code != S_permit && sym_code != S_deny) {
return(NULL);
@ -1482,10 +1490,13 @@ parse_cmd_matches(void)
result->type = (parse_permission() == S_permit) ? N_permit : N_deny;
result->value = tac_strdup(sym_buf);
result->value1 = (void *) regcomp(result->value);
if (!result->value1) {
report(LOG_ERR, "in regular expression %s on line %d",
sym_buf, sym_line);
result->value1 = tac_malloc(sizeof(regex_t));
ecode = regcomp((regex_t *)result->value1, (char *)result->value,
(REG_EXTENDED | REG_NOSUB));
if (ecode) {
regerror(ecode, (regex_t *)result->value1, buf, 256);
report(LOG_ERR, "in regex %s on line %d", sym_buf, sym_line);
report(LOG_ERR, "regex compile failed: %s", buf);
tac_exit(1);
}
sym_get();
@ -1832,9 +1843,11 @@ get_hvalue(HOST *host, int field)
v.pval = host->key;
break;
/*case S_type:
/* XXX
case S_type:
v.pval = host->type;
break;*/
break;
*/
case S_prompt:
v.pval = host->prompt;
@ -2139,7 +2152,7 @@ cfg_acl_check(char *aclname, char *ip)
next = acl->nodes;
while (next) {
if (regexec(next->value1, ip)) {
if (regexec((regex_t *)next->value1, ip, 0, NULL, 0) == REG_OK) {
if (debug & DEBUG_AUTHEN_FLAG)
report(LOG_DEBUG, "ip %s matched %s regex %s of acl filter %s",
ip, next->type == S_deny ? "deny" : "permit",
@ -2516,20 +2529,6 @@ cfg_user_svc_default_is_permit(char *user)
}
}
int
cfg_no_user_permitted(void)
{
if (no_user_dflt == S_permit)
return(1);
return(0);
}
char *
cfg_get_authen_default(void)
{
return(authen_default);
}
int
cfg_get_maxprocs(void)
{
@ -2560,6 +2559,12 @@ cfg_get_accepttimeout(void)
return(accepttimeout);
}
char *
cfg_get_authen_default(void)
{
return(authen_default);
}
/*
* Return 1 if this user has any ppp services configured. Used for
* authorizing ppp/lcp requests

View File

@ -1,10 +1,13 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* config.h.in. Generated from configure.ac by autoheader. */
#ifndef CONFIG_H
#define CONFIG_H 1
/* define this to include support for RSA SecurID */
#undef ACECLNT
/* define this to include ACL support */
#undef ACLS
@ -14,6 +17,10 @@
/* define this if your o/s is AIX */
#undef AIX
/* Define this if you have DES routines you can link to for ARAP (See the user
guide for more details) */
#undef ARAP_DES
/* define this to include debugging support */
#undef DBG
@ -65,6 +72,9 @@
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the <shadow.h> header file. */
#undef HAVE_SHADOW_H
@ -125,6 +135,12 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <utmpx.h> header file. */
#undef HAVE_UTMPX_H
/* Define to 1 if you have the <utmp.h> header file. */
#undef HAVE_UTMP_H
/* Define to 1 if you have the `wait3' function. */
#undef HAVE_WAIT3
@ -149,6 +165,10 @@
/* Define to 1 if `sizeof (long int)' = 8. Obsolete, use `SIZEOF_LONG_INT'. */
#undef LONG_64_BITS
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* define this to include MAXSESS support to enforce a limit on maximum
sessions per user */
#undef MAXSESS
@ -160,9 +180,19 @@
/* define this if your o/s is MIPS */
#undef MIPS
/* Define this if you need MSCHAP support */
#undef MSCHAP
/* Define this if you have DES routines you can link to for MSCHAP (See the
user guide for more details) */
#undef MSCHAP_DES
/* define this if your o/s is NetBSD */
#undef NETBSD
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
@ -175,15 +205,15 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* define this to include profiling */
#undef PROFILE
/* Define to 1 if the C compiler supports function prototypes. */
#undef PROTOTYPES
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
@ -237,6 +267,9 @@
/* define this if your waitpid() takes an union wait status pointer */
#undef UNIONWAIT
/* Version number of package */
#undef VERSION
/* define this to set pedantic gcc warnings */
#undef WARN
@ -256,9 +289,6 @@
`char[]'. */
#undef YYTEXT_POINTER
/* Define like PROTOTYPES; this can be used by system headers. */
#undef __PROTOTYPES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
@ -288,5 +318,44 @@
# define socklen_t int
#endif
/* host specifics */
/* Define this if your password file does not contain age and comment fields. */
#define NO_PWAGE
#if AIX
/*
* The only way to properly compile BSD stuff on AIX is to define a
* "bsdcc" compiler on your system. See /usr/lpp/bos/bsdport on your
* system for details. People who do NOT do this tell me that the code
* still compiles but that it then doesn't behave correctly e.g. child
* processes are not reaped correctly. Don't expect much sympathy if
* you do this.
*/
# define _BSD 1
# define _BSD_INCLUDES
# define NO_PWAGE
#endif /* AIX */
#if LINUX
# define NO_PWAGE
# include <unistd.h>
# ifdef GLIBC
# define CONST_SYSERRLIST
# endif
#endif /* LINUX */
#if NETBSD
# define NO_PWAGE
# define CONST_SYSERRLIST
#endif
#if FREEBSD
# define CONST_SYSERRLIST
# define NO_PWAGE
#endif
#if BSDI
# define NO_PWAGE
#endif
#endif /* CONFIG_H */

17818
tacacs-F4.0.4.28/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,17 @@
dnl Process this file with autoconf to produce a configure script.
dnl A configure script is provided, in cause you do not have autoconf.
AC_PREREQ(2.13)
AC_INIT(CHANGES)
PACKAGE=`sed -n 's/.*package.*"\(.*\)".*/\1/p' $srcdir/version.h.in|tr -d ' '`
VERSION=`sed -n 's/.*version.*"\(.*\)".*/\1/p' $srcdir/version.h.in|tr -d ' '`
AC_PREREQ(2.69)
dnl VERSION needs to be updated in version.h.in such that 'make dist'
dnl uses the correct filename for the directory name and tarball and binaries
dnl get the right version numbers.
AM_INIT_AUTOMAKE($PACKAGE, $VERSION, tac_plus@shrubbery.net)
AC_INIT([tacacs],
m4_esyscmd_s([sed -n 's/.*version.*"\(.*\)".*/\1/p' version.h.in]))
AC_CONFIG_AUX_DIR([aconf])
AC_CONFIG_MACRO_DIR([aconf])
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE()
@ -20,13 +21,13 @@ dnl AC_CONFIG_SUBDIRS(etc man share)
dnl ---- XXX: these really should deal with the individual reasons why
dnl linux/whatever is different, rather than a blanket stmt
dnl is this crack, i mean linux?
AH_TEMPLATE(AIX, [define this if your o/s is AIX])
AH_TEMPLATE(FREEBSD, [define this if your o/s is FreeBSD])
AH_TEMPLATE(NETBSD, [define this if your o/s is NetBSD])
AH_TEMPLATE(SOLARIS, [define this if your o/s is Solaris])
AH_TEMPLATE(HPUX, [define this if your o/s is HPux])
AH_TEMPLATE(LINUX, [define this if your o/s is Linux])
AH_TEMPLATE(MIPS, [define this if your o/s is MIPS])
AH_TEMPLATE([AIX], [define this if your o/s is AIX])
AH_TEMPLATE([FREEBSD], [define this if your o/s is FreeBSD])
AH_TEMPLATE([NETBSD], [define this if your o/s is NetBSD])
AH_TEMPLATE([SOLARIS], [define this if your o/s is Solaris])
AH_TEMPLATE([HPUX], [define this if your o/s is HPux])
AH_TEMPLATE([LINUX], [define this if your o/s is Linux])
AH_TEMPLATE([MIPS], [define this if your o/s is MIPS])
AC_CANONICAL_HOST
case "${host_os}" in
*aix* )
@ -37,7 +38,7 @@ case "${host_os}" in
# CPPFLAGS="$CFLAGS -I/usr/local/include"; export CPPFLAGS
# LDFLAGS="$LDFLAGS -L/usr/local/lib"; export LDFLAGS
# LIBS="-lcrypt $LIBS"; export LIBS
AC_DEFINE(AIX)
AC_DEFINE([AIX])
;;
*freebsd* )
#CPPFLAGS="$CFLAGS -I/usr/pkg/include"; export CPPFLAGS
@ -126,7 +127,6 @@ ACX_PTHREAD([CC=$PTHREAD_CC; CFLAGS="$CFLAGS $PTHREAD_CFLAGS";
# compiler specifics
AC_PROG_CC
AM_C_PROTOTYPES
AC_PROG_CPP
AC_C_CONST
AC_C_INLINE
@ -142,7 +142,7 @@ if test "$LEX" != "flex" ; then
$LEX --version > /dev/null 2>&1
if test $? -ne 0 ; then
AC_MSG_RESULT()
AC_MSG_ERROR([registry requires gnu flex. sorry])
AC_MSG_ERROR([tac_plus requires gnu flex. sorry])
fi
AC_MSG_RESULT(yes)
fi
@ -154,7 +154,7 @@ if test "$YACC" != "bison" ; then
$YACC --version > /dev/null 2>&1
if test $? -ne 0 ; then
AC_MSG_RESULT()
AC_MSG_ERROR([registry requires gnu bison. sorry])
AC_MSG_ERROR([tac_plus requires gnu bison. sorry])
fi
AC_MSG_RESULT(yes)
fi
@ -172,8 +172,7 @@ dnl
AC_MSG_CHECKING(whether to include symbols)
AH_TEMPLATE(DBG, [define this to include debugging support])
AC_ARG_ENABLE(debug,
[
--enable-debug include compiler symbols],
AS_HELP_STRING([--enable-debug],[include compiler symbols]),
[ case "$enable_debug" in
no)
AC_MSG_RESULT(no)
@ -198,8 +197,7 @@ dnl XXX: this should only be set for gcc....
AC_MSG_CHECKING(whether to set gcc warnings)
AH_TEMPLATE(WARN, [define this to set pedantic gcc warnings])
AC_ARG_ENABLE(warn,
[
--enable-warn pedantic gcc warnings],
AS_HELP_STRING([--enable-warn],[pedantic gcc warnings]),
[ case "$enable_debug" in
no)
AC_MSG_RESULT(no)
@ -232,9 +230,7 @@ AC_MSG_CHECKING(whether to use libwrap)
AH_TEMPLATE(LIBWRAP, [define this to include libwrap (tcp_wrappers) support])
AH_TEMPLATE(HAVE_LIBWRAP, [])
AC_ARG_WITH(libwrap,
[
--with-libwrap[[=PATH]] libwrap (tcp_wrappers) support. PATH is dir above
lib, eg: /usr/local. (default)],
AS_HELP_STRING([--with-libwrap[[=PATH]]],[libwrap (tcp_wrappers) support. PATH is dir above lib, eg: /usr/local. (default)]),
[ case "$withval" in
no)
AC_MSG_RESULT(no)
@ -297,8 +293,7 @@ dnl
AC_MSG_CHECKING([whether to include skey support])
AH_TEMPLATE(SKEY, [define this to include support for skey])
AC_ARG_WITH(skey,
[ --with-skey[[=PATH]] libskey (skey) support. PATH is dir above lib,
eg: /usr/local],
AS_HELP_STRING([--with-skey[[=PATH]]],[libskey (skey) support. PATH is dir above lib, eg: /usr/local]),
[ case "$withval" in
no)
AC_MSG_RESULT(no)
@ -334,6 +329,48 @@ AC_ARG_WITH(skey,
AC_SUBST(SKEY)
AM_CONDITIONAL([TACSKEY], [test "${with_skey}" != "no"])
dnl
dnl aceclnt - aka RSA SecurID
dnl
AC_MSG_CHECKING([whether to include RSA SecurID support])
AH_TEMPLATE(ACECLNT, [define this to include support for RSA SecurID])
AC_ARG_WITH(aceclnt,
AS_HELP_STRING([--with-aceclnt[[=PATH]]],[libaceclnt (RSA SecurID) support. PATH is dir above lib, eg: /usr/local]),
[ case "$withval" in
no)
AC_MSG_RESULT(no)
;;
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(ACECLNT)
AC_SEARCH_LIBS([SD_Init], [aceclnt],
[ ],
[AC_MSG_ERROR(Could not find libaceclnt. You must first install aceclnt or provide a hint to the location of library and includes, as in --with-aceclnt=/usr/local)])
;;
*)
AC_MSG_RESULT(yes)
AC_DEFINE(ACECLNT)
if test -d "$withval" ; then
LDFAGS="$LDFLAGS -L$withval/lib"
CFLAGS="$CFLAGS -I$withval/include"
AC_SEARCH_LIBS([SD_Init], [aceclnt],
[ ],
[AC_MSG_ERROR([Could not find libaceclnt.])
])
else
AC_SEARCH_LIBS([SD_Init], [$withval],
[ ],
[AC_MSG_ERROR([Could not find lib$withval.])
])
fi
;;
esac ],
AC_MSG_RESULT(no)
with_aceclnt="no"
)
AC_SUBST(ACECLNT)
AM_CONDITIONAL([TACACECLNT], [test "${with_aceclnt}" != "no"])
dnl
dnl XXX: might be good to have these as config file options
dnl or just options for running scripts
@ -342,7 +379,7 @@ dnl
AC_MSG_CHECKING([whether to setuid()])
AH_TEMPLATE(TACPLUS_USERID, [define this to a UID for setuid() at run-time])
AC_ARG_WITH(userid,
[ --with-userid=UID tacacs will setuid(UID) after it binds the tcp port],
AS_HELP_STRING([--with-userid=UID],[tacacs will setuid(UID) after it binds the tcp port]),
[ case "$withval" in
no)
AC_MSG_RESULT(no)
@ -370,7 +407,7 @@ dnl
AC_MSG_CHECKING(whether to setgid())
AH_TEMPLATE(TACPLUS_GROUPID, [define this to a GID for setgid() at run-time])
AC_ARG_WITH(groupid,
[ --with-groupid=UID tacacs will setgid(GID) after it binds the tcp port],
AS_HELP_STRING([--with-groupid=UID],[tacacs will setgid(GID) after it binds the tcp port]),
[ case "$withval" in
no)
AC_MSG_RESULT(no)
@ -398,7 +435,7 @@ dnl
AC_MSG_CHECKING(whether to include ACL support)
AH_TEMPLATE(ACLS, [define this to include ACL support])
AC_ARG_ENABLE(acls,
[ --enable-acls tacacs config ACL support (default)],
AS_HELP_STRING([--enable-acls],[tacacs config ACL support (default)]),
[ case "$enable_acls" in
no)
AC_MSG_RESULT(no)
@ -428,7 +465,7 @@ dnl
AC_MSG_CHECKING(whether to include user-enable support)
AH_TEMPLATE(UENABLE, [define this to include user-specific enable password support])
AC_ARG_ENABLE(uenable,
[ --enable-uenable tacacs config per-user enable support (default)],
AS_HELP_STRING([--enable-uenable],[tacacs config per-user enable support (default)]),
[ case "$enable_uenable" in
no)
AC_MSG_RESULT(no)
@ -458,7 +495,7 @@ dnl
AC_MSG_CHECKING(whether to include maximum sessions (maxsess) support)
AH_TEMPLATE(MAXSESS, [define this to include MAXSESS support to enforce a limit on maximum sessions per user ])
AC_ARG_ENABLE(maxsess,
[ --enable-maxsess Enforce a limit on maximum sessions per user],
AS_HELP_STRING([--enable-maxsess],[Enforce a limit on maximum sessions per user]),
[ case "$enable_maxsess" in
no)
AC_MSG_RESULT(no)
@ -483,7 +520,7 @@ AC_MSG_CHECKING(whether to include maxsess finger support)
AH_TEMPLATE(MAXSESS_FINGER, [define this to include support to finger NASes for
the number of sessions a user is using])
AC_ARG_ENABLE(finger,
[ --enable-finger finger NAS for number of sessions a user is using],
AS_HELP_STRING([--enable-finger],[finger NAS for number of sessions a user is using]),
[ case "$enable_finger" in
no)
AC_MSG_RESULT(no)
@ -502,6 +539,68 @@ AC_ARG_ENABLE(finger,
AC_MSG_RESULT(no)
)
AC_SUBST(MAXSESS_FINGER)
dnl
dnl ARAP_DES - enable DES for ARAP
dnl
AC_MSG_CHECKING(whether to include ARAP DES support)
AH_TEMPLATE(ARAP_DES, [Define this if you have DES routines you can link to for ARAP (See the user guide for more details)])
AC_ARG_ENABLE(arapdes,
AS_HELP_STRING([--enable-arapdes],[enable DES for ARAP]),
[ case "$enable_arapdes" in
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(ARAP_DES)
;;
* | no)
AC_MSG_RESULT(no)
;;
esac ],
# ie: no --{enable,disable}-arapdes option, withval == ""
AC_MSG_RESULT(no)
)
AC_SUBST(ARAP_DES)
dnl
dnl MSCHAP - enable MSCHAP
dnl
AC_MSG_CHECKING(whether to include MSCHAP support)
AH_TEMPLATE(MSCHAP, [Define this if you need MSCHAP support])
AC_ARG_ENABLE(mschap,
AS_HELP_STRING([--enable-mschap],[enable MSCHAP]),
[ case "$enable_mschap" in
yes)
AC_CHECK_HEADER(mschap_.h)
AC_MSG_RESULT(yes)
AC_DEFINE(MSCHAP)
;;
* | no)
AC_MSG_RESULT(no)
;;
esac ],
# ie: no --{enable,disable}-mschap option, withval == ""
AC_MSG_RESULT(no)
)
AC_SUBST(MSCHAP_)
dnl
dnl MSCHAP_DES - enable DES for MSCHAP
dnl
AC_MSG_CHECKING(whether to include MSCHAP DES support)
AH_TEMPLATE(MSCHAP_DES, [Define this if you have DES routines you can link to for MSCHAP (See the user guide for more details)])
AC_ARG_ENABLE(mschapdes,
AS_HELP_STRING([--enable-mschapdes],[enable DES for MSCHAP]),
[ case "$enable_mschapdes" in
yes)
AC_CHECK_HEADER(mschap_des.h)
AC_MSG_RESULT(yes)
AC_DEFINE(MSCHAP_DES)
;;
* | no)
AC_MSG_RESULT(no)
;;
esac ],
# ie: no --{enable,disable}-mschapdes option, withval == ""
AC_MSG_RESULT(no)
)
AC_SUBST(MSCHAP_DES)
dnl
dnl pid file location
@ -513,7 +612,7 @@ else
TACPLUS_PIDFILE="/etc/tac_plus.pid"
fi
AC_ARG_WITH(pidfile,
[ --with-pidfile=PATH alternate pidfile FQPN],
AS_HELP_STRING([--with-pidfile=PATH],[alternate pidfile FQPN]),
[ case "$withval" in
*)
AC_MSG_RESULT($withval)
@ -534,7 +633,7 @@ else
TACPLUS_ACCTFILE="/var/tmp/tac_plus.acct"
fi
AC_ARG_WITH(acctfile,
[ --with-acctfile=PATH alternate accounting file FQPN],
AS_HELP_STRING([--with-acctfile=PATH],[alternate accounting file FQPN]),
[ case "$withval" in
*)
AC_MSG_RESULT($withval)
@ -555,7 +654,7 @@ else
TACPLUS_LOGFILE="/var/tmp/tac_plus.log"
fi
AC_ARG_WITH(logfile,
[ --with-logfile=PATH alternate log file FQPN],
AS_HELP_STRING([--with-logfile=PATH],[alternate log file FQPN]),
[ case "$withval" in
*)
AC_MSG_RESULT($withval)
@ -576,7 +675,7 @@ else
TACPLUS_WHOLOGFILE="/var/tmp/tacwho.log"
fi
AC_ARG_WITH(whologfile,
[ --with-whologfile=PATH alternate wholog file FQPN],
AS_HELP_STRING([--with-whologfile=PATH],[alternate wholog file FQPN]),
[ case "$withval" in
*)
AC_MSG_RESULT($withval)
@ -593,7 +692,7 @@ dnl
AC_MSG_CHECKING(whether to profile)
AH_TEMPLATE(PROFILE, [define this to include profiling])
AC_ARG_WITH(prof,
[ --with-prof Compile in profiling.],
AS_HELP_STRING([--with-prof],[Compile in profiling.]),
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
@ -632,7 +731,7 @@ AC_HEADER_TIME
AC_CHECK_HEADERS(crypt.h ctype.h errno.h fcntl.h malloc.h shadow.h stdlib.h \
stdint.h string.h strings.h sys/resource.h sys/socket.h \
sys/types.h sys/wait.h sysexits.h syslog.h termios.h unistd.h \
wait.h)
utmp.h utmpx.h wait.h)
AH_TEMPLATE([SHADOW_PASSWORDS],
[define if your system has a shadow password file])
@ -662,8 +761,8 @@ AC_CHECK_TYPES([pid_t], [], [], [#if HAVE_SYS_TYPES_H
#endif])
# check functions
AC_CHECK_FUNCS([getdtablesize memcpy memset strchr strcspn strerror strrchr \
wait3 wait4 waitpid])
AC_CHECK_FUNCS([getdtablesize memcpy memset random strchr strcspn strerror \
strrchr wait3 wait4 waitpid])
AC_FUNC_SETPGRP
# Is the wait(2) status an int or union
@ -867,6 +966,45 @@ AH_BOTTOM([
# define socklen_t int
#endif
/* host specifics */
/* Define this if your password file does not contain age and comment fields. */
#define NO_PWAGE
#if AIX
/*
* The only way to properly compile BSD stuff on AIX is to define a
* "bsdcc" compiler on your system. See /usr/lpp/bos/bsdport on your
* system for details. People who do NOT do this tell me that the code
* still compiles but that it then doesn't behave correctly e.g. child
* processes are not reaped correctly. Don't expect much sympathy if
* you do this.
*/
# define _BSD 1
# define _BSD_INCLUDES
# define NO_PWAGE
#endif /* AIX */
#if LINUX
# define NO_PWAGE
# include <unistd.h>
# ifdef GLIBC
# define CONST_SYSERRLIST
# endif
#endif /* LINUX */
#if NETBSD
# define NO_PWAGE
# define CONST_SYSERRLIST
#endif
#if FREEBSD
# define CONST_SYSERRLIST
# define NO_PWAGE
#endif
#if BSDI
# define NO_PWAGE
#endif
#endif /* CONFIG_H */
])
AC_CONFIG_HEADERS(config.h)

View File

@ -26,14 +26,10 @@
#ifdef MSCHAP
# include "md4.h"
# include "mschap.h"
#ifdef MSCHAP_DES
#include "arap_des.h"
#endif
#endif /* MSCHAP */
#ifdef ARAP_DES
#include "arap_des.h"
#if ARAP_DES || MSCHAP_DES
# include "fdes.h"
#endif
/* internal state variables */
@ -103,8 +99,8 @@ default_fn(struct authen_data *data)
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
if (debug) {
report(LOG_DEBUG,
"authentication query for '%s' %s from %s rejected",
name && name[0] ? name : "unknown",
"authentication query for '%s' port %s from %s rejected",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port, session.peer);
}
return(0);
@ -118,8 +114,9 @@ default_fn(struct authen_data *data)
chap_verify(data);
if (debug) {
report(LOG_DEBUG, "chap-login query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
report(LOG_DEBUG,
"chap-login query for '%s' port %s from %s %s",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port, session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
"accepted" : "rejected");
@ -132,8 +129,9 @@ default_fn(struct authen_data *data)
mschap_verify(data);
if (debug) {
report(LOG_DEBUG, "mschap-login query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
report(LOG_DEBUG,
"mschap-login query for '%s' port %s from %s %s",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port, session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
"accepted" : "rejected");
@ -146,8 +144,8 @@ default_fn(struct authen_data *data)
arap_verify(data);
if (debug) {
report(LOG_DEBUG, "arap query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
report(LOG_DEBUG, "arap query for '%s' port %s from %s %s",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port, session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
"accepted" : "rejected");
@ -158,8 +156,8 @@ default_fn(struct authen_data *data)
pap_verify(data);
if (debug) {
report(LOG_INFO, "pap-login query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
report(LOG_DEBUG, "pap-login query for '%s' port %s from %s %s",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port,
session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
@ -179,8 +177,8 @@ default_fn(struct authen_data *data)
default:
/* Authentication finished */
if (debug)
report(LOG_INFO, "login query for '%s' %s from %s %s",
name && name[0] ? name : "unknown",
report(LOG_DEBUG, "login query for '%s' port %s from %s %s",
(name != NULL && name[0] != '\0') ? name : "unknown",
session.port,
session.peer,
(data->status == TAC_PLUS_AUTHEN_STATUS_PASS) ?
@ -211,14 +209,13 @@ default_fn(struct authen_data *data)
name == NULL ? "unknown" : name,
session.peerip, session.port);
return(0);
case TAC_PLUS_AUTHEN_STATUS_PASS:
if (session.peer)
report(LOG_NOTICE, "login success: user=%s device=%s ip=%s port=%s client=%s",
name == NULL ? "unknown" : name,
session.peer, session.peerip, session.port, clientip);
else
report(LOG_NOTICE, "login success: user=%s device=%s port=%s",
report(LOG_NOTICE, "login failure: user=%s device=%s port=%s",
name == NULL ? "unknown" : name,
session.peerip, session.port);
return(0);
@ -324,7 +321,7 @@ pap_verify(struct authen_data *data)
name = data->NAS_id->username;
if (!name[0]) {
if (name[0] == '\0') {
/* something awful has happened. Give up and die */
report(LOG_ERR, "%s %s: no username for inbound PAP login",
session.peer, session.port);
@ -339,6 +336,12 @@ pap_verify(struct authen_data *data)
/* Assume the worst */
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
verify(name, passwd, data, TAC_PLUS_RECURSE);
#ifdef ACLS
if (verify_host(name, data, S_acl, TAC_PLUS_RECURSE) != S_permit)
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
#endif
free(passwd);
return;
}
/* Verify the challenge and id against the response by looking up the
@ -347,7 +350,7 @@ pap_verify(struct authen_data *data)
static void
chap_verify(struct authen_data *data)
{
char *name, *secret, *chal, digest[MD5_LEN];
char *name, *secret, *chal, digest[TAC_MD5_DIGEST_LEN];
char *exp_date, *p;
u_char *mdp;
char id;
@ -364,7 +367,7 @@ chap_verify(struct authen_data *data)
id = data->client_data[0];
chal_len = data->client_dlen - 1 - MD5_LEN;
chal_len = data->client_dlen - 1 - TAC_MD5_DIGEST_LEN;
if (chal_len < 0) {
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
return;
@ -381,8 +384,10 @@ chap_verify(struct authen_data *data)
/* Get the secret */
secret = cfg_get_chap_secret(name, TAC_PLUS_RECURSE);
/* If there is no chap password for this user, see if there is a global
* password for her that we can use */
/*
* If there is no chap password for this user, see if there is a global
* password for her that we can use
*/
if (!secret) {
secret = cfg_get_global_secret(name, TAC_PLUS_RECURSE);
}
@ -424,14 +429,20 @@ chap_verify(struct authen_data *data)
* digest value. If they are equal, it's a pass, otherwise it's a
* failure
*/
if (memcmp(digest, data->client_data + 1 + chal_len, MD5_LEN)) {
if (memcmp(digest, data->client_data + 1 + chal_len, TAC_MD5_DIGEST_LEN)) {
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
} else {
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
}
#ifdef ACLS
if (verify_host(name, data, S_acl, TAC_PLUS_RECURSE) != S_permit)
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
#endif
exp_date = cfg_get_expires(name, TAC_PLUS_RECURSE);
set_expiration_status(exp_date, data);
return;
}
/*
@ -455,6 +466,7 @@ pw_bitshift(char *pw)
pws[i] = pw[i] << 1;
memcpy(pw, pws, 8);
return;
}
static void
@ -462,6 +474,9 @@ arap_verify(struct authen_data *data)
{
char nas_chal[8], r_chal[8], r_resp[8], secret[8];
char *name, *cfg_secret, *exp_date, *p;
#ifdef ARAP_DES
union LR_block desblk;
#endif
if (!(char) data->NAS_id->username[0]) {
report(LOG_ERR, "%s %s: no username for arap_verify",
@ -511,15 +526,16 @@ arap_verify(struct authen_data *data)
pw_bitshift(secret);
#ifdef ARAP_DES
des_init(0);
des_setkey(secret);
des_endes(nas_chal);
des_done();
#endif /* ARAP_DES */
tac_set_des_mode(DES_MODE_ENCRYPT);
tac_des_loadkey(secret, DES_KEY_SHIFT);
memcpy(desblk.string, nas_chal, 8);
tac_des(&desblk);
memcpy(nas_chal, desblk.string, 8);
#endif
/*
* Now compare the remote's response value with the just calculated one
* value. If they are equal, it's a pass, otherwise it's a failure.
* Now compare the remote's response value with the one just calculated.
* If they are equal, it's a pass, otherwise it's a failure.
*/
if (memcmp(nas_chal, r_resp, 8)) {
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
@ -529,18 +545,25 @@ arap_verify(struct authen_data *data)
#ifdef ARAP_DES
/* Now calculate the response to the remote's challenge */
des_init(0);
des_setkey(secret);
des_endes(r_chal);
des_done();
#endif /* ARAP_DES */
tac_set_des_mode(DES_MODE_ENCRYPT);
tac_des_loadkey(secret, DES_KEY_SHIFT);
memcpy(desblk.string, r_chal, 8);
tac_des(&desblk);
memcpy(r_chal, desblk.string, 8);
#endif
data->server_data = tac_malloc(8);
data->server_dlen = 8;
memcpy(data->server_data, r_chal, 8);
#ifdef ACLS
if (verify_host(name, data, S_acl, TAC_PLUS_RECURSE) != S_permit)
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
#endif
exp_date = cfg_get_expires(name, TAC_PLUS_RECURSE);
set_expiration_status(exp_date, data);
return;
}
#ifdef MSCHAP
@ -549,8 +572,11 @@ static void
mschap_desencrypt(char *clear, unsigned char *str, unsigned char *cypher)
{
unsigned char key[8];
#ifdef MSCHAP_DES
union LR_block desblk;
#endif
/* des_state_type *des_state = NULL; */
/* XXX des_state_type *des_state = NULL; */
memset(key, 0, 8);
@ -591,23 +617,27 @@ mschap_desencrypt(char *clear, unsigned char *str, unsigned char *cypher)
/* copy clear to cypher, cause our des encrypts in place */
memcpy(cypher, clear, 8);
/*
XXX
des_init(0,&des_state);
des_setkey(des_state,key);
des_endes(des_state,cypher);
des_done(des_state);
*/
#ifdef MSCHAP_DES
des_init(0);
des_setkey(key);
des_endes(cypher);
des_done();
#endif /* MSCHAP_DES */
tac_set_des_mode(DES_MODE_ENCRYPT);
tac_des_loadkey(key, DES_KEY_SHIFT);
memcpy(desblk.string, cypher, 8);
tac_des(&desblk);
memcpy(cypher, desblk.string, 8);
#endif
return;
}
static void
mschap_deshash(char *clear, char *cypher)
{
mschap_desencrypt(MSCHAP_KEY, clear, cypher);
return;
}
static void
@ -624,6 +654,7 @@ mschap_lmpasswordhash(char *password, char *passwordhash)
mschap_deshash(&upassword[0], &passwordhash[0]);
mschap_deshash(&upassword[7], &passwordhash[8]);
return;
}
static void
@ -637,6 +668,7 @@ mschap_challengeresponse(char *challenge, char *passwordhash, char *response)
mschap_desencrypt(challenge, &zpasswordhash[0], &response[0]);
mschap_desencrypt(challenge, &zpasswordhash[7], &response[8]);
mschap_desencrypt(challenge, &zpasswordhash[14], &response[16]);
return;
}
void
@ -646,6 +678,7 @@ mschap_lmchallengeresponse(char *challenge, char *password, char *response)
mschap_lmpasswordhash(password, passwordhash);
mschap_challengeresponse(challenge, passwordhash, response);
return;
}
static int
@ -683,6 +716,7 @@ mschap_ntpasswordhash(char *password, char *passwordhash)
MD4Update(&context, unicode_password,
mschap_unicode_len(unicode_password));
MD4Final(passwordhash, &context);
return;
}
void
@ -692,6 +726,7 @@ mschap_ntchallengeresponse(char *challenge, char *password, char *response)
mschap_ntpasswordhash(password, passwordhash);
mschap_challengeresponse(challenge, passwordhash, response);
return;
}
/*
@ -729,7 +764,7 @@ mschap_verify(struct authen_data *data)
report(LOG_DEBUG, "%s %s: ms-chap user=%s, id=%d chal_len=%d",
session.peer, session.port, name, (int) id, chal_len);
/* report_hex(LOG_DEBUG, (u_char *)data->client_data + 1, chal_len); */
/* XXX report_hex(LOG_DEBUG, (u_char *)data->client_data + 1, chal_len); */
}
/* Assume failure */
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
@ -788,8 +823,14 @@ mschap_verify(struct authen_data *data)
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
}
#ifdef ACLS
if (verify_host(name, data, S_acl, TAC_PLUS_RECURSE) != S_permit)
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
#endif
exp_date = cfg_get_expires(name, TAC_PLUS_RECURSE);
set_expiration_status(exp_date, data);
return;
}
#endif /* MSCHAP */
@ -801,7 +842,8 @@ mschap_verify(struct authen_data *data)
int
verify_host(char *name, struct authen_data *data, int type, int recurse)
{
char *val;
char *realname, *val;
int status;
/* lookup host acl for user */
if (!cfg_user_exists(name) && cfg_user_exists(DEFAULT_USERNAME)) {
@ -809,14 +851,22 @@ verify_host(char *name, struct authen_data *data, int type, int recurse)
report(LOG_DEBUG, "Authenticating ACLs for user '%s' instead of "
"'%s'", DEFAULT_USERNAME, name);
}
val = cfg_get_pvalue(DEFAULT_USERNAME, 1, type, recurse);
realname = DEFAULT_USERNAME;
} else
val = cfg_get_pvalue(name, 1, type, recurse);
realname = name;
val = cfg_get_pvalue(realname, 1, type, recurse);
/* no host acl for user */
if (val == NULL)
return(S_permit);
return(cfg_acl_check(val, data->NAS_id->NAS_ip));
if ((status = cfg_acl_check(val, data->NAS_id->NAS_ip)) != S_permit) {
if (debug & DEBUG_AUTHEN_FLAG)
report(LOG_DEBUG, "host ACLs for user '%s' deny", realname);
} else
if (debug & DEBUG_AUTHEN_FLAG)
report(LOG_DEBUG, "host ACLs for user '%s' permit", realname);
return(status);
}
#endif

View File

@ -46,7 +46,6 @@ struct private_data {
*
* Return 0 if data->status is valid, otherwise 1
*/
int
default_v0_fn(struct authen_data *data)
{
@ -73,7 +72,7 @@ default_v0_fn(struct authen_data *data)
/* Unless we're enabling, we need a username */
if (data->service != TAC_PLUS_AUTHEN_SVC_ENABLE &&
!(char) data->NAS_id->username[0]) {
(char)data->NAS_id->username[0] == '\0') {
switch (p->state) {
case STATE_AUTHEN_GETUSER:
@ -118,10 +117,10 @@ default_v0_fn(struct authen_data *data)
passwd = p->password;
if (!passwd[0]) {
/* no password yet. Either we need to ask for one and expect to get
* called again, or we asked but nothing came back, which is fatal */
/*
* no password yet. Either we need to ask for one and expect to get
* called again, or we asked but nothing came back, which is fatal
*/
switch (p->state) {
case STATE_AUTHEN_GETPASS:
/* We already asked for a password. This should be the reply */

1061
tacacs-F4.0.4.28/des_iip.h Normal file

File diff suppressed because it is too large Load Diff

1061
tacacs-F4.0.4.28/des_ip.h Normal file

File diff suppressed because it is too large Load Diff

8209
tacacs-F4.0.4.28/des_key.h Normal file

File diff suppressed because it is too large Load Diff

142
tacacs-F4.0.4.28/des_s_p.h Normal file
View File

@ -0,0 +1,142 @@
/*
* s_p.h - contains combined Sbox and P permutation table
*/
static unsigned long S_P[8][64] = {
/* SBOX 1 */
0x820200, 0x20000, 0x80800000, 0x80820200,
0x800000, 0x80020200, 0x80020000, 0x80800000,
0x80020200, 0x820200, 0x820000, 0x80000200,
0x80800200, 0x800000, 0, 0x80020000,
0x20000, 0x80000000, 0x800200, 0x20200,
0x80820200, 0x820000, 0x80000200, 0x800200,
0x80000000, 0x200, 0x20200, 0x80820000,
0x200, 0x80800200, 0x80820000, 0,
0, 0x80820200, 0x800200, 0x80020000,
0x820200, 0x20000, 0x80000200, 0x800200,
0x80820000, 0x200, 0x20200, 0x80800000,
0x80020200, 0x80000000, 0x80800000, 0x820000,
0x80820200, 0x20200, 0x820000, 0x80800200,
0x800000, 0x80000200, 0x80020000, 0,
0x20000, 0x800000, 0x80800200, 0x820200,
0x80000000, 0x80820000, 0x200, 0x80020200,
/* SBOX 2 */
0x10042004, 0, 0x42000, 0x10040000,
0x10000004, 0x2004, 0x10002000, 0x42000,
0x2000, 0x10040004, 0x4, 0x10002000,
0x40004, 0x10042000, 0x10040000, 0x4,
0x40000, 0x10002004, 0x10040004, 0x2000,
0x42004, 0x10000000, 0, 0x40004,
0x10002004, 0x42004, 0x10042000, 0x10000004,
0x10000000, 0x40000, 0x2004, 0x10042004,
0x40004, 0x10042000, 0x10002000, 0x42004,
0x10042004, 0x40004, 0x10000004, 0,
0x10000000, 0x2004, 0x40000, 0x10040004,
0x2000, 0x10000000, 0x42004, 0x10002004,
0x10042000, 0x2000, 0, 0x10000004,
0x4, 0x10042004, 0x42000, 0x10040000,
0x10040004, 0x40000, 0x2004, 0x10002000,
0x10002004, 0x4, 0x10040000, 0x42000,
/* SBOX 3 */
0x41000000, 0x1010040, 0x40, 0x41000040,
0x40010000, 0x1000000, 0x41000040, 0x10040,
0x1000040, 0x10000, 0x1010000, 0x40000000,
0x41010040, 0x40000040, 0x40000000, 0x41010000,
0, 0x40010000, 0x1010040, 0x40,
0x40000040, 0x41010040, 0x10000, 0x41000000,
0x41010000, 0x1000040, 0x40010040, 0x1010000,
0x10040, 0, 0x1000000, 0x40010040,
0x1010040, 0x40, 0x40000000, 0x10000,
0x40000040, 0x40010000, 0x1010000, 0x41000040,
0, 0x1010040, 0x10040, 0x41010000,
0x40010000, 0x1000000, 0x41010040, 0x40000000,
0x40010040, 0x41000000, 0x1000000, 0x41010040,
0x10000, 0x1000040, 0x41000040, 0x10040,
0x1000040, 0, 0x41010000, 0x40000040,
0x41000000, 0x40010040, 0x40, 0x1010000,
/* SBOX 4 */
0x100402, 0x4000400, 0x2, 0x4100402,
0, 0x4100000, 0x4000402, 0x100002,
0x4100400, 0x4000002, 0x4000000, 0x402,
0x4000002, 0x100402, 0x100000, 0x4000000,
0x4100002, 0x100400, 0x400, 0x2,
0x100400, 0x4000402, 0x4100000, 0x400,
0x402, 0, 0x100002, 0x4100400,
0x4000400, 0x4100002, 0x4100402, 0x100000,
0x4100002, 0x402, 0x100000, 0x4000002,
0x100400, 0x4000400, 0x2, 0x4100000,
0x4000402, 0, 0x400, 0x100002,
0, 0x4100002, 0x4100400, 0x400,
0x4000000, 0x4100402, 0x100402, 0x100000,
0x4100402, 0x2, 0x4000400, 0x100402,
0x100002, 0x100400, 0x4100000, 0x4000402,
0x402, 0x4000000, 0x4000002, 0x4100400,
/* SBOX 5 */
0x2000000, 0x4000, 0x100, 0x2004108,
0x2004008, 0x2000100, 0x4108, 0x2004000,
0x4000, 0x8, 0x2000008, 0x4100,
0x2000108, 0x2004008, 0x2004100, 0,
0x4100, 0x2000000, 0x4008, 0x108,
0x2000100, 0x4108, 0, 0x2000008,
0x8, 0x2000108, 0x2004108, 0x4008,
0x2004000, 0x100, 0x108, 0x2004100,
0x2004100, 0x2000108, 0x4008, 0x2004000,
0x4000, 0x8, 0x2000008, 0x2000100,
0x2000000, 0x4100, 0x2004108, 0,
0x4108, 0x2000000, 0x100, 0x4008,
0x2000108, 0x100, 0, 0x2004108,
0x2004008, 0x2004100, 0x108, 0x4000,
0x4100, 0x2004008, 0x2000100, 0x108,
0x8, 0x4108, 0x2004000, 0x2000008,
/* SBOX 6 */
0x20000010, 0x80010, 0, 0x20080800,
0x80010, 0x800, 0x20000810, 0x80000,
0x810, 0x20080810, 0x80800, 0x20000000,
0x20000800, 0x20000010, 0x20080000, 0x80810,
0x80000, 0x20000810, 0x20080010, 0,
0x800, 0x10, 0x20080800, 0x20080010,
0x20080810, 0x20080000, 0x20000000, 0x810,
0x10, 0x80800, 0x80810, 0x20000800,
0x810, 0x20000000, 0x20000800, 0x80810,
0x20080800, 0x80010, 0, 0x20000800,
0x20000000, 0x800, 0x20080010, 0x80000,
0x80010, 0x20080810, 0x80800, 0x10,
0x20080810, 0x80800, 0x80000, 0x20000810,
0x20000010, 0x20080000, 0x80810, 0,
0x800, 0x20000010, 0x20000810, 0x20080800,
0x20080000, 0x810, 0x10, 0x20080010,
/* SBOX 7 */
0x1000, 0x80, 0x400080, 0x400001,
0x401081, 0x1001, 0x1080, 0,
0x400000, 0x400081, 0x81, 0x401000,
0x1, 0x401080, 0x401000, 0x81,
0x400081, 0x1000, 0x1001, 0x401081,
0, 0x400080, 0x400001, 0x1080,
0x401001, 0x1081, 0x401080, 0x1,
0x1081, 0x401001, 0x80, 0x400000,
0x1081, 0x401000, 0x401001, 0x81,
0x1000, 0x80, 0x400000, 0x401001,
0x400081, 0x1081, 0x1080, 0,
0x80, 0x400001, 0x1, 0x400080,
0, 0x400081, 0x400080, 0x1080,
0x81, 0x1000, 0x401081, 0x400000,
0x401080, 0x1, 0x1001, 0x401081,
0x400001, 0x401080, 0x401000, 0x1001,
/* SBOX 8 */
0x8200020, 0x8208000, 0x8020, 0,
0x8008000, 0x200020, 0x8200000, 0x8208020,
0x20, 0x8000000, 0x208000, 0x8020,
0x208020, 0x8008020, 0x8000020, 0x8200000,
0x8000, 0x208020, 0x200020, 0x8008000,
0x8208020, 0x8000020, 0, 0x208000,
0x8000000, 0x200000, 0x8008020, 0x8200020,
0x200000, 0x8000, 0x8208000, 0x20,
0x200000, 0x8000, 0x8000020, 0x8208020,
0x8020, 0x8000000, 0, 0x208000,
0x8200020, 0x8008020, 0x8008000, 0x200020,
0x8208000, 0x20, 0x200020, 0x8008000,
0x8208020, 0x200000, 0x8200000, 0x8000020,
0x208000, 0x8020, 0x8008020, 0x8200000,
0x20, 0x8208000, 0x208020, 0,
0x8000000, 0x8200020, 0x8000, 0x208020,
};

View File

@ -20,7 +20,7 @@
*/
#include "tac_plus.h"
#include "pathsl.h"
#include <limits.h>
#include <time.h>
#if defined(__DragonFly__) && !defined(O_SYNC)
#define O_SYNC O_FSYNC
@ -38,7 +38,7 @@ acct_write(char *string)
if (write(acctfd, string, strlen(string)) != strlen(string)) {
report(LOG_ERR, "%s: couldn't write acct file %s %s",
session.peer,
TACPLUS_ACCTFILE, strerror(errno));
session.acctfile, strerror(errno));
return(1);
}
@ -70,22 +70,24 @@ do_acct_file(struct acct_rec *rec)
{
int i, errors;
time_t t = time(NULL);
char *ct = ctime(&t);
char ct[LINE_MAX];
struct tm *tm;
ct[24] = '\0';
tm = localtime(&t);
strftime(ct, LINE_MAX, "%h %e %T", tm);
if (!acctfd) {
acctfd = open(TACPLUS_ACCTFILE, O_CREAT | O_WRONLY | O_APPEND, 0644);
acctfd = open(session.acctfile, O_CREAT | O_WRONLY | O_APPEND, 0644);
if (acctfd < 0) {
report(LOG_ERR, "Can't open acct file %s -- %s",
TACPLUS_ACCTFILE, strerror(errno));
session.acctfile, strerror(errno));
return(1);
}
}
if (!tac_lockfd(TACPLUS_ACCTFILE, acctfd)) {
if (!tac_lockfd(session.acctfile, acctfd)) {
rec->admin_msg = tac_strdup("Cannot lock log file");
report(LOG_ERR, "%s: Cannot lock %s",
session.peer, TACPLUS_ACCTFILE);
session.peer, session.acctfile);
return(1);
}
@ -203,11 +205,18 @@ do_acct_syslog(struct acct_rec *rec)
int
wtmp_entry(char *line, char *name, char *host, time_t utime)
{
#if HAVE_UTMP_H
struct utmp entry;
#elif HAVE_UTMPX_H
struct utmpx entry;
#endif
if (!wtmpfile) {
return(1);
}
#if HAVE_UTMPX_H && !HAVE_UTMP_H
# define ut_name ut_user
#endif
memset(&entry, 0, sizeof entry);
@ -227,7 +236,13 @@ wtmp_entry(char *line, char *name, char *host, time_t utime)
else
memcpy(entry.ut_host, host, sizeof(entry.ut_host));
#endif
#if HAVE_UTMP_H
entry.ut_time = utime;
#elif HAVE_UTMPX_H
entry.ut_tv.tv_sec = utime;
#else
# error "unknown utmp time field"
#endif
#ifdef FREEBSD
wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND, 0644);

547
tacacs-F4.0.4.28/do_auth.py Normal file
View File

@ -0,0 +1,547 @@
#!/usr/bin/python
# Program I threw together to do the things tac_plus won't
# It allows very granular control. Please visit tacacs.org as
# this is continually updated
# History:
# Version 1.1
# Simple typo - a stray 's' botched a deny statement
# Version 1.2
# Did you know a firewall doesn't end it's commands with a <cr>?
# Version 1.3
# Needs a default user. If most of your users have the same access,
# and you have a default access in tac_plus.conf, you need it here as
# well.
# Version 1.4
# CRS doesn't send $address when in conf t
# Added -fix_crs_bug as as simple/stupid workaround
# Version 1.5
# Mistake in the example, thanks to aojea
# Version 1.6
# Added support for other services besides service=shell
# (ie - they work, by they match on IP/Source only. If you have examples of
# pairs other than cmd to match on, please bring them to my attention)
# Version 1.7
# Fixed reression
# Support for replacing av pairs
# Version 1.8
# Nexus support (tac_pair format different)
# Version 1.9
# Better Nexus Support
# Only send roles to Nexus
# Better av pair replacement
# TO DO (If anybody bothers to request them)
# Possible web front end - simple cgi shouldn't be too hard to write
# More work on tac_pairs - sniff wlc traffic
# Write a better option parser to ignore options not sent (See CRS Bug)
'''
do_auth.py [-options]
Version 1.9
do_auth is a python program I wrote to work as an authorization script for
tacacs to allow greater flexability in tacacs authentication. It allows
a user to be part of many predefined groups that can allow different
access to different devices based on ip, user, and source address.
Do not play with do_auth untill you have a firm grasp on tac_plus!
-u Username. Mandatory. $user
-i Ip address of user. Optional. If not specified, all host_ entries
are ignored and can be omitted. $address
**Note: If you use IOS-XR, you MUST add -fix_crs_bug after $address
due to a bug in IOS-XR
-d Device address. Optional. If not specified, all device_ entries
are ignored and can be omitted. $name
-f Config Filename. Default is do_auth.ini.
-l Logfile. Default is log.txt.
-D Debug mode. Allows you to call the program without reading
from stdin. Useful to test your configuration before going
live. Sets a default command of "show users wides".
Groups are assigned to users in the [users] section. A user must
be assigned to one or more groups, one per line. Groups are defined
in brackets, but can be any name. Each group can have up to 6 options
as defined below.
host_deny Deny any user coming from this host. Optional.
host_allow Allow users from this range. Mandatory if
-i is specified.
device_deny Deny any device with this IP. Optional.
device_permit Allow this range. Mandatory if -d is specified
command_deny Deny these commands. Optional.
command_permit Allow these commands. Mandatory.
av_pairs list of av pairs to replace if found. Optional - be careful
The options are parsed in order till a match is found. Obviously,
for login, the commands section is not parsed. If a match is not
found, or a deny is found, we move on to the next group. At the
end, we have an implicit deny if no groups match.
An simple example is as follows.
[users]
homer =
simpson_group
television_group
stimpy =
television_group
[simpson_group]
host_deny =
1.1.1.1
1.1.1.2
host_allow =
1.1.1.*
device_permit =
10.1.1.*
command_permit =
.*
[television_group]
host_allow =
.*
device_permit =
.*
command_permit =
show.*
Example tacacs line: after authorization "/usr/bin/python
/root/do_auth.pyc -i $address -fix_crs_bug -u $user -d $name -l /root/log.txt
-f /root/do_auth.ini"
(that's one line)
Example av_pair:
The following example will replace any priv-lvl with priv-lvl=1 ONLY if passed.
Think of "av_pairs" as a find/replace function.
av_pairs =
priv-lvl=1
Brocade has a brocade-privlvl which I like. It maps priv-lvl to
brocade-privlvl, but priv-lvl=1 results in interface privileges. Here
is an example of how to map to brocade-privlvl=5 which has no modification
rights. Unfortunately, it does require you to put in the IP's of your gear.
The following group would go before other groups:
[brocade_readonly]
host_allow =
.*
device_permit =
192.168.1.*
command_permit =
.*
av_pairs =
priv-lvl,brocade-privlvl=5
You could also put "priv-lvl=15,brocade-privlvl=5" or whatever your
tac_plus deamon is passing; as long as it's a match it accomplished the same
thing. In this example, we essentially replace the whole av_pair resulting
in the user having only read access. Alternatively, a good "disable account"
can be created by simpley doing:
av_pairs =
brocade-privlvl=5
This results in the brocades having read/only, and the Cisco's go into disable
because they don't understand it. (We're assuming that the user has no enable
account or the priv-lvl is pointless) You could also add a shell role for nexus,
which we will discuss next. (shell:roles="network-admin")
NEXUS - Due to a slight change in the nexus, do_auth is able to
discern if a device is a nexus or not. In tac_plus, do the following:
service = exec {
priv-lvl = 1
shell:roles=\"\\"network-operator\\""
idletime = 3
timeout = 15
}
after authorization <do_auth yada yada>
This configuration does NOT work without do_auth. However, WITH do_auth,
do_auth will only send shell:roles to Nexus switches, allowing your
other gear to work correctly. Simply put av_pairs in your do_auth, and
it will figure it out for you. (If not, it won't touch them. The logic is
simple: If (av_pairs in .ini): Then (do_stuff), Else (exit(2)- Don't modify 'em!))
Roles can also be modified in a do_auth group, as below:
av_pairs =
priv-lvl=15
shell:roles="network-admin"
Also of note, you MUST USE DOUBLE QUOTES to get tac_plus to correctly
pass "network-operator" in the service example above. UNLESS you are
modifying the key with do_auth in av_pairs - it will fix the quotes.
BUGS: You must know your regular expressions. If you enter a bad
expression, such as *. instead of .*, python re will freak out and
not evaluate the expression. (Thought about netaddr, but would you
really install it?)
CAVEATS: One group can not take away what another group grants via deny.
If a match is not found, it will go on to the next group. If a deny is
matched, it will go on to the next group.
Order is crucial - the groups should go from more specific to less
specific. In the above example, if television_group was put before
simpson_group, simpson_group would never be called because
televsion_group catches everything in device_permit.
HELP: If somebody has a WLC or other unknown network equipment, I
require some testing/sniffing done - thanks!!
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 or any
later version as published by the Free Software Foundation,
http://www.gnu.org/
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Written by Dan Schmidt - Please visit tacacs.org to check for updates.
'''
import sys,re,getopt,ConfigParser
from time import strftime
# I really don't want to deal with these exceptions more than once
# filename is only used in log statements
def get_attribute(config, the_section, the_option, log_file, filename):
if not config.has_section(the_section):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Section '%s' does not exist in %s\n"
% (the_section, filename))
sys.exit(1)
if not config.has_option(the_section, the_option):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Option '%s' does not exist in section %s in file %s\n"
% (the_option, the_section, filename))
sys.exit(1)
#Should not have any exceptions - BUT, just in case
try:
attributes = config.get(the_section, the_option)
except ConfigParser.NoSectionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Section '%s' Doesn't Exist!\n"
% (the_section))
sys.exit(1)
except ConfigParser.DuplicateSectionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Duplicate section '%s'\n"
% (the_section))
sys.exit(1)
except ConfigParser.NoOptionError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: '%s' not found in section '%s\n'"
% (the_option, the_section))
sys.exit(1)
#To do: finish exceptions.
except ConfigParser.ParsingError:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Can't parse file '%s'! (You got me)\n"
% (filename))
sys.exit(1)
attributes = attributes.split('\n')
#Strip empty lines
attributes2 = []
for line in attributes:
if line:
attributes2.append(line)
return attributes2
# Can't make it part of get_attribute... oh well...
# We need someway to check to see if a username exists with out exit(1)
def check_username(config, log_file, user_name):
if not config.has_section('users'):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: users section doesn't exist!")
sys.exit(1)
if config.has_option('users', user_name):
return True
else:
return False
# If match item in our_list, true, else false
# Example - if deny section has a match for 10.1.1.1,
# return True, else False
# If the section doesn't exist, we assume an
# impicity deny/false
def match_it(the_section, the_option, match_item, config, log_file, filename):
if config.has_option(the_section,the_option):
our_list = get_attribute(config, the_section, the_option, log_file, filename)
for item in our_list:
#p = re.compile(item) Not necessary - we're only using it once
if re.match(item,match_item):
return True
return False
def main():
#Defaults
filename = "do_auth.ini"
log_name = "log.txt"
user_name = ""
ip_addr = ""
device = ""
is_debug = False
argv = sys.argv
try:
optlist, args = getopt.getopt(sys.argv[1:], 'i:u:f:l:d:?:D', ['fix_crs_bug','?', '-?', 'help', 'Help'])
except getopt.GetoptError, err:
print str(err)
print __doc__
sys.exit(1)
for (i, j) in optlist:
if i == '-i':
ip_addr = j
elif i == '-u':
user_name = j
elif i == '-f':
filename = j
elif i == '-l':
log_name = j
elif i == '-d':
device = j
elif i in ('?', '-?', 'help', 'Help'):
print __doc__
sys.exit(1)
elif i == '-D':
is_debug = True
else:
print 'Unknown option:', i
sys.exit(1)
if len(argv) < 7:
print __doc__
sys.exit(1)
log_file = open (log_name, "a")
#DEBUG! We at least got CALLED
# log_file.write('Hello World!' + '\n')
#read AV pairs
av_pairs = []
if not (is_debug):
for line in sys.stdin:
av_pairs.append(line)
else:
#Default Debug command is "show users wide"
#Later versions will allow this to be set
av_pairs.append("service=shell\n")
av_pairs.append("cmd=show\n")
av_pairs.append("cmd-arg=users\n")
av_pairs.append("cmd-arg=wide\n")
av_pairs.append("cmd-arg=<cr>\n")
#DEBUG - print tac pairs
# for item in av_pairs:
# log_file.write(item)
# Function to make cmd's readable
# Not very good, but will do for now
# I don't use any other service other than shell to test!
the_command = ""
return_pairs = ""
if (av_pairs[0] == "service=shell\n"):
if av_pairs[1] == ("cmd=\n"): # #&*@ Nexus!
if len(av_pairs) > 2:
#DEBUG
# log_file.write('Nexus pairs found\n')
return_pairs = av_pairs[2:] #strip the "cmd=" for consistency
#Commands - Concatenate to a readable command
elif av_pairs[1].startswith("cmd="):
our_command = av_pairs[1].split("=")
the_command = our_command[1].strip('\n')
if len(av_pairs) > 2:
i = 2
our_command = av_pairs[i].split("=")
while not (our_command[1] == "<cr>\n"):
the_command = the_command + " " + our_command[1].strip('\n')
i = i + 1
if i == len(av_pairs): # Firewalls don't give a <cr>!!
break
our_command = av_pairs[i].split("=")
#DEBUG - We got the command
#log_file.write(the_command + '\n')
#Login - Get av_pairs to pass back to tac_plus
elif av_pairs[1].startswith("cmd*"): #Anybody know why it's "cmd*"?
if len(av_pairs) > 2:
return_pairs = av_pairs[2:] #You MUST strip the "cmd*" av-pair
# Definately not a Nexus, so strip any nexus pair
for item in return_pairs:
if item.startswith("shell:roles"):
return_pairs.remove(item)
else:
return_pairs = av_pairs
if not user_name:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: No username entered!\n")
sys.exit(1)
config = ConfigParser.SafeConfigParser()
if not (filename in config.read(filename)):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "Error: Can't open/parse '%s'\n"
% (filename))
sys.exit(1)
the_section = "users"
# If the user doesn't exist, just use the default settings
# Kind of a hack, but it works because we only get_attribute on user_name once.
# We have the : in there which we can use to split if required
if not check_username(config, log_file, user_name):
user_name = (user_name + ":(default)")
groups = get_attribute(config, "users", "default", log_file, filename)
else:
groups = get_attribute(config, "users", user_name, log_file, filename)
for this_group in groups:
if ip_addr:
if match_it(this_group, "host_deny", ip_addr, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied from source '%s' in '%s'->'%s'\n"
% (user_name, ip_addr, this_group, "host_deny"))
sys.exit(1)
else:
# HUM... afterthought. We need it to continue if more groups exist
continue
if not match_it(this_group, "host_allow", ip_addr, config, log_file, filename):
#Stupid IOS-XR
if ip_addr == "-fix_crs_bug":
pass
elif this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed from source '%s' in '%s'->'%s'\n"
% (user_name, ip_addr, this_group, "host_allow"))
sys.exit(1)
else:
continue
if device:
if match_it(this_group, "device_deny", device, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied access to device '%s' in '%s'->'%s'\n"
% (user_name, device, this_group, "device_deny"))
sys.exit(1)
else:
continue
if not match_it(this_group, "device_permit", device, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed access to device '%s' in '%s'->'%s'\n"
% (user_name, device, this_group, "device_permit"))
sys.exit(1)
else:
continue
# Attempt to modify return pairs
want_tac_pairs = False
if config.has_option(this_group, "av_pairs"):
temp_av_pairs = get_attribute(config, this_group, "av_pairs", log_file, filename)
i = 0
for item in return_pairs:
splt = item.split('=')
if len(splt) > 1:
#DEBUG
#for thing in splt:
# log_file.write('Thing:' + thing + '\n')
for item2 in temp_av_pairs:
item2 = item2.strip()
if item2.find(',') > -1:
splt2 = item2.split(',')
if len(splt2) > 1:
#splt3 = splt2[0].split('=')
if splt[0].find(splt2[0]) > -1:
want_tac_pairs = True
return_pairs[i] = ('%s' % splt2[1])
else:
splt2 = item2.split('=')
if len(splt2) > 1:
if splt[0] == splt2[0].strip(): # strip needed?
want_tac_pairs = True
#DEBUG
#log_file.write("Replacing pairs %s=%s\n" %
# (splt2[0].strip(),
# splt2[1].strip()))
return_pairs[i] = ('%s=%s' % (splt2[0].strip(),
splt2[1].strip()))
i = i + 1
# The previous 4 statements are to deny, it we passed them, proceed
# If we are logging in, return pairs, if not, go no to check the command
# Yes, simply printing them is how you return them
# First, let's make sure we're doing service = shell. If not, just
# allow it. I currently have little knowledge of cmd's sent by other
# services which is why this code is a little klugy.
if return_pairs:
splt = av_pairs[0].split('=') # Removed service in return_pairs
if len(splt) > 1:
if not splt[1].strip() == 'shell':
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' granted non-shell access to device '%s' in group '%s' from '%s'\n"
% (user_name, device, this_group, ip_addr))
return_pairs = av_pairs[2:] # Cut the first two?
for item in return_pairs:
#DEBUG
# log_file.write("Returning:%s\n" % item.strip())
print item.strip('\n')
if want_tac_pairs:
#DEBUG
# log_file.write("Exiting status 2\n")
sys.exit(2)
else:
#DEBUG
# log_file.write("Exiting status 0\n")
sys.exit(0) # Don't even TRY to mess with the tac pairs
#Proceed with shell stuff
if not len(the_command) > 0:
#DEBUG
# log_file.write("not len(the_command) > 0\n")
for item in return_pairs:
#DEBUG
# log_file.write("Returning:%s\n" % item.strip())
print item.strip('\n')
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' granted access to device '%s' in group '%s' from '%s'\n"
% (user_name, device, this_group, ip_addr))
sys.exit(2)
else: # Check command
if match_it(this_group, "command_deny", the_command, config, log_file, filename):
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' denied command '%s' to device '%s' in '%s'->'%s'\n"
% (user_name, the_command, device, this_group, "command_deny"))
sys.exit(1)
else:
continue
elif match_it(this_group, "command_permit", the_command, config, log_file, filename):
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' allowed command '%s' to device '%s' in '%s'->'%s'\n"
% (user_name, the_command, device, this_group, "command_permit"))
sys.exit(0)
else: #exit & log if last group
if this_group == groups[-1]:
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed command '%s' to device '%s' in any group\n"
% (user_name, the_command, device))
#Can't... remember why I added this given the implicit deny
sys.exit(1)
else:
continue
#implicit deny at the end
log_file.write(strftime("%Y-%m-%d %H:%M:%S: ")
+ "User '%s' not allowed access to device '%s' from '%s' in any group\n"
% (user_name, device, ip_addr))
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -20,7 +20,14 @@
*/
#include "tac_plus.h"
#include "regexp.h"
#include <regex.h>
#ifndef REG_OK
# ifdef REG_NOERROR
# define REG_OK REG_NOERROR
# else
# define REG_OK 0
# endif
#endif
static int arg_ok(char *);
static char *assemble_args(struct author_data *);
@ -59,30 +66,6 @@ do_author(struct author_data *data)
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "do_author: user='%s'", username);
/* If this user doesn't exist in our configs, do the default */
if (!cfg_user_exists(username) && !cfg_user_exists(DEFAULT_USERNAME)) {
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "do_author: user '%s' nor 'DEFAULT' exist",
username);
if (cfg_no_user_permitted()) {
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "user '%s' or '%s' not found, permitted by "
"default", username, DEFAULT_USERNAME);
data->status = AUTHOR_STATUS_PASS_ADD;
data->output_args = NULL;
data->num_out_args = 0;
return(0);
}
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "user '%s' or '%s' not found, denied by default",
username, DEFAULT_USERNAME);
data->status = AUTHOR_STATUS_FAIL;
return(0);
}
if (!cfg_user_exists(username) && cfg_user_exists(DEFAULT_USERNAME)) {
if (debug & DEBUG_AUTHOR_FLAG) {
report(LOG_DEBUG, "Authorizing user '%s' instead of '%s'",
@ -369,9 +352,9 @@ post_authorization(char *username, struct author_data *data)
static char *
value(char *s)
{
while (*s && *s != '=' && *s != '*')
while (*s != '\0' && *s != '=' && *s != '*')
s++;
if (*s)
if (*s != '\0')
return(++s);
return(NULL);
}
@ -391,8 +374,11 @@ assemble_args(struct author_data *data)
len = 0;
for (i = 0; i < data->num_in_args; i++) {
nas_arg = data->input_args[i];
if (strncmp(nas_arg, "cmd-arg", strlen("cmd-arg"))==0)
len += strlen(value(nas_arg)) + 1;
if (strncmp(nas_arg, "cmd-arg", strlen("cmd-arg")) == 0) {
v = value(nas_arg);
if (v != NULL)
len += strlen(v) + 1;
}
}
if (len <= 0) {
@ -412,9 +398,12 @@ assemble_args(struct author_data *data)
free(buf);
return(NULL);
}
strcat(buf, v);
if (i < (data->num_in_args - 1))
strcat(buf, " ");
strncat(buf, v, len - 1);
len -= strlen(v);
if (i < (data->num_in_args - 1)) {
strncat(buf, " ", len - 1);
len -= 1;
}
}
return(buf);
}
@ -489,6 +478,7 @@ authorize_exec(char *user, struct author_data *data)
static int
authorize_cmd(char *user, char *cmd, struct author_data *data)
{
char buf[256];
NODE *node;
char *args;
int match;
@ -535,19 +525,26 @@ authorize_cmd(char *user, char *cmd, struct author_data *data)
/* The command exists. The default if nothing matches is DENY */
data->status = AUTHOR_STATUS_FAIL;
data->num_out_args = 0;
for (node = node->value1; node && args; node = node->next) {
match = regexec((regexp *) node->value1, args);
match = regexec((regex_t *)node->value1, args, 0, NULL, 0);
if (debug & DEBUG_AUTHOR_FLAG) {
report(LOG_INFO, "line %d compare %s %s '%s' & '%s' %smatch",
report(LOG_INFO, "line %d compare %s %s '%s' & '%s' %s",
node->line, cmd,
node->type == N_permit ? "permit" : "deny",
node->value, args, (match ? "" : "no "));
node->value, args,
(match == REG_NOMATCH ? "no match" :
!match ? "match" : "regex failure"));
}
if (!match)
if (match == REG_NOMATCH)
continue;
if (match != REG_OK) {
regerror(match, (regex_t *)node->value1, buf, 256);
report(LOG_INFO, "regexec error: %s on line %d: %s",
(char *)node->value, node->line, buf);
continue;
}
switch (node->type) {
case N_permit:
@ -736,7 +733,6 @@ authorize_svc(char *user, int svc, char *protocol, char *svcname,
* we'll allow it. */
if (cfg_user_svc_default_is_permit(user)) {
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "svc=%s protocol=%s svcname=%s not found, "
"permitted by default", cfg_nodestring(svc),
@ -772,7 +768,8 @@ authorize_svc(char *user, int svc, char *protocol, char *svcname,
for (i = 0; i < data->num_in_args; i++) {
if (!arg_ok(data->input_args[i])) {
char buf[MAX_INPUT_LINE_LEN+50];
sprintf(buf, "Illegal arg %s from NAS", data->input_args[i]);
snprintf(buf, sizeof(buf), "Illegal arg %s from NAS",
data->input_args[i]);
data->status = AUTHOR_STATUS_ERROR;
data->admin_msg = tac_strdup(buf);
report(LOG_ERR, "%s: Error %s", session.peer, buf);
@ -893,7 +890,6 @@ authorize_svc(char *user, int svc, char *protocol, char *svcname,
*outp++ = tac_strdup(nas_arg);
data->num_out_args++;
goto next_nas_arg;
} else {
/*
* NAS AV pair is Optional
@ -1009,7 +1005,6 @@ authorize_svc(char *user, int svc, char *protocol, char *svcname,
goto next_nas_arg;
}
next_nas_arg:;
}
/*

View File

@ -134,12 +134,11 @@ dump_nas_pak(u_char *pak)
seq = hdr->seq_no;
if (seq % 2 != 1) {
report(LOG_DEBUG, "nas packets should be odd numbered seq=%d",
seq);
report(LOG_DEBUG, "nas packets should be odd numbered seq=%d", seq);
exit(1);
}
resid = hdr->datalength;
resid = ntohl(hdr->datalength);
switch (hdr->type) {
case TAC_PLUS_AUTHEN:
start = (struct authen_start *) (pak + TAC_PLUS_HDR_SIZE);
@ -509,8 +508,8 @@ dump_tacacs_pak(u_char *pak)
acct = (struct acct_reply *) (pak + TAC_PLUS_HDR_SIZE);
report(LOG_DEBUG, "ACCT/REPLY status=%d", acct->status);
report(LOG_DEBUG, "msg_len=%d data_len=%d",
acct->msg_len, acct->data_len);
report(LOG_DEBUG, "msg_len=%d data_len=%d", acct->msg_len,
acct->data_len);
p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REPLY_FIXED_FIELDS_SIZE;

View File

@ -80,7 +80,7 @@ enable(char *passwd, struct authen_data *data)
if (level < TAC_PLUS_PRIV_LVL_MAX) {
char buf[11];
sprintf(buf, "$enab%d$", level);
snprintf(buf, sizeof(buf), "$enab%d$", level);
if (!verify(buf, passwd, data, TAC_PLUS_NORECURSE))
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
goto SUCCESS;

View File

@ -34,8 +34,6 @@
* (which is 16 bytes long). The resulting hash can safely be used as
* input to another call to create_md5_hash, as its contents are copied
* before the new hash is generated.
*
*
*/
void
create_md5_hash(int session_id, char *key, u_char version, u_char seq_no,
@ -49,7 +47,7 @@ create_md5_hash(int session_id, char *key, u_char version, u_char seq_no,
sizeof(seq_no);
if (prev_hash) {
md_len += MD5_LEN;
md_len += TAC_MD5_DIGEST_LEN;
}
mdp = md_stream = (u_char *) tac_malloc(md_len);
memcpy(mdp, &session_id, sizeof(session_id));
@ -65,8 +63,8 @@ create_md5_hash(int session_id, char *key, u_char version, u_char seq_no,
mdp += sizeof(seq_no);
if (prev_hash) {
memcpy(mdp, prev_hash, MD5_LEN);
mdp += MD5_LEN;
memcpy(mdp, prev_hash, TAC_MD5_DIGEST_LEN);
mdp += TAC_MD5_DIGEST_LEN;
}
MD5Init(&mdcontext);
MD5Update(&mdcontext, md_stream, md_len);
@ -89,8 +87,8 @@ int
md5_xor(HDR *hdr, u_char *data, char *key)
{
int i, j;
u_char hash[MD5_LEN]; /* the md5 hash */
u_char last_hash[MD5_LEN]; /* the last hash we generated */
u_char hash[TAC_MD5_DIGEST_LEN]; /* the md5 hash */
u_char last_hash[TAC_MD5_DIGEST_LEN]; /* the last hash we generated */
u_char *prev_hashp = (u_char *) NULL; /* pointer to last created
* hash */
int data_len;
@ -107,7 +105,6 @@ md5_xor(HDR *hdr, u_char *data, char *key)
return(0);
for (i = 0; i < data_len; i += 16) {
create_md5_hash(session_id, key, version, seq_no, prev_hashp, hash);
if (debug & DEBUG_MD5_HASH_FLAG) {
@ -118,17 +115,17 @@ md5_xor(HDR *hdr, u_char *data, char *key)
session_id, key, version, seq_no);
if (prev_hashp) {
report(LOG_DEBUG, "prev_hash:");
for (k = 0; k < MD5_LEN; k++)
for (k = 0; k < TAC_MD5_DIGEST_LEN; k++)
report(LOG_DEBUG, "0x%x", prev_hashp[k]);
} else {
report(LOG_DEBUG, "no prev. hash");
}
report(LOG_DEBUG, "hash: ");
for (k = 0; k < MD5_LEN; k++)
for (k = 0; k < TAC_MD5_DIGEST_LEN; k++)
report(LOG_DEBUG, "0x%x", hash[k]);
} /* debug */
memcpy(last_hash, hash, MD5_LEN);
}
memcpy(last_hash, hash, TAC_MD5_DIGEST_LEN);
prev_hashp = last_hash;
for (j = 0; j < 16; j++) {

View File

@ -41,25 +41,30 @@
* Return PW_EXPIRED if already expired
*/
#define SEC_IN_DAY (24*60*60)
#define WARNING_PERIOD 14
#define SEC_IN_DAY ((time_t)(24*60*60))
#define WARNING_PERIOD ((time_t)14)
static char *monthname[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
static int32_t days_ere_month[] = {0, 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
/*
* compare the *date in a "month day year" format to the current day. if
* greater, return PW_EXPIRED, else PW_OK.
*/
int
check_expiration(char *date)
{
int32_t day, month, year, leaps, now, expiration, warning;
int32_t day, month, year, leaps;
time_t now, expiration, warning;
char monthstr[10];
int i;
monthstr[0] = '\0';
/* If no date or a shell, let it pass. (Backward compatibility.) */
if (!date || (strlen(date) == 0) || (*date == '/'))
if (date == NULL || (strlen(date) == 0) || (*date == '/'))
return(PW_OK);
/* Parse date string. Fail it upon error. */

158
tacacs-F4.0.4.28/fdes.c Normal file
View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 1991 David G. Koontz.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms. Inclusion in a product or release
* as part of a package for sale is not agreed to. Storing this
* software in a nonvolatile storage device characterized as an
* integrated circuit providing read only memory (ROM), either as
* source code or machine executeable instructions is similarly not
* agreed to. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
* IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE
*/
#ifndef lint
char Copyright[]=
"@(#) Copyright (c) 1991 David G. Koontz\n All rights reserved.\n";
#endif
/*
* fdes.c - faster implementation of DES algorithm.
*/
#include "config.h"
#include "fdes.h"
#include "des_ip.h"
#include "des_iip.h"
#include "des_key.h"
#include "des_s_p.h"
/* Key Schedule permuted for S Box input: */
static union block_48 K_S[16];
static union block_48 *key_start;
static int des_mode;
#pragma weak tac_des
#pragma weak tac_des_loadkey
#pragma weak tac_set_des_mode
void
tac_set_des_mode(int encode)
{
if (encode) {
key_start = &K_S[0];
des_mode = SHIFT_FOR_ENCRYPT;
} else {
key_start = &K_S[15];
des_mode = SHIFT_FOR_DECRYPT;
}
}
void
tac_des_loadkey(unsigned char *key, int shift)
{
unsigned i,j;
union block_48 data;
if (!shift) /* key lookup table always shifts */
for (i = 0; i < 8; i++)
data.string[i] = key[i] >> 1;
else
for (i = 0; i < 8; i++)
data.string[i] = key[i];
for ( j = 0; j < 16; j++) /* key load must be re-entrant */
K_S[j].AB[0] = K_S[j].AB[1] = 0;
for (i = 0; i < 8; i++) { /* 8 bytes (56 bits) of key */
for(j = 0; j < 16;j++) { /* load K_S[0-16] byte at a time */
K_S[j].AB[0] |= KEY[i][data.string[i]][j][0];
K_S[j].AB[1] |= KEY[i][data.string[i]][j][1];
}
}
}
static void
no_ip_des(union LR_block *block)
{
unsigned int round;
int shift;
unsigned long temp_f;
union block_48 pre_S, *k_s;
k_s = key_start;
shift = des_mode;
for (round = 0; round < 8; round++) { /* f(R,K), 16 double rounds */
/* Expansion Permutation, E XOR K */
temp_f = block->LR[RR]; /* L/R reg. is R31,R0...R30 (D0-D31) format */
pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0]; /* S1S3S5S7 */
pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1];
k_s += shift; /* S2S4S6S8 */
/* S Box and P lookup: temp_f = f(R,K) */
temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]]
| S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]]
| S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]]
| S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]];
/* f(R,K) EXOR L */
temp_f ^= block->LR[LL]; /* temp_f is new R */
block->LR[LL] = temp_f; /* update L register */
/* Repeat round (temp_f carried through) */
pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0];
pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1];
k_s += shift;
temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]]
| S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]]
| S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]]
| S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]];
temp_f ^= block->LR[RR]; /* L is old R */
block->LR[RR] = temp_f; /* update R register */
}
/* had L/R swap here */
}
void
tac_des(union LR_block *block)
{
unsigned long temp;
union LR_block data;
data.LR[LL] = block->LR[LL];
data.LR[RR] = block->LR[RR];
temp = IP[ 0][data.string[0]] | IP[ 1][data.string[1]] |
IP[ 2][data.string[2]] | IP[ 3][data.string[3]] |
IP[ 4][data.string[4]] | IP[ 5][data.string[5]] |
IP[ 6][data.string[6]] | IP[ 7][data.string[7]];
data.LR[LL] =
IP[ 8][data.string[0]] | IP[ 9][data.string[1]] |
IP[10][data.string[2]] | IP[11][data.string[3]] |
IP[12][data.string[4]] | IP[13][data.string[5]] |
IP[14][data.string[6]] | IP[15][data.string[7]];
data.LR[RR] = temp;
no_ip_des(&data);
temp = IIP[ 0][data.string[0]] | IIP[ 1][data.string[1]] |
IIP[ 2][data.string[2]] | IIP[ 3][data.string[3]] |
IIP[ 4][data.string[4]] | IIP[ 5][data.string[5]] |
IIP[ 6][data.string[6]] | IIP[ 7][data.string[7]];
block->LR[AA] =
IIP[ 8][data.string[0]] | IIP[ 9][data.string[1]] |
IIP[10][data.string[2]] | IIP[11][data.string[3]] |
IIP[12][data.string[4]] | IIP[13][data.string[5]] |
IIP[14][data.string[6]] | IIP[15][data.string[7]];
block->LR[BB] = temp;
}

68
tacacs-F4.0.4.28/fdes.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 1990 David G. Koontz.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the above mentioned individual.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE
*/
/*
* fdes.h - faster implementation of DES algorithm
*/
#define BIT(x) ( 1 << x )
#define AA 0
#define BB 1
#define RR 1
#define LL 0
#define SHIFT_FOR_ENCRYPT 1
#define SHIFT_FOR_DECRYPT -1
/* How to find R Register Bits affecting S boxes: */
/* this is an ENDIAN referenced byte index */
#ifndef WORDS_BIGENDIAN /* BIG_ENDIAN */
#define S1 3
#define S2 7
#define S3 2
#define S4 6
#define S5 1
#define S6 5
#define S7 0
#define S8 4
#else /* LITTLE_ENDIAN */
#define S1 0
#define S2 4
#define S3 1
#define S4 5
#define S5 2
#define S6 6
#define S7 3
#define S8 7
#endif
union LR_block {
unsigned char string[8];
unsigned long LR[2];
};
union block_48 {
unsigned char string[8];
unsigned long AB[2];
unsigned short SxSy[4];
};
#define DES_MODE_ENCRYPT 1
#define DES_MODE_DECRYPT 0
#define DES_KEY_SHIFT 1
#define DES_KEY_NOSHIFT 0
void tac_des(union LR_block *);
void tac_des_loadkey(unsigned char *, int);
void tac_set_des_mode(int);

View File

@ -38,7 +38,7 @@ calculate_hash(char *name)
int c;
while (c = *name++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
hash = ((hash >> 5) + hash) + c; /* hash * 33 + c */
return hash;
}
@ -52,8 +52,8 @@ hash_lookup(void **hashtab, char *name)
entry = hashtab[hashslot];
while (entry) {
/* Node exists in table. return it */
if (STREQ(name, entry->name))
/* Node exists in table. return it */
return(entry);
entry = entry->hash;
}
@ -114,7 +114,6 @@ void * hash_delete_entry(void **hashtab, char *entry_name) {
return NULL;
}
/* Return an array of pointers to all the entries in a hash table */
void **
hash_get_entries(void **hashtab)

View File

@ -50,4 +50,3 @@ int main (int argc, char **argv) {
}
exit(0);
}

View File

@ -21,8 +21,6 @@
#include "tac_plus.h"
#ifdef MAXSESS
#if HAVE_CTYPE_H
# include <ctype.h>
#endif
@ -31,6 +29,8 @@
char *wholog = TACPLUS_WHOLOGFILE;
static int timed_read(int, unsigned char *, int, int);
/*
* initialize wholog file for tracking of user logins/logouts from
* accounting records.
@ -109,7 +109,6 @@ process_stop_record(struct identity *idp)
tac_lockfd(wholog, fileno(fp));
for (recnum = 0; 1; recnum++) {
fseek(fp, recnum * sizeof(struct peruser), SEEK_SET);
if (fread(&pu, sizeof(pu), 1, fp) <= 0) {
@ -166,11 +165,11 @@ process_start_record(struct identity *idp)
}
}
/* This is a START record, so write a new record or update the existing
/*
* This is a START record, so write a new record or update the existing
* one. Note that we zero the memory, so the strncpy()'s will truncate
* long names and always leave a null-terminated string.
*/
memset(&pu, 0, sizeof(pu));
strncpy(pu.username, idp->username, sizeof(pu.username) - 1);
strncpy(pu.NAS_name, idp->NAS_name, sizeof(pu.NAS_name) - 1);
@ -179,7 +178,6 @@ process_start_record(struct identity *idp)
/* Already in DB? */
if (foundrec >= 0) {
if (debug & DEBUG_MAXSESS_FLAG) {
report(LOG_DEBUG,
"START record -- overwrite existing %s entry %d for %s "
@ -262,8 +260,8 @@ loguser(struct acct_rec *rec)
*
* Return -1 on error, eof or timeout. Otherwise return number of bytes read.
*/
int
timed_read(int fd, u_char *ptr, int nbytes, int timeout)
static int
timed_read(int fd, unsigned char *ptr, int nbytes, int timeout)
{
int nread;
struct pollfd pfds;
@ -322,7 +320,6 @@ timed_read(int fd, u_char *ptr, int nbytes, int timeout)
/* NOTREACHED */
}
#ifdef MAXSESS_FINGER
/*
* Contact a NAS (using finger) to check how many sessions this USER
* is currently running on it.
@ -346,64 +343,63 @@ timed_read(int fd, u_char *ptr, int nbytes, int timeout)
* Column zero contains a space or an asterisk character. The line number
* starts at column 1 and is 3 digits wide. User names start at column 13,
* with a maximum possible width of 10.
*
* Returns the number of sessions/connections, or zero on error.
*/
static int
ckfinger(char *user, char *nas, struct identity *idp)
{
struct sockaddr_in sin;
struct servent *serv;
int count, s, bufsize;
struct addrinfo hints, *res, *resp;
int count, s, bufsize, ecode;
char *buf, *p, *pn;
int incr = 4096, slop = 32;
u_long inaddr;
char *curport = portname(idp->NAS_port);
char *name;
/* The finger service, aka port 79 */
serv = getservbyname("finger", "tcp");
if (serv) {
sin.sin_port = serv->s_port;
} else {
sin.sin_port = 79;
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
/* Get IP addr for the NAS */
inaddr = inet_addr(nas);
if (inaddr != -1) {
/* A dotted decimal address */
memcpy(&sin.sin_addr, &inaddr, sizeof(inaddr));
sin.sin_family = AF_INET;
} else {
struct hostent *host = gethostbyname(nas);
if (host == NULL) {
report(LOG_ERR, "ckfinger: gethostbyname %s failure: %s",
nas, strerror(errno));
if ((ecode = getaddrinfo(nas, "finger", &hints, &res)) != 0) {
report(LOG_ERR, "ckfinger: getaddrinfo %s failure: %s", nas,
gai_strerror(ecode));
return(0);
}
memcpy(&sin.sin_addr, host->h_addr, host->h_length);
sin.sin_family = host->h_addrtype;
}
s = socket(AF_INET, SOCK_STREAM, 0);
ecode = 0;
for (resp = res; resp != NULL; resp = resp->ai_next) {
s = socket(resp->ai_family, resp->ai_socktype, resp->ai_protocol);
if (s < 0) {
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
continue;
report(LOG_ERR, "ckfinger: socket: %s", strerror(errno));
freeaddrinfo(res);
return(0);
}
if ((ecode = connect(s, resp->ai_addr, res->ai_addrlen)) < 0) {
close(s);
continue;
} else
break;
}
freeaddrinfo(res);
/* socket failure / no supported address families */
if (resp == NULL && ecode == 0) {
report(LOG_ERR, "ckfinger: socket: %s", strerror(errno));
return(0);
}
if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
report(LOG_ERR, "ckfinger: connect failure %s", strerror(errno));
close(s);
if (ecode != 0) {
report(LOG_ERR, "ckfinger: connect %s: %s", nas, strerror(errno));
return(0);
}
/* Read in the finger output into a single flat buffer */
/* Read the finger output into a single flat buffer */
buf = NULL;
bufsize = 0;
for (;;) {
int x;
buf = tac_realloc(buf, bufsize + incr + slop);
x = timed_read(s, buf + bufsize, incr, 10);
x = timed_read(s, (unsigned char *)(buf + bufsize), incr, 10);
if (x <= 0) {
break;
}
@ -503,19 +499,18 @@ ckfinger(char *user, char *nas, struct identity *idp)
* Use finger to contact each NAS that wholog says has this user
* logged on.
*/
static int
int
countusers_by_finger(struct identity *idp)
{
FILE *fp;
struct peruser pu;
int x, naddr, nsess, n;
char **addrs, *uname;
char **addrs;
fp = fopen(wholog, "r+");
if (fp == NULL) {
return(0);
}
uname = idp->username;
/* Count sessions */
tac_lockfd(wholog, fileno(fp));
@ -527,7 +522,7 @@ countusers_by_finger(struct identity *idp)
int dup;
/* Ignore records for everyone except this user */
if (strcmp(pu.username, uname)) {
if (strcmp(pu.username, idp->username)) {
continue;
}
/* Only check a given NAS once */
@ -549,13 +544,13 @@ countusers_by_finger(struct identity *idp)
/* Validate via finger */
if (debug & DEBUG_MAXSESS_FLAG) {
report(LOG_DEBUG, "Running finger on %s for user %s/%s",
pu.NAS_name, uname, idp->NAS_port);
pu.NAS_name, idp->username, idp->NAS_port);
}
n = ckfinger(uname, pu.NAS_name, idp);
n = ckfinger(idp->username, pu.NAS_name, idp);
if (debug & DEBUG_MAXSESS_FLAG) {
report(LOG_DEBUG, "finger reports %d active session%s for %s on %s",
n, (n == 1 ? "" : "s"), uname, pu.NAS_name);
n, (n == 1 ? "" : "s"), idp->username, pu.NAS_name);
}
nsess += n;
}
@ -569,13 +564,12 @@ countusers_by_finger(struct identity *idp)
return(nsess);
}
#endif /* MAXSESS_FINGER */
/*
* Estimate how many sessions a named user currently owns by looking in
* the wholog file.
*/
static int
int
countuser(struct identity *idp)
{
FILE *fp;
@ -591,7 +585,6 @@ countuser(struct identity *idp)
tac_lockfd(wholog, fileno(fp));
nsess = 0;
while (fread(&pu, sizeof(pu), 1, fp) > 0) {
/* Current user */
if (strcmp(pu.username, idp->username)) {
continue;
@ -608,80 +601,3 @@ countuser(struct identity *idp)
fclose(fp);
return(nsess);
}
/*
* is_async()
* Tell if the named NAS port is an async-like device.
*
* Finger reports async users, but not ISDN ones (yay). So we can do
* a "slow" double check for async, but not ISDN.
*/
static int
is_async(char *portname)
{
if (isdigit((int) *portname) || !strncmp(portname, "Async", 5) ||
!strncmp(portname, "tty", 3)) {
return(1);
}
return(0);
}
/*
* See if this user can have more sessions.
*/
int
maxsess_check_count(char *user, struct author_data *data)
{
int sess, maxsess;
struct identity *id;
/* No max session configured--don't check */
id = data->id;
maxsess = cfg_get_intvalue(user, TAC_IS_USER, S_maxsess, TAC_PLUS_RECURSE);
if (!maxsess) {
if (debug & (DEBUG_MAXSESS_FLAG | DEBUG_AUTHOR_FLAG)) {
report(LOG_DEBUG, "%s may run an unlimited number of sessions",
user);
}
return(0);
}
/* Count sessions for this user by looking in our wholog file */
sess = countuser(id);
if (debug & (DEBUG_MAXSESS_FLAG | DEBUG_AUTHOR_FLAG)) {
report(LOG_DEBUG, "user %s is running %d out of a maximum of %d "
"sessions", user, sess, maxsess);
}
#ifdef MAXSESS_FINGER
if ((sess >= maxsess) && is_async(id->NAS_port)) {
/*
* If we have finger available, double check this count by contacting
* the NAS
*/
sess = countusers_by_finger(id);
}
#endif
/* If it's really too high, don't authorize more services */
if (sess >= maxsess) {
char buf[80];
sprintf(buf,
"Login failed; too many active sessions (%d maximum)",
maxsess);
data->msg = tac_strdup(buf);
if (debug & (DEBUG_AUTHOR_FLAG | DEBUG_MAXSESS_FLAG)) {
report(LOG_DEBUG, data->msg);
}
data->status = AUTHOR_STATUS_FAIL;
data->output_args = NULL;
data->num_out_args = 0;
return(1);
}
return(0);
}
#endif /* MAXSESS */

View File

@ -0,0 +1,110 @@
/*
* $Id: maxsess.c,v 1.12 2009-07-16 18:13:19 heas Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "tac_plus.h"
#if HAVE_CTYPE_H
# include <ctype.h>
#endif
#include <poll.h>
#include <signal.h>
/*
* is_async()
* Tell if the named NAS port is an async-like device.
*
* Finger reports async users, but not ISDN ones (yay). So we can do
* a "slow" double check for async, but not ISDN.
*/
static int
is_async(char *portname)
{
if (isdigit((int) *portname) || !strncmp(portname, "Async", 5) ||
!strncmp(portname, "tty", 3)) {
return(1);
}
return(0);
}
/*
* See if this user can have more sessions.
*/
#ifdef MAXSESS
int
maxsess_check_count(char *user, struct author_data *data)
{
int sess, maxsess;
struct identity *id;
/* No max session configured--don't check */
id = data->id;
#if MAXSESS
maxsess = cfg_get_intvalue(user, TAC_IS_USER, S_maxsess, TAC_PLUS_RECURSE);
#else
maxsess = 0;
#endif
if (!maxsess) {
if (debug & (DEBUG_MAXSESS_FLAG | DEBUG_AUTHOR_FLAG)) {
report(LOG_DEBUG, "%s may run an unlimited number of sessions",
user);
}
return(0);
}
/* Count sessions for this user by looking in our wholog file */
sess = countuser(id);
if (debug & (DEBUG_MAXSESS_FLAG | DEBUG_AUTHOR_FLAG)) {
report(LOG_DEBUG, "user %s is running %d out of a maximum of %d "
"sessions", user, sess, maxsess);
}
#ifdef MAXSESS_FINGER
if ((sess >= maxsess) && is_async(id->NAS_port)) {
/*
* If we have finger available, double check this count by contacting
* the NAS
*/
sess = countusers_by_finger(id);
}
#endif
/* If it's really too high, don't authorize more services */
if (sess >= maxsess) {
char buf[80];
snprintf(buf, sizeof(buf),
"Login failed; too many active sessions (%d maximum)", maxsess);
data->msg = tac_strdup(buf);
if (debug & (DEBUG_AUTHOR_FLAG | DEBUG_MAXSESS_FLAG)) {
report(LOG_DEBUG, data->msg);
}
data->status = AUTHOR_STATUS_FAIL;
data->output_args = NULL;
data->num_out_args = 0;
return(1);
}
return(0);
}
#endif

View File

@ -44,7 +44,7 @@
* documentation and/or software.
*/
#include <config.h>
#include "config.h"
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>

View File

@ -45,7 +45,7 @@
* documentation and/or software.
*/
#include <config.h>
#include "config.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif

View File

@ -55,6 +55,8 @@
# include <stdint.h>
#endif
#define MD5_SIZE 16
/* typedef a generic pointer type */
typedef unsigned char *POINTER;

View File

@ -21,6 +21,7 @@
#include "tac_plus.h"
#include <poll.h>
#include <netdb.h>
#include <signal.h>
#include <time.h>
@ -44,7 +45,7 @@ get_authen_continue(void)
HDR *hdr;
u_char *pak;
struct authen_cont *cont;
char msg[255];
char msg[NI_MAXHOST + 256];
pak = read_packet();
if (!pak)
@ -53,9 +54,10 @@ get_authen_continue(void)
cont = (struct authen_cont *)(pak + TAC_PLUS_HDR_SIZE);
if ((hdr->type != TAC_PLUS_AUTHEN) || (hdr->seq_no <= 1)) {
sprintf(msg,
"%s: Bad packet type=%d/seq no=%d when expecting authentication cont",
session.peer, hdr->type, hdr->seq_no);
if (snprintf(msg, sizeof(msg), "%s: Bad packet type=%d/seq no=%d "
"when expecting authentication cont", session.peer,
hdr->type, hdr->seq_no) == -1)
strcpy(msg, "");
report(LOG_ERR, msg);
send_authen_error(msg);
return(NULL);
@ -95,7 +97,7 @@ read_packet(void)
/* read a packet header */
len = sockread(session.sock, (u_char *)&hdr,
TAC_PLUS_HDR_SIZE, cfg_get_readtimeout());
TAC_PLUS_HDR_SIZE, TAC_PLUS_READ_TIMEOUT);
if (len != TAC_PLUS_HDR_SIZE) {
report(LOG_DEBUG, "Read %d bytes from %s %s, expecting %d",
len, session.peer, session.port, TAC_PLUS_HDR_SIZE);
@ -114,7 +116,7 @@ read_packet(void)
if ((ntohl(hdr.datalength) & ~0xffffUL) ||
(len < TAC_PLUS_HDR_SIZE) || (len > 0x10000)) {
report(LOG_ERR, "%s: Illegal data size: %lu\n", session.peer,
ntohl(hdr.datalength));
(unsigned long)ntohl(hdr.datalength));
return(NULL);
}
pkt = (u_char *)tac_malloc(len);
@ -127,7 +129,7 @@ read_packet(void)
/* read the rest of the packet data */
if (sockread(session.sock, data, ntohl(hdr.datalength),
cfg_get_readtimeout()) != ntohl(hdr.datalength)) {
TAC_PLUS_READ_TIMEOUT) != ntohl(hdr.datalength)) {
report(LOG_ERR, "%s: start_session: bad socket read", session.peer);
free(pkt);
return(NULL);
@ -136,7 +138,7 @@ read_packet(void)
session.last_exch = time(NULL);
if (session.seq_no != hdr.seq_no) {
report(LOG_ERR, "%s: Illegal session seq # %d != packet seq # %d",
report(LOG_ERR, "%s: Illegal session seq #, expecting %d, received %d",
session.peer, session.seq_no, hdr.seq_no);
free(pkt);
return(NULL);
@ -228,9 +230,11 @@ send_acct_reply(u_char status, char *msg, char *data)
void
send_authen_error(char *msg)
{
char buf[255];
char buf[NI_MAXHOST + 256];
sprintf(buf, "%s %s: %s", session.peer, session.port, msg);
if (snprintf(buf, sizeof(buf), "%s %s: %s", session.peer, session.port,
msg) == -1)
strcpy(buf, "");
report(LOG_ERR, buf);
send_authen_reply(TAC_PLUS_AUTHEN_STATUS_ERROR, buf, strlen(buf), NULL, 0,
0);
@ -380,22 +384,21 @@ send_error_reply(int type, char *msg)
switch (type) {
case TAC_PLUS_AUTHEN:
send_authen_error(msg);
return;
break;
case TAC_PLUS_AUTHOR:
send_author_reply(AUTHOR_STATUS_ERROR, msg, NULL, 0, NULL);
return;
break;
case TAC_PLUS_ACCT:
send_acct_reply(TAC_PLUS_ACCT_STATUS_ERROR, msg, NULL);
return;
break;
default:
report(LOG_ERR, "Illegal type %d for send_error_reply", type);
return;
break;
}
/*NOTREACHED*/
return;
}
@ -419,7 +422,7 @@ sockread(int fd, u_char *ptr, int nbytes, int timeout)
int status = poll(&pfds, 1, timeout * 1000);
if (status == 0) {
report(LOG_DEBUG, "%s: timeout reading fd %d (%d secs)", session.peer, fd, cfg_get_readtimeout());
report(LOG_DEBUG, "%s: timeout reading fd %d", session.peer, fd);
return(-1);
}
if (status < 0) {
@ -554,7 +557,7 @@ write_packet(u_char *pak)
return(-1);
}
if (sockwrite(session.sock, pak, len, cfg_get_writetimeout()) != len) {
if (sockwrite(session.sock, pak, len, TAC_PLUS_WRITE_TIMEOUT) != len) {
return(-1);
}
session.last_exch = time(NULL);

View File

@ -60,6 +60,9 @@ parser_init(void)
declare("access", S_access);
declare("accounting", S_accounting);
#ifdef ACECLNT
declare("aceclnt", S_aceclnt);
#endif
#ifdef ACLS
declare("acl", S_acl);
#endif
@ -93,7 +96,6 @@ parser_init(void)
declare("ipx", S_ipx);
declare("key", S_key);
declare("lcp", S_lcp);
declare("md5", S_md5);
#ifdef MAXSESS
declare("maxsess", S_maxsess);
#endif
@ -124,6 +126,7 @@ parser_init(void)
declare("readtimeout", S_readtimeout);
declare("writetimeout", S_writetimeout);
declare("accepttimeout", S_accepttimeout);
}
/* Return a keyword code if a keyword is recognized. 0 otherwise */
@ -178,6 +181,10 @@ codestring(int type)
#ifdef SKEY
case S_skey:
return("skey");
#endif
#ifdef ACECLNT
case S_aceclnt:
return("aceclnt");
#endif
case S_name:
return("name");
@ -259,8 +266,6 @@ codestring(int type)
return("prompt");
case S_logging:
return("logging");
case S_md5:
return("md5");
#ifdef HAVE_PAM
case S_pam:
return("PAM");

View File

@ -90,7 +90,7 @@
# define S_pam 49
#endif
#define S_syslog 50
#define S_md5 51
#define S_aceclnt 51
#define S_maxprocs 52
#define S_maxprocsperclt 53
#define S_readtimeout 54

View File

@ -83,19 +83,19 @@ lookup(char *sym, struct author_data *data)
return(tac_strdup(data->id->NAC_address));
}
if (STREQ(sym, "priv")) {
sprintf(buf, "%d", data->id->priv_lvl);
snprintf(buf, sizeof(buf), "%d", data->id->priv_lvl);
return(tac_strdup(buf));
}
if (STREQ(sym, "method")) {
sprintf(buf, "%d", data->authen_method);
snprintf(buf, sizeof(buf), "%d", data->authen_method);
return(tac_strdup(buf));
}
if (STREQ(sym, "type")) {
sprintf(buf, "%d", data->authen_type);
snprintf(buf, sizeof(buf), "%d", data->authen_type);
return(tac_strdup(buf));
}
if (STREQ(sym, "service")) {
sprintf(buf, "%d", data->service);
snprintf(buf, sizeof(buf), "%d", data->service);
return(tac_strdup(buf));
}
if (STREQ(sym, "status")) {
@ -204,17 +204,17 @@ waitfor(int pid)
ret = waitpid(pid, &status, 0);
if (ret < 0) {
report(LOG_ERR, "%s: pid %l no child exists", session.peer, (long)pid);
report(LOG_ERR, "%s: pid %ld no child exists", session.peer, (long)pid);
return(-1);
}
if (!WIFEXITED(status)) {
report(LOG_ERR, "%s: pid %l child in illegal state", session.peer,
report(LOG_ERR, "%s: pid %ld child in illegal state", session.peer,
(long)pid);
return(-1);
}
if (debug & DEBUG_AUTHOR_FLAG)
report(LOG_DEBUG, "pid %d child exited status %l", (long)pid,
WEXITSTATUS(status));
report(LOG_DEBUG, "pid %ld child exited status %ld", (long)pid,
(long)WEXITSTATUS(status));
return(WEXITSTATUS(status));
}

View File

@ -21,7 +21,6 @@
#include "tac_plus.h"
#include "expire.h"
#include "md5.h"
#ifdef HAVE_CRYPT_H
# include <crypt.h>
@ -33,7 +32,11 @@
#if HAVE_PAM
# ifdef __APPLE__ /* MacOS X */
# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060
# include <security/pam_appl.h>
# else
# include <pam/pam_appl.h>
# endif
# else
# include <security/pam_appl.h>
# endif
@ -42,18 +45,16 @@ static int pam_tacacs(int, const struct pam_message **, struct pam_response **,
#endif
/*
* Generic password verification routines for des, md5, file and cleartext passwords
* Generic password verification routines for des, file and cleartext passwords
*/
static int etc_passwd_file_verify(char *, char *, struct authen_data *);
static int des_verify(char *, char *);
static int md5_verify(char *, char *);
#if HAVE_PAM
static int pam_verify(char *, char *, struct authen_data *data);
#endif
static int passwd_file_verify(char *, char *, struct authen_data *, char *);
// Global password variable for pap PAM support
static char *predef_passwd;
extern char *progname;
/* Adjust data->status depending on whether a user has expired or not */
void
@ -66,8 +67,10 @@ set_expiration_status(char *exp_date, struct authen_data *data)
return;
}
/* Check the expiration date, if any. If NULL, this check will return
* PW_OK */
/*
* Check the expiration date, if any. If NULL, this check will return
* PW_OK
*/
expired = check_expiration(exp_date);
switch (expired) {
@ -77,7 +80,7 @@ set_expiration_status(char *exp_date, struct authen_data *data)
exp_date ? exp_date : "<no expiry date set>");
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
return;
break;
case PW_EXPIRING:
if (debug & DEBUG_PASSWD_FLAG)
@ -87,7 +90,7 @@ set_expiration_status(char *exp_date, struct authen_data *data)
free(data->server_msg);
data->server_msg = tac_strdup("Password will expire soon");
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
return;
break;
case PW_EXPIRED:
if (debug & DEBUG_PASSWD_FLAG)
@ -97,16 +100,15 @@ set_expiration_status(char *exp_date, struct authen_data *data)
free(data->server_msg);
data->server_msg = tac_strdup("Password has expired");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return;
break;
default:
report(LOG_ERR, "%s: Bogus return value %d from check_expiration",
session.peer, expired);
data->status = TAC_PLUS_AUTHEN_STATUS_ERROR;
return;
break;
}
/*NOTREACHED*/
return;
}
@ -131,7 +133,7 @@ verify(char *name, char *passwd, struct authen_data *data, int recurse)
* If there is no login or pap password for this user, see if there is
* a global password that can be used.
*/
if (!cfg_passwd) {
if (cfg_passwd == NULL) {
cfg_passwd = cfg_get_global_secret(name, recurse);
}
@ -140,7 +142,7 @@ verify(char *name, char *passwd, struct authen_data *data, int recurse)
* matter) but the default authentication = file <file> statement
* has been issued, attempt to use this password file
*/
if (!cfg_passwd) {
if (cfg_passwd == NULL) {
char *file = cfg_get_authen_default();
if (file) {
return(passwd_file_verify(name, passwd, data, file));
@ -168,7 +170,7 @@ verify(char *name, char *passwd, struct authen_data *data, int recurse)
#endif
p = tac_find_substring("cleartext ", cfg_passwd);
if (p) {
if (p != NULL) {
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "verify daemon %s == NAS %s", p, passwd);
@ -204,27 +206,13 @@ verify(char *name, char *passwd, struct authen_data *data, int recurse)
return(data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
}
/* Try to verify a md5 password hash */
p = tac_find_substring("md5 ", cfg_passwd);
if (p) {
if (!md5_verify(passwd, p)) {
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return(0);
} else {
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
}
exp_date = cfg_get_expires(name, recurse);
set_expiration_status(exp_date, data);
return(data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
}
p = tac_find_substring("file ", cfg_passwd);
if (p) {
return(passwd_file_verify(name, passwd, data, p));
}
/* Oops. No idea what kind of password this is. This should never
/*
* Oops. No idea what kind of password this is. This should never
* happen as the parser should never create such passwords.
*/
report(LOG_ERR, "%s: Error cannot identify password type %s for %s",
@ -364,10 +352,10 @@ etc_passwd_file_verify(char *user, char *supplied_passwd,
* Convert this to ascii so that the traditional tacacs
* password expiration routines work correctly.
*/
if (spwd->sp_expire > 0) {
long secs = spwd->sp_expire * 24 * 60 * 60;
char *p = ctime(&secs);
memcpy(buf, p + 4, 7);
memcpy(buf + 7, p + 20, 4);
buf[11] = '\0';
@ -481,49 +469,15 @@ des_verify(char *users_passwd, char *encrypted_passwd)
return(0);
}
static int
md5_verify(char *users_passwd, char *encrypted_passwd)
{
MD5_CTX mdcontext;
u_char digest[MD5_LEN];
char pwdigesthex[33];
int i;
MD5Init(&mdcontext);
MD5Update(&mdcontext, (u_char *)users_passwd, sizeof(users_passwd));
MD5Final((u_char *) digest, &mdcontext);
/* Convert to Hex */
static const char hex[] = "0123456789abcdef";
for (i=0;i<MD5_LEN;i++) {
pwdigesthex[i+i] = hex[digest[i] >> 4];
pwdigesthex[i+i+1] = hex[digest[i] & 0x0f];
}
pwdigesthex[i+i]='\0';
if (debug && DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "md5_verify: got: %s wanted: %s", pwdigesthex, encrypted_passwd);
if (strcmp(pwdigesthex, encrypted_passwd) == 0) {
if(debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "Password is correct");
return(1);
}
if(debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "Password is incorrect");
return(0);
}
#if HAVE_PAM
/* pam_conv (PAM conversation) callback */
static int
pam_tacacs(int nmsg, const struct pam_message **pmpp, struct pam_response
**prpp, void *appdata_ptr)
{
int i;
struct authen_cont *acp;
char *passwd = (char *)appdata_ptr;
u_char *reply, *rp;
if (debug & DEBUG_PASSWD_FLAG)
@ -541,11 +495,12 @@ pam_tacacs(int nmsg, const struct pam_message **pmpp, struct pam_response
switch (pmpp[i]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_ERR, "%s %s: PAM_PROMPT_ECHO_OFF", session.peer,
report(LOG_DEBUG, "%s %s: PAM_PROMPT_ECHO_OFF", session.peer,
session.port);
if (strcmp(predef_passwd, "") != 0) {
prpp[i]->resp = predef_passwd;
/* pre-supplied password, such as service=PAP, or prompt for it */
if (passwd != NULL && strlen(passwd) > 0) {
prpp[i]->resp = tac_strdup(passwd);
} else {
send_authen_reply(TAC_PLUS_AUTHEN_STATUS_GETPASS,
(char *)pmpp[i]->msg,
@ -554,19 +509,20 @@ pam_tacacs(int nmsg, const struct pam_message **pmpp, struct pam_response
reply = get_authen_continue();
if (!reply) {
/* Typically due to a premature connection close */
report(LOG_ERR, "%s %s: Null reply packet, expecting CONTINUE",
session.peer, session.port);
report(LOG_ERR, "%s %s: Null reply packet, expecting "
"CONTINUE", session.peer, session.port);
goto fail;
}
acp = (struct authen_cont *)(reply + TAC_PLUS_HDR_SIZE);
rp = reply + TAC_PLUS_HDR_SIZE + TAC_AUTHEN_CONT_FIXED_FIELDS_SIZE;
rp = reply + TAC_PLUS_HDR_SIZE +
TAC_AUTHEN_CONT_FIXED_FIELDS_SIZE;
/*
* A response to our GETDATA/GETPASS request. Create a
* null-terminated string for authen_data.
*/
prpp[i]->resp = (char *)tac_malloc(acp->user_msg_len + 1);
bcopy(rp, prpp[i]->resp, acp->user_msg_len);
memcpy(prpp[i]->resp, rp, acp->user_msg_len);
prpp[i]->resp[acp->user_msg_len] = '\0';
free(reply);
@ -574,7 +530,7 @@ pam_tacacs(int nmsg, const struct pam_message **pmpp, struct pam_response
break;
case PAM_PROMPT_ECHO_ON:
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_ERR, "%s %s: PAM_PROMPT_ECHO_ON", session.peer,
report(LOG_DEBUG, "%s %s: PAM_PROMPT_ECHO_ON", session.peer,
session.port);
send_authen_reply(TAC_PLUS_AUTHEN_STATUS_GETDATA,
@ -645,9 +601,8 @@ pam_verify(char *user, char *passwd, struct authen_data *data)
int err;
int acct;
int pam_flag;
struct pam_conv conv = { pam_tacacs, NULL };
struct pam_conv conv = { pam_tacacs, passwd };
pam_handle_t *pamh = NULL;
predef_passwd = passwd;
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "pam_verify %s %s", user, passwd);
@ -658,7 +613,7 @@ pam_verify(char *user, char *passwd, struct authen_data *data)
return(0);
}
if ((err = pam_start("tac_plus", user, &conv, &pamh)) != PAM_SUCCESS) {
if ((err = pam_start(progname, user, &conv, &pamh)) != PAM_SUCCESS) {
report(LOG_ERR, "pam_start failed: %s", pam_strerror(pamh, err));
pam_end(pamh, err);
if (debug & DEBUG_PASSWD_FLAG)
@ -703,7 +658,7 @@ pam_verify(char *user, char *passwd, struct authen_data *data)
break;
default:
if (debug & DEBUG_PASSWD_FLAG)
report(LOG_DEBUG, "pam_acct_mgmt() returned unknown value %d",
report(LOG_DEBUG, "pam_account_mgmt returned unknown value %d",
acct);
break;
}

View File

@ -20,7 +20,6 @@
*/
#include "tac_plus.h"
#include "pathsl.h"
#include <stdio.h>
#ifdef AIX
@ -37,10 +36,12 @@
FILE *ostream = NULL;
char *logfile = TACPLUS_LOGFILE;
/* report:
*
* This routine reports errors and such via stderr and syslog() if
* appopriate. It just helps avoid a lot of if-else in the code.
* appopriate.
*
* LOG_DEBUG messages are ignored unless debugging is on.
* All other priorities are always logged to syslog.
@ -57,92 +58,20 @@ report(priority, fmt, va_alist)
va_dcl /* no terminating semi-colon */
#endif
{
char msg[255]; /* temporary string */
char *fp, *bufp, *charp;
int len, m, i, n;
char digits[16];
char msg[4096]; /* temporary string */
va_list ap;
charp = NULL;
m = 0;
int ret;
#ifdef __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
/* ensure that msg is never overwritten */
n = 255;
fp = fmt;
len = 0;
msg[n-1] = '\0';
bufp = msg;
while (*fp) {
if (*fp != '%') {
if ((len+1) >= n) {
break;
}
*bufp++ = *fp++;
len++;
continue;
}
/* seen a '%' */
fp++;
switch (*fp) {
case 's':
fp++;
charp = va_arg(ap, char *);
m = strlen(charp);
break;
case 'u':
fp++;
i = va_arg(ap, uint);
sprintf(digits, "%u", i);
m = strlen(digits);
charp = digits;
break;
case 'x':
fp++;
i = va_arg(ap, uint);
sprintf(digits, "%x", i);
m = strlen(digits);
charp = digits;
break;
case 'd':
fp++;
i = va_arg(ap, int);
sprintf(digits, "%d", i);
m = strlen(digits);
charp = digits;
break;
}
if ((len + m + 1) >= n) {
break;
}
memcpy(bufp, charp, m);
bufp += m;
len += m;
continue;
}
msg[len] = '\0';
/* check we never overwrote the end of the buffer */
if (msg[n-1]) {
abort();
}
ret = vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
if (ret < 0)
msg[0] = '\0';
if (console) {
if (!ostream)
@ -159,14 +88,14 @@ report(priority, fmt, va_alist)
if (debug) {
int logfd;
logfd = open(TACPLUS_LOGFILE, O_CREAT | O_WRONLY | O_APPEND, 0644);
logfd = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0644);
if (logfd >= 0) {
char buf[512];
time_t t = time(NULL);
char *ct = ctime(&t);
ct[24] = '\0';
tac_lockfd(TACPLUS_LOGFILE, logfd);
tac_lockfd(logfile, logfd);
sprintf(buf, "%s [%ld]: ", ct, (long)getpid());
write(logfd, buf, strlen(buf));
if (priority == LOG_ERR)

View File

@ -171,7 +171,7 @@ outbound_pap(struct authen_data *data)
static void
outbound_chap(struct authen_data *data)
{
char *name, *secret, *chal, digest[MD5_LEN];
char *name, *secret, *chal, digest[TAC_MD5_DIGEST_LEN];
char *p;
u_char *mdp;
char id;
@ -252,9 +252,9 @@ outbound_chap(struct authen_data *data)
/*
* Now return the calculated response value */
data->server_data = tac_malloc(MD5_LEN);
memcpy(data->server_data, digest, MD5_LEN);
data->server_dlen = MD5_LEN;
data->server_data = tac_malloc(TAC_MD5_DIGEST_LEN);
memcpy(data->server_data, digest, TAC_MD5_DIGEST_LEN);
data->server_dlen = TAC_MD5_DIGEST_LEN;
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
}

View File

@ -91,7 +91,7 @@ do_sendpass_fn(struct authen_data *data)
exp_date = cfg_get_expires(name, TAC_PLUS_RECURSE);
/* The user exists. Check her expiration date, if any */
/* The user exists. Check the expiration date, if any */
expired = check_expiration(exp_date);
switch (expired) {

View File

@ -99,7 +99,7 @@ skey_fn(struct authen_data *data)
/* Unless we're enabling, we need a username */
if (data->service != TAC_PLUS_AUTHEN_SVC_ENABLE &&
!(char) data->NAS_id->username[0]) {
(char)data->NAS_id->username[0] == '\0') {
switch (p->state) {
case STATE_AUTHEN_GETUSER:
@ -166,7 +166,7 @@ skey_fn(struct authen_data *data)
if (skeychallenge(&p->skey, name, skeyprompt, 80) == 0) {
char buf[256];
sprintf(buf, "%s\nS/Key challenge: ", skeyprompt);
snprintf(buf, sizeof(buf), "%s\nS/Key challenge: ", skeyprompt);
data->server_msg = tac_strdup(buf);
data->status = TAC_PLUS_AUTHEN_STATUS_GETPASS;
p->state = STATE_AUTHEN_GETPASS;

View File

@ -1,6 +1,6 @@
.\"
.hys 50
.TH tac_plus 8 "27 July 2009"
.TH tac_plus 8 "29 December 2014"
.\"
.SH NAME
tac_plus \- tacacs plus daemon
@ -20,9 +20,18 @@ tac_plus \- tacacs plus daemon
.BI \-l
<logfile>]
[\c
.BI \-m
<max_listen_queue>]
[\c
.BI \-p
<tcp_port>]
[\c
.BI \-Q
<setgid>]
[\c
.BI \-U
<setuid>]
[\c
.BI \-u
<wtmpfile>]
[\c
@ -80,6 +89,8 @@ option.
.sp
.nf
Value Meaning
2 configuration parsing debugging
4 fork(1) debugging
8 authorization debugging
16 authentication debugging
32 password file processing debugging
@ -89,6 +100,8 @@ Value Meaning
512 encryption/decryption
1024 MD5 hash algorithm debugging
2048 very low level encryption/decryption
32768 max session debugging
65536 lock debugging
.fi
.\"
.TP
@ -131,6 +144,11 @@ option is used.
The logs are still posted to syslog.
.\"
.TP
.B -m <max_listen_queue>
Specify an alternative client listen queue limit.
The default is SOMAXCONN or 64, if your O/S does not specify one.
.\"
.TP
.B -L
Lookup DNS PTR (Domain Name System PoinTeR) record of client addresses.
The resulting FQDN (Fully Qualified Domain Name), if it resolves, will be
@ -155,6 +173,14 @@ for incoming tcp connections. Note: this changes the name of the
pid file created by the daemon.
.\"
.TP
.B \-Q <setgid groupname>
Specify the groupname or GID to
.IR setgid(2).
If the daemon was compiled with a specific GID, this option overrides that
value.
By default, the daemon inherits the GID from its parent process.
.\"
.TP
.B \-S
Enables or allows client single-connection mode, where-by the client will
create one connection and interleave queries.
@ -180,6 +206,14 @@ Log all informational, debugging or error messages to
/dev/console
in addition to logging to syslogd. Useful for debugging.
.\"
.TP \-U <setuid username>
Specify the username or UID to
.IR setuid(2).
If the daemon was compiled with a specific UID, this option overrides that
value.
The daemon must be started by root to open the privileged port.
By default, it does not change it's UID and therefore remains root.
.\"
.TP
.B \-u <wtmpfile>
Write wtmp entries to the specified wtmp file.
@ -235,8 +269,14 @@ root, as it contains passwords and keys.
If the daemon is receives a SIGHUP or SIGUSR1, it will reinitialize itself
and re-read its configuration file.
.sp
Note: if an error is encountered in the configuration file, the daemon
will die.
Note: if an error is encountered in the configuration file or the file can
not be opened for reading, such as due to insufficient permissions resulting
from process ownership and file permissions, the daemon will exit.
.sp
Likewise, if the daemon is configured to send accounting records to a file
and that file can not be opened for writing, such as due to insufficient
permissions resulting from process ownership and file permissions, the daemon
will exit.
.\"
.SH "LOG MESSAGES"
.B tac_plus

View File

@ -20,15 +20,14 @@
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
* Facebook Fork 2014 Cooper Lees <cooper@fb.com>
*/
#include "pathsl.h"
#include "version.h"
#include "tac_plus.h"
#include <grp.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <pwd.h>
#include <sys/wait.h>
#include <signal.h>
@ -44,7 +43,7 @@ static int initialised; /* data structures have been allocated */
volatile sig_atomic_t reinitialize; /* schedule config reinitialization */
int sendauth_only; /* don't respond to sendpass requests */
int debug; /* debugging flags */
int facility = LOG_LOCAL3; /* syslog facility */
int facility = LOG_DAEMON; /* syslog facility */
int port = TAC_PLUS_PORT; /* port we're listening on */
char *portstr = TAC_PLUS_PORTSTR;
int console; /* write all syslog messages to console */
@ -59,11 +58,14 @@ int single; /* single thread (for debugging) */
int opt_G; /* foreground */
int opt_S; /* enable single-connection */
int wtmpfd; /* for wtmp file logging */
int total_child_count = 0; /* count of child procs */
char *opt_Q;
char *opt_U;
int total_child_count = 0;
volatile sig_atomic_t dump_client_table = 0;
volatile sig_atomic_t reap_children = 0;
char *wtmpfile = NULL;
char *bind_address = NULL;
struct timeval started_at;
struct session session; /* session data */
@ -126,7 +128,7 @@ handler(int signum)
{
/* report() is not reentrant-safe */
#define RCVSIG_STR "Received signal\n"
write(fileno(stderr), RCVSIG_STR, strlen(RCVSIG_STR));
(void)write(fileno(stderr), RCVSIG_STR, strlen(RCVSIG_STR));
reinitialize = 1;
#ifdef REARMSIGNAL
signal(SIGUSR1, handler);
@ -143,15 +145,14 @@ dump_clients_handler(int signum)
#endif
}
#if defined(REAPCHILD) && defined(REAPSIGIGN)
RETSIGTYPE
reapchild(int notused)
{
reap_children = 1;
}
#endif
void
reapchildren()
{
@ -171,10 +172,9 @@ reapchildren()
pid = waitpid(-1, &status, WNOHANG);
if (pid <= 1)
return;
snprintf(msgbuf, MSGBUFSZ, "Cleaning up session for pid %lu", pid);
snprintf(msgbuf, MSGBUFSZ, "Clening up session for pid %lu", pid);
report(LOG_DEBUG, msgbuf);
procs_for_client = decrement_client_count_for_proc(pid);
/* decrement the global child counter */
total_child_count--;
}
reap_children = 0;
@ -189,7 +189,6 @@ get_socket(int **sa, int *nsa)
{
char host[NI_MAXHOST], serv[NI_MAXHOST];
struct addrinfo hint, *res, *rp;
u_long inaddr;
int ecode,
flag,
kalive = 1,
@ -222,8 +221,10 @@ get_socket(int **sa, int *nsa)
if (1 || debug & DEBUG_PACKET_FLAG)
report(LOG_DEBUG, "socket FD %d AF %d", s, rp->ai_family);
flag = 1;
#ifdef IPV6_V6ONLY
if (rp->ai_family == AF_INET6)
setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag));
#endif
#ifdef SO_REUSEADDR
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag,
sizeof(flag)) < 0)
@ -275,6 +276,7 @@ get_socket(int **sa, int *nsa)
report(LOG_ERR, "get_socket: could not bind a listening socket");
tac_exit(1);
}
return(0);
}
@ -294,9 +296,14 @@ main(int argc, char **argv)
{
extern char *optarg;
FILE *fp;
int c, *s, ns;
int c, *s, ns, somaxconn;
struct pollfd *pfds;
#ifndef SOMAXCONN
# define SOMAXCONN 64
#endif
somaxconn = SOMAXCONN;
#if PROFILE
moncontrol(0);
#endif
@ -310,13 +317,17 @@ main(int argc, char **argv)
memset(&session, 0, sizeof(session));
session.peer = tac_strdup("unknown");
#if defined(REAPCHILD) && defined(REAPSIGIGN)
client_count_init();
#endif
open_logfile();
if (argc <= 1) {
usage();
tac_exit(1);
}
while ((c = getopt(argc, argv, "B:C:d:hiPp:tGgvSsLw:u:")) != EOF)
while ((c = getopt(argc, argv, "B:C:d:hiPp:Q:tGgvSsLl:m:w:U:u:")) != EOF)
switch (c) {
case 'B': /* bind() address*/
bind_address = optarg;
@ -358,6 +369,15 @@ main(int argc, char **argv)
case 'i': /* inetd mode */
standalone = 0;
break;
case 'l': /* logfile */
logfile = tac_strdup(optarg);
break;
case 'm': /* SOMAXCONN */
somaxconn = atoi(optarg);
break;
case 'Q': /* setgid */
opt_Q = tac_strdup(optarg);
break;
case 'S': /* enable single-connection */
opt_S = 1;
break;
@ -366,6 +386,9 @@ main(int argc, char **argv)
wholog = tac_strdup(optarg);
break;
#endif
case 'U': /* setuid */
opt_U = tac_strdup(optarg);
break;
case 'u':
wtmpfile = tac_strdup(optarg);
break;
@ -380,10 +403,6 @@ main(int argc, char **argv)
/* read the configuration/etc */
init();
#if defined(REAPCHILD) && defined(REAPSIGIGN)
client_count_init();
#endif
open_logfile();
signal(SIGUSR1, handler);
signal(SIGHUP, handler);
@ -401,11 +420,7 @@ main(int argc, char **argv)
/* running under inetd */
char host[NI_MAXHOST];
int on;
#ifdef IPV6
struct sockaddr_in6 name;
#else
struct sockaddr_in name;
#endif
socklen_t name_len;
name_len = sizeof(name);
@ -419,22 +434,20 @@ main(int argc, char **argv)
on = 0;
else
on = NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&name, name_len, host, 128,
NULL, 0, on)) {
if (getnameinfo((struct sockaddr *)&name, name_len, host,
NI_MAXHOST, NULL, 0, on)) {
strncpy(host, "unknown", NI_MAXHOST - 1);
host[NI_MAXHOST - 1] = '\0';
}
if (session.peer) free(session.peer);
if (session.peer) {
free(session.peer);
}
session.peer = tac_strdup(host);
if (session.peerip) free(session.peerip);
#ifdef IPV6
session.peerip = tac_strdup((char *)inet_ntop(name.sin6_family,
&name.sin6_addr, host, name_len));
#else
if (session.peerip)
free(session.peerip);
session.peerip = tac_strdup((char *)inet_ntop(name.sin_family,
&name.sin_addr, host, name_len));
#endif
&name.sin_addr, host, NI_MAXHOST));
if (debug & DEBUG_AUTHEN_FLAG)
report(LOG_INFO, "session.peerip is %s", session.peerip);
}
@ -532,12 +545,8 @@ main(int argc, char **argv)
get_socket(&s, &ns);
#ifndef SOMAXCONN
#define SOMAXCONN 5
#endif
for (c = 0; c < ns; c++) {
if (listen(s[c], SOMAXCONN) < 0) {
if (listen(s[c], somaxconn) < 0) {
console = 1;
report(LOG_ERR, "listen: %s", strerror(errno));
tac_exit(1);
@ -581,14 +590,35 @@ main(int argc, char **argv)
childpid = 0;
}
}
if (opt_Q) {
struct group *gr;
if ((gr = getgrnam(opt_Q)) == NULL) {
report(LOG_ERR, "Could set groupid to %s: %s", opt_Q,
strerror(errno));
} else if (setgid(gr->gr_gid)) {
report(LOG_ERR, "Cannot set group id to %d %s",
gr->gr_gid, strerror(errno));
}
}
#ifdef TACPLUS_GROUPID
if (setgid(TACPLUS_GROUPID))
else if (setgid(TACPLUS_GROUPID))
report(LOG_ERR, "Cannot set group id to %d %s",
TACPLUS_GROUPID, strerror(errno));
#endif
if (opt_U) {
struct passwd *pw;
if ((pw = getpwnam(opt_U)) == NULL) {
report(LOG_ERR, "Could not find username %s: %s", opt_U,
strerror(errno));
} else if (setuid(pw->pw_uid)) {
report(LOG_ERR, "Cannot set user id to %d %s",
pw->pw_uid, strerror(errno));
}
}
#ifdef TACPLUS_USERID
if (setuid(TACPLUS_USERID))
else if (setuid(TACPLUS_USERID))
report(LOG_ERR, "Cannot set user id to %d %s",
TACPLUS_USERID, strerror(errno));
#endif
@ -617,14 +647,10 @@ main(int argc, char **argv)
int pid;
#endif
char host[NI_MAXHOST];
#ifdef IPV6
struct sockaddr_in6 from;
#else
struct sockaddr_in from;
#endif
socklen_t from_len;
int newsockfd, status;
int flags;
int newsockfd = -1;
int flags, status;
int procs_for_client;
#if defined(REAPCHILD) && defined(REAPSIGIGN)
@ -641,15 +667,15 @@ main(int argc, char **argv)
dump_client_table = 0;
}
status = poll(pfds, ns, cfg_get_accepttimeout() * 1000);
status = poll(pfds, ns, TAC_PLUS_ACCEPT_TIMEOUT * 1000);
if (status == 0)
continue;
if (status == -1)
if (errno == EINTR)
continue;
memset((char *)&from, 0, sizeof(from));
from_len = sizeof(from);
memset((char *)&from, 0, from_len);
for (c = 0; c < ns; c++) {
if (pfds[c].revents & POLLIN)
newsockfd = accept(s[c], (struct sockaddr *)&from, &from_len);
@ -671,24 +697,21 @@ main(int argc, char **argv)
flags = 0;
else
flags = NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&from, from_len, host, 128, NULL, 0,
flags)) {
if (getnameinfo((struct sockaddr *)&from, from_len, host, NI_MAXHOST,
NULL, 0, flags)) {
strncpy(host, "unknown", NI_MAXHOST - 1);
host[NI_MAXHOST - 1] = '\0';
}
if (session.peer) free(session.peer);
if (session.peer) {
free(session.peer);
}
session.peer = tac_strdup(host);
if (session.peerip) free(session.peerip);
memset(host, 0, NI_MAXHOST);
#ifdef IPV6
session.peerip = tac_strdup((char *)inet_ntop(from.sin6_family,
&from.sin6_addr, host, INET6_ADDRSTRLEN));
#else
if (session.peerip)
free(session.peerip);
session.peerip = tac_strdup((char *)inet_ntop(from.sin_family,
&from.sin_addr, host, INET_ADDRSTRLEN));
#endif
&from.sin_addr, host, NI_MAXHOST));
if (debug & DEBUG_PACKET_FLAG)
report(LOG_DEBUG, "session request from %s sock=%d",
session.peer, newsockfd);
@ -703,18 +726,9 @@ main(int argc, char **argv)
close(newsockfd);
continue;
}
/* we did not get a peer IP for some reason */
if (! session.peerip) {
report(LOG_ALERT, "Refused connection from %s [%s], no peer IP?",
session.peer, session.peerip);
shutdown(newsockfd, 2);
close(newsockfd);
continue;
}
/* now we check the process count per client */
/* no we check the process count per client */
procs_for_client = get_client_count(session.peerip);
report(LOG_ALERT, "connection [%d] from %s [%s]", procs_for_client + 1,
session.peer, session.peerip);
report(LOG_ALERT, "connection [%d] from %s [%s]", procs_for_client + 1, session.peer, session.peerip);
if (procs_for_client >= cfg_get_maxprocsperclt()) {
report(LOG_ALERT, "refused connection from %s [%s] at client max procs [%d]",
session.peer, session.peerip, procs_for_client);
@ -723,7 +737,9 @@ main(int argc, char **argv)
continue;
}
#endif
pid = fork();
if (pid < 0) {
report(LOG_ERR, "fork error");
tac_exit(1);
@ -731,15 +747,12 @@ main(int argc, char **argv)
} else {
pid = 0;
}
if (pid == 0) {
/* child */
if (!single) {
if (ns > 1) {
for (c = 0; c < ns; c++) {
if (!single)
for (c = 0; c < ns; c++)
close(s[c]);
}
}
}
session.sock = newsockfd;
#ifdef LIBWRAP
if (! hosts_ctl(progname,session.peer,session.peerip,progname)) {
@ -754,8 +767,8 @@ main(int argc, char **argv)
continue;
}
}
if (debug)
report(LOG_DEBUG, "connect from %s [%s]", session.peer, session.peerip);
report(LOG_INFO, "connect from %s [%s]", session.peer,
session.peerip);
#endif
#if PROFILE
moncontrol(1);
@ -767,6 +780,8 @@ main(int argc, char **argv)
if (!single)
tac_exit(0);
} else {
if (debug & DEBUG_FORK_FLAG)
report(LOG_DEBUG, "forked %ld", (long)pid);
/* parent */
#if defined(REAPCHILD) && defined(REAPSIGIGN)
total_child_count++;
@ -884,7 +899,10 @@ usage(void)
fprintf(stderr, "Usage: tac_plus -C <config_file> [-GghiLPstv]"
" [-B <bind address>]"
" [-d <debug level>]"
" [-l <logfile>]"
" [-p <port>]"
" [-Q <setgid groupname>]"
" [-U <setuid username>]"
" [-u <wtmpfile>]"
#ifdef MAXSESS
" [-w <whologfile>]"

View File

@ -1,6 +1,6 @@
.\"
.hys 50
.TH tac_plus.conf 5 "2 March 2009"
.TH tac_plus.conf 5 "1 August 2013"
.\"
.SH NAME
.\"
@ -92,34 +92,19 @@ interface. For example:
.\"
.TP
.B default authentication
By default, authorization fails for users that do not appear in the
By default, authentication fails for users that do not appear in the
configuration file. This overrides that behavior, thus permitting
all authorization requests for such users.
all authentication requests for such users.
.sp
.nf
default authentication = file <filename>
.fi
.sp
Such users will be authorized via the <user> "DEFAULT".
Such users will be authentication via the <user> "DEFAULT".
.sp
Also see "user = DEFAULT", <default service>, and <default attribute>.
.\"
.TP
.B default authorization
Analogous to the use of <user> "DEFAULT" for default authentication.
Provided for backward compatibility.
.sp
.nf
default authorization = <permission>
.fi
OR
.nf
user = NAME {
default authorization = permit
}
.fi
.\"
.TP
.B group
Analogous to a <user> and accepting the same syntax, a group provides
a template of which a <user> or another group can be a member.
@ -136,7 +121,7 @@ group (which may be a member of yet another group, and so on).
.TP
.B host
The host clause allows the configuration values noted below to be set
for the client name by IP address. If
for the client named by IP address. If
.B tac_plus
is started with the
.B \-L
@ -227,15 +212,24 @@ the AV pair is optional.
[ optional ] <string> = <string>
.fi
.sp
Optional AV pairs are only sent to the client if it requests them. That is,
the client must have included the given AV pair as a mandatory or optional
pair in the request.
.sp
Some clients react incorrectly and negatively to receiving AV pairs that it
did not solicit. Optional AV pairs should be ignored if they are not
recognized or not supported in any given context.
.sp
Also see the "Configuring Authorization" and "AV Pairs" sections below.
.\"
.TP
.B cmd_auth
Specify command authorization.
.sp
For command authorization, the Cisco expands all commands to their
full names. For example, when the command "config t" is entered it
will be expanded to "configuration terminal".
For command authorization, the device should expand all abbreviated commands
to their full names and compress adjacent white-space.
For example, when the command "config t" is entered it will be expanded
to "configure terminal".
.sp
.nf
cmd = <string> {
@ -250,7 +244,9 @@ Specify a command argument match.
.sp
.nf
<permission> <regex>
<permission> XXX: need .* ?
<permission> <regex>
...
<permission>
.fi
.sp
The <regex> matches arguments of the command <string>. For example,
@ -263,6 +259,11 @@ to allow show diag but no other show commands:
}
.fi
.sp
The end of the <cmd-match> has an implicit <permission> determined by
<default service>.
So, if the 'deny' had been omitted in the example above, the result of
the authorization would be the value of <default service>.
.sp
Note: 'cmd-arg' should never appear in a configuration file.
It is used internally by the daemon to construct a string
which is then matched against the regular expressions which appear
@ -282,6 +283,8 @@ Specifies the default <permission> for service authorization.
default service = <permission>
.fi
.sp
If omitted, the default is 'deny'.
.sp
Note: if used, <default service> must precede all other <svc> directives
in a <user> clause.
.\"
@ -301,6 +304,16 @@ directives in a <svc> clause.
Represents the one-way encryption of a password <string>. For example,
a password might encrypt to the string 0AmUKnIT2gheo.
.sp
DES is the encryption historically used in Unix passwd(5) files. The
crypt() function of the system's libcrypt is used to perform the
encryption. The libcrypt of modern Unicies tend to support additional
encryption algorithms and thus so would
.B tac_plus.
See the system's crypt manual page. To utilize another format, use the
des keyword followed by the crypt in the format as described in the
manpage. Typically it will have a "$1" prefix for MD5, "$2" for blowfish,
and so on.
.sp
.BR tac_pwd (8)
is a utility supplied with
.B tac_plus
@ -379,7 +392,7 @@ with skey (--enable-skey) support.
PAM (Pluggable Authentication Modules framework) is an authentication
mechanism (and much more) capable of various types of authentication
methods that are chosen by a configuration file.
The PAM service name is "tac_plus".
The PAM service name is the name of tac_plus executable, normally "tac_plus".
PAM can be used only for login authentication, it is not implemented for
enable authorization, and does not support OTP-like challenge system (ie:
no additional prompting).
@ -424,8 +437,9 @@ those exceptions, enclose the string in double quotes ("this has whitespace").
.TP
.B svc_auth
XXX:
service = ( exec | arap | slip | ppp | shell | tty-daemon |
connection | system ) protocol = <proto> {
service = ( arap | connection | exec | ppp protocol = <proto> |
shell | slip | system | tty-daemon | <client defined> )
{
[ <default attribute> ]
<attr_value_pair>*
}
@ -452,6 +466,9 @@ news, syslog, user, and uucp.
enable = <password_spec>
pap = cleartext "inbound pap password"
opap = cleartext "outbound pap password"
pap = des <des_string>
pap = file <filename>
pap = PAM
login = <password_spec>
global = cleartext "outbound pap password"
}
@ -503,6 +520,10 @@ chap
#endif
pap = cleartext <string> |
pap = des <string> |
pap = file <filename> |
#ifdef PAM
pap = PAM |
#endif
opap = cleartext <string> |
global = cleartext <string> |
msg = <string>

Some files were not shown because too many files have changed in this diff Show More