Skip to content

Commit

Permalink
IPv6 Support for tac_plus
Browse files Browse the repository at this point in the history
Summary:
- Add data structure support for IPv6 addresses - Stop seg faulting
- Add dirty hacks to allow for different acct, log and pid files so we
  can run a v4 and v6 binary
- New spec and init file for v6

Reviewers: dgadling

Test Plan:
- Run on dev server and test
- Run on a prod box

Task ID: 4378696
  • Loading branch information
cooperlees committed May 27, 2014
1 parent 2001451 commit cdfe0f8
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 170 deletions.
29 changes: 15 additions & 14 deletions tacacs+-F4.0.4.19/do_acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/

#include "tac_plus.h"
#include "pathsl.h"
#include <time.h>
#if defined(__DragonFly__) && !defined(O_SYNC)
#define O_SYNC O_FSYNC
Expand All @@ -37,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,
session.acctfile, strerror(errno));
TACPLUS_ACCTFILE, strerror(errno));
return(1);
}

Expand Down Expand Up @@ -74,17 +75,17 @@ do_acct_file(struct acct_rec *rec)
ct[24] = '\0';

if (!acctfd) {
acctfd = open(session.acctfile, O_CREAT | O_WRONLY | O_APPEND, 0644);
acctfd = open(TACPLUS_ACCTFILE, O_CREAT | O_WRONLY | O_APPEND, 0644);
if (acctfd < 0) {
report(LOG_ERR, "Can't open acct file %s -- %s",
session.acctfile, strerror(errno));
TACPLUS_ACCTFILE, strerror(errno));
return(1);
}
}
if (!tac_lockfd(session.acctfile, acctfd)) {
if (!tac_lockfd(TACPLUS_ACCTFILE, acctfd)) {
rec->admin_msg = tac_strdup("Cannot lock log file");
report(LOG_ERR, "%s: Cannot lock %s",
session.peer, session.acctfile);
session.peer, TACPLUS_ACCTFILE);
return(1);
}

Expand Down Expand Up @@ -155,16 +156,16 @@ do_acct_syslog(struct acct_rec *rec)

switch(rec->acct_type) {
case ACCT_TYPE_UPDATE:
acct_type = "update";
acct_type = "update";
break;
case ACCT_TYPE_START:
acct_type = "start";
acct_type = "start";
break;
case ACCT_TYPE_STOP:
acct_type = "stop";
acct_type = "stop";
break;
default:
acct_type = "default";
acct_type = "default";
}

for (i = 0; i < rec->num_args; i++) {
Expand All @@ -183,14 +184,14 @@ do_acct_syslog(struct acct_rec *rec)
}
}

syslog(LOG_INFO, "%s %s %s %s %s %s",
((rec->identity->NAS_name) && rec->identity->NAS_name[0]) ?
syslog(LOG_INFO, "%s %s %s %s %s %s",
((rec->identity->NAS_name) && rec->identity->NAS_name[0]) ?
rec->identity->NAS_name : "unknown",
((rec->identity->username) && rec->identity->username[0]) ?
((rec->identity->username) && rec->identity->username[0]) ?
rec->identity->username : "unknown",
((rec->identity->NAS_port) && rec->identity->NAS_port[0]) ?
((rec->identity->NAS_port) && rec->identity->NAS_port[0]) ?
rec->identity->NAS_port : "unknown",
((rec->identity->NAC_address) && rec->identity->NAC_address[0]) ?
((rec->identity->NAC_address) && rec->identity->NAC_address[0]) ?
rec->identity->NAC_address : "unknown",
acct_type, cmdbuf);

Expand Down
5 changes: 0 additions & 5 deletions tacacs+-F4.0.4.19/pathsl.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#ifndef PATHSL_H
#define PATHSL_H

/* daemon pid file location */
#define TACPLUS_PIDFILE "/var/run/tac_plus.pid"

Expand All @@ -12,5 +9,3 @@

/* This is a shared file used to maintain a record of who is logged in */
#define TACPLUS_WHOLOGFILE "/var/log/tacwho.log"

#endif
7 changes: 3 additions & 4 deletions tacacs+-F4.0.4.19/report.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/

#include "tac_plus.h"
#include "pathsl.h"
#include <stdio.h>

#ifdef AIX
Expand All @@ -36,8 +37,6 @@

FILE *ostream = NULL;

char *logfile = TACPLUS_LOGFILE;

/* report:
*
* This routine reports errors and such via stderr and syslog() if
Expand Down Expand Up @@ -160,14 +159,14 @@ report(priority, fmt, va_alist)
if (debug) {
int logfd;

logfd = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0644);
logfd = open(TACPLUS_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(logfile, logfd);
tac_lockfd(TACPLUS_LOGFILE, logfd);
sprintf(buf, "%s [%ld]: ", ct, (long)getpid());
write(logfd, buf, strlen(buf));
if (priority == LOG_ERR)
Expand Down
85 changes: 39 additions & 46 deletions tacacs+-F4.0.4.19/tac_plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
* 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 <[email protected]>
*/

#include "pathsl.h"
#include "version.h"
#include "tac_plus.h"
#include <netinet/tcp.h>
Expand Down Expand Up @@ -195,10 +198,8 @@ 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)
Expand Down Expand Up @@ -250,7 +251,6 @@ get_socket(int **sa, int *nsa)
report(LOG_ERR, "get_socket: could not bind a listening socket");
tac_exit(1);
}

return(0);
}

Expand Down Expand Up @@ -286,14 +286,13 @@ main(int argc, char **argv)
memset(&session, 0, sizeof(session));
session.peer = tac_strdup("unknown");

open_logfile();

if (argc <= 1) {
usage();
tac_exit(1);
}

while ((c = getopt(argc, argv, "B:C:d:hiPp:tGgvSsLl:w:u:")) != EOF)
while ((c = getopt(argc, argv, "B:C:d:hiPp:tGgvSsLw:u:")) != EOF)
switch (c) {
case 'B': /* bind() address*/
bind_address = optarg;
Expand Down Expand Up @@ -335,9 +334,6 @@ main(int argc, char **argv)
case 'i': /* inetd mode */
standalone = 0;
break;
case 'l': /* logfile */
logfile = tac_strdup(optarg);
break;
case 'S': /* enable single-connection */
opt_S = 1;
break;
Expand All @@ -361,6 +357,8 @@ main(int argc, char **argv)
/* read the configuration/etc */
init();

open_logfile();

signal(SIGUSR1, handler);
signal(SIGHUP, handler);
signal(SIGTERM, die);
Expand All @@ -376,7 +374,7 @@ main(int argc, char **argv)
/* running under inetd */
char host[NI_MAXHOST];
int on;
struct sockaddr_in name;
struct sockaddr_in6 name;
socklen_t name_len;

name_len = sizeof(name);
Expand All @@ -390,20 +388,17 @@ main(int argc, char **argv)
on = 0;
else
on = NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&name, name_len, host, 128,
if (getnameinfo((struct sockaddr6 *)&name, name_len, host, 128,
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);
session.peerip = tac_strdup((char *)inet_ntop(name.sin_family,
&name.sin_addr, host, name_len));
if (session.peerip) free(session.peerip);
session.peerip = tac_strdup((char *)inet_ntop(name.sin6_family,
&name.sin6_addr, host, name_len));
if (debug & DEBUG_AUTHEN_FLAG)
report(LOG_INFO, "session.peerip is %s", session.peerip);
}
Expand All @@ -416,7 +411,7 @@ main(int argc, char **argv)
#endif
start_session();
tac_exit(0);
}
}

if (single) {
session.flags |= SESS_NO_SINGLECONN;
Expand Down Expand Up @@ -586,7 +581,7 @@ main(int argc, char **argv)
int pid;
#endif
char host[NI_MAXHOST];
struct sockaddr_in from;
struct sockaddr_in6 from;
socklen_t from_len;
int newsockfd, status;
int flags;
Expand All @@ -605,7 +600,7 @@ main(int argc, char **argv)
from_len = sizeof(from);
for (c = 0; c < ns; c++) {
if (pfds[c].revents & POLLIN)
newsockfd = accept(s[c], (struct sockaddr *)&from, &from_len);
newsockfd = accept(s[c], (struct sockaddr6 *)&from, &from_len);
else if (pfds[c].revents & (POLLERR | POLLHUP | POLLNVAL)) {
report(LOG_ERR, "exception on listen FD %d", s[c]);
tac_exit(1);
Expand All @@ -624,7 +619,7 @@ main(int argc, char **argv)
flags = 0;
else
flags = NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&from, from_len, host, 128, NULL, 0,
if (getnameinfo((struct sockaddr6 *)&from, from_len, host, 128, NULL, 0,
flags)) {
strncpy(host, "unknown", NI_MAXHOST - 1);
host[NI_MAXHOST - 1] = '\0';
Expand All @@ -637,53 +632,52 @@ main(int argc, char **argv)

if (session.peerip)
free(session.peerip);
session.peerip = tac_strdup((char *)inet_ntop(from.sin_family,
&from.sin_addr, host, from_len));

session.peerip = tac_strdup((char *)inet_ntop(from.sin6_family,
&from.sin6_addr, host, INET6_ADDRSTRLEN));
if (debug & DEBUG_PACKET_FLAG)
report(LOG_DEBUG, "session request from %s sock=%d",
session.peer, newsockfd);

if (!single) {
pid = fork();

if (pid < 0) {
report(LOG_ERR, "fork error");
tac_exit(1);
}
} else {
pid = 0;
}

if (pid == 0) {
/* child */
printf("--> In child ...\n"); // C
if (!single) {
for (c = 0; c < ns; c++)
close(s[c]);
}
session.sock = newsockfd;
if (ns > 1) {
for (c = 0; c < ns; c++) {
close(s[c]);
}
}
}
session.sock = newsockfd;
#ifdef LIBWRAP
if (! hosts_ctl(progname,session.peer,session.peerip,progname)) {
report(LOG_ALERT, "refused connection from %s [%s]",
if (! hosts_ctl(progname,session.peer,session.peerip,progname)) {
report(LOG_ALERT, "refused connection from %s [%s]",
session.peer, session.peerip);
shutdown(session.sock, 2);
close(session.sock);
if (!single) {
tac_exit(0);
} else {
close(session.sock);
continue;
}
}
if (debug)
report(LOG_DEBUG, "connect from %s [%s]", session.peer,
session.peerip);
shutdown(session.sock, 2);
close(session.sock);
if (!single) {
tac_exit(0);
} else {
close(session.sock);
continue;
}
}
if (debug)
report(LOG_DEBUG, "connect from %s [%s]", session.peer, session.peerip);
#endif
#if PROFILE
moncontrol(1);
#endif

printf("--> Start Session\n"); // C
start_session();
shutdown(session.sock, 2);
close(session.sock);
Expand Down Expand Up @@ -802,7 +796,6 @@ usage(void)
fprintf(stderr, "Usage: tac_plus -C <config_file> [-GghiLPstv]"
" [-B <bind address>]"
" [-d <debug level>]"
" [-l <logfile>]"
" [-p <port>]"
" [-u <wtmpfile>]"
#ifdef MAXSESS
Expand Down
5 changes: 4 additions & 1 deletion tacacs+-F4.0.4.19/tac_plus.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* 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 <[email protected]>
*/

#include "config.h"
Expand Down Expand Up @@ -172,6 +174,7 @@
*/

#define AUTHEN_NAME_SIZE 128
#define NI_MAXHOST 1025

struct authen_type {
char authen_name[AUTHEN_NAME_SIZE];
Expand Down Expand Up @@ -671,7 +674,7 @@ struct peruser {
char username[64]; /* User name */
char NAS_name[32]; /* NAS user logged into */
char NAS_port[32]; /* ...port on that NAS */
char NAC_address[32]; /* ...IP address of NAS */
char NAC_address[128]; /* ...IP address of NAS */
};
#endif /* MAXSESS */

Expand Down
Loading

0 comments on commit cdfe0f8

Please sign in to comment.