-/*
+/*
Copyright (c) 1995-1998 by Cisco systems, Inc.
Permission to use, copy, modify, and distribute this software for
FITNESS FOR A PARTICULAR PURPOSE.
*/
+
#include "tac_plus.h"
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <string.h>
+#include <utmp.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "do_acct.h"
+#include "report.h"
+#include "utils.h"
+#include "main.h"
+#include "do_author.h" /* for "struct identity" */
+
+
+char *wtmpfile = NULL; /* for wtmp file logging */
+
+
+static int wtmpfd = 0;
static int acctfd = 0;
-/* Make a acct entry into the accounting file for accounting.
+/* Make a acct entry into the accounting file for accounting.
Return 1 on error */
+static int acct_write TAC_ARGS((char *string));
+
static int
acct_write(string)
- char *string;
+char *string;
{
- if (write(acctfd, string, strlen(string)) != strlen(string)) {
+ if ((unsigned long)write(acctfd, string, strlen(string)) != strlen(string)) {
report(LOG_ERR, "%s: couldn't write acct file %s %s",
session.peer,
session.acctfile, sys_errlist[errno]);
return(1);
}
-
+
if (debug & DEBUG_ACCT_FLAG)
report(LOG_DEBUG, "'%s'", string);
return(0);
}
+static int acct_write_field TAC_ARGS((char *string));
+
/* Write a string or "unknown" into the accounting file.
Return 1 on error */
static int
acct_write_field(string)
- char *string;
+char *string;
{
if (string && string[0]) {
if (acct_write(string))
return(0);
}
+int do_acct TAC_ARGS((struct acct_rec *rec));
+
int
do_acct(rec)
struct acct_rec *rec;
return(1);
}
}
-
+
if (!tac_lockfd(session.acctfile, acctfd)) {
rec->admin_msg = tac_strdup("Cannot lock log file");
- report(LOG_ERR, "%s: Cannot lock %s",
+ report(LOG_ERR, "%s: Cannot lock %s",
session.peer, session.acctfile);
return(1);
}
for (i=0; i < rec->num_args; i++) {
errors += acct_write(rec->args[i]);
- if (i < (rec->num_args-1))
+ if (i < (rec->num_args-1))
errors += acct_write("\t");
}
errors += acct_write("\n");
return (0);
}
-int
+static int wtmp_entry TAC_ARGS((char *line, char *name, char *host, time_t utime));
+
+static int
wtmp_entry (line, name, host, utime)
- char *line, *name, *host;
- time_t utime;
+char *line, *name, *host;
+time_t utime;
{
struct utmp entry;
strcpy(entry.ut_name, name);
else bcopy(name, entry.ut_name, sizeof entry.ut_name);
-#ifndef SOLARIS
+#ifdef HAVE_UTMP_UT_HOST
if (strlen(host) < sizeof entry.ut_host)
strcpy(entry.ut_host, host);
else bcopy(host, entry.ut_host, sizeof entry.ut_host);
#endif
entry.ut_time = utime;
- wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_SYNC, 0644);
+ wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_SYNC, 0644);
if (wtmpfd < 0) {
report(LOG_ERR, "Can't open wtmp file %s -- %s",
wtmpfile, sys_errlist[errno]);
report(LOG_ERR, "%s: couldn't write wtmp file %s %s",
session.peer, wtmpfile, sys_errlist[errno]);
return(1);
- }
+ }
close(wtmpfd);
if (debug & DEBUG_ACCT_FLAG) {
- report(LOG_DEBUG, "wtmp: %s, %s %s %d", line, name, host, utime);
+ report(LOG_DEBUG, "wtmp: %s, %s %s %ld", line, name, host, (long)utime);
}
-
+
return(0);
}
+char *find_attr_value TAC_ARGS((char *attr, char **args, int cnt));
+
char *
find_attr_value (attr, args, cnt)
- char *attr, **args;
- int cnt;
+char *attr, **args;
+int cnt;
{
int i;
return(NULL);
}
+int do_wtmp TAC_ARGS((struct acct_rec *rec));
+
int
do_wtmp(rec)
- struct acct_rec *rec;
+struct acct_rec *rec;
{
time_t now = time(NULL);
char *service;
char *elapsed_time, *start_time;
time_t start_utime = 0, stop_utime = 0, elapsed_utime = 0;
-
+
switch(rec->acct_type) {
case ACCT_TYPE_START:
}
return(0);
}
-
+
if (rec->acct_type != ACCT_TYPE_STOP) {
return(0);
}
- /*
+ /*
* Since xtacacs logged start records containing the peer address
* for a connection, we have to generate them from T+ stop records.
* Might as well do this for exec records too.
*/
-
+
elapsed_time = find_attr_value("elapsed_time", rec->args, rec->num_args);
if (elapsed_time) {
start_time = find_attr_value("start_time", rec->args, rec->num_args);
- /*
+ /*
* Use the start_time if there is one. If not (e.g. the NAS may
* not know the time), assume the stop time is now, and calculate
* the rest
} else {
start_utime = now - elapsed_utime;
stop_utime = now;
- }
+ }
if (STREQ(service, "slip") || STREQ(service, "ppp")) {
char *dest_addr = find_attr_value("addr", rec->args, rec->num_args);