mirror of https://github.com/facebook/tac_plus
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:
parent
ff94901988
commit
6aa67cba1c
|
|
@ -1,5 +1,5 @@
|
|||
Project: tacacs+
|
||||
Version: 4.0.19-fb
|
||||
Version: 4.0.28-fb
|
||||
Release date: 20140530
|
||||
Website:
|
||||
License: Cisco
|
||||
|
|
|
|||
24
README.md
24
README.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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()
|
||||
|
|
@ -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
|
|
@ -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:
|
||||
|
|
@ -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
|
|
@ -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 *);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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];
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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:
|
||||
|
|
@ -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_
|
||||
|
|
@ -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*)
|
||||
|
|
@ -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"
|
||||
;;
|
||||
|
|
@ -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:
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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])])
|
||||
|
|
@ -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
|
||||
])
|
||||
|
|
@ -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)
|
||||
])
|
||||
|
|
@ -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])])
|
||||
|
|
@ -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:
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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",
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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);
|
||||
|
|
@ -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()
|
||||
|
|
@ -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:;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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++) {
|
||||
|
|
@ -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. */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -50,4 +50,3 @@ int main (int argc, char **argv) {
|
|||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
|
@ -55,6 +55,8 @@
|
|||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define MD5_SIZE 16
|
||||
|
||||
/* typedef a generic pointer type */
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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");
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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>]"
|
||||
|
|
@ -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
Loading…
Reference in New Issue