FITNESS FOR A PARTICULAR PURPOSE.
*/
+
#include "tac_plus.h"
#ifdef MAXSESS
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <netdb.h>
+
+#include "maxsess.h"
+#include "report.h"
+#include "utils.h"
+#include "cfgfile.h"
+#include "main.h"
+#include "do_acct.h"
+#include "parse.h"
+
+
+void maxsess_loginit TAC_ARGS((void));
+
+
+/* Configurable:
+ */
+
+/* This is a shared file used to maintain a record of who's on
+ */
+#define WHOLOG_DEFAULT "/var/log/tac_who.log"
+
+
+/*
+ * This is state kept per user/session
+ */
+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 *wholog = WHOLOG_DEFAULT;
/*
* initialize wholog file for tracking of user logins/logouts from
}
}
+static char *portname TAC_ARGS((char *oldport));
+
/*
* Given a port description, return it in a canonical format.
*
return (p);
}
+static void write_record TAC_ARGS((char *name, FILE *fp, void *buf, int size, long int offset));
+
/*
* Seek to offset and write a buffer into the file pointed to by fp
*/
char *name;
{
if (fseek(fp, offset, SEEK_SET) < 0) {
- report(LOG_ERR, "%s fd=%d Cannot seek to %d %s",
+ report(LOG_ERR, "%s fd=%d Cannot seek to %ld %s",
name, fileno(fp), offset, sys_errlist[errno]);
}
if (fwrite(buf, size, 1, fp) != 1) {
}
}
+static void process_stop_record TAC_ARGS((struct identity *idp));
+
static void
process_stop_record(idp)
struct identity *idp;
/* A match. Zero out this record */
bzero(&pu, sizeof(pu));
- write_record(wholog, fp, &pu, sizeof(pu),
+ write_record(wholog, fp, &pu, sizeof(pu),
recnum * sizeof(struct peruser));
if (debug & DEBUG_MAXSESS_FLAG) {
fclose(fp);
}
+static void process_start_record TAC_ARGS((struct identity *idp));
+
static void
process_start_record(idp)
struct identity *idp;
/* This is a START record, so write a new record or update the existing
* one. Note that we bzero(), so the strncpy()'s will truncate long
- * names and always leave a null-terminated string.
+ * names and always leave a null-terminated string.
*/
bzero(&pu, sizeof(pu));
}
+void loguser TAC_ARGS((struct acct_rec *rec));
+
/*
* Given a start or a stop accounting record, update the file of
* records which tracks who's logged on and where.
*/
+void
loguser(rec)
struct acct_rec *rec;
{
* Return -1 on error, eof or timeout. Otherwise return number of
* bytes read. */
-int
+static int timed_read TAC_ARGS((int fd, void *ptr, int nbytes, int timeout));
+
+static int
timed_read(fd, ptr, nbytes, timeout)
int fd;
-u_char *ptr;
+void *ptr;
int nbytes;
int timeout;
{
* with a maximum possible width of 10.
*/
+static int ckfinger TAC_ARGS((char *user, char *nas, struct identity *idp));
+
static int
ckfinger(user, nas, idp)
char *user, *nas;
/* Get IP addr for the NAS */
inaddr = inet_addr(nas);
- if (inaddr != -1) {
+ if (inaddr != (u_long)-1) {
/* A dotted decimal address */
bcopy(&inaddr, &sin.sin_addr, sizeof(inaddr));
sin.sin_family = AF_INET;
return (count);
}
+static int countusers_by_finger TAC_ARGS((struct identity *idp));
+
/*
* Verify how many sessions a user has according to the wholog file.
* Use finger to contact each NAS that wholog says has this user
return (nsess);
}
+static int countuser TAC_ARGS((struct identity *idp));
+
/*
* Estimate how many sessions a named user currently owns by looking in
* the wholog file.
return (nsess);
}
+static int is_async TAC_ARGS((char *portname));
+
/*
* is_async()
* Tell if the named NAS port is an async-like device.
return (0);
}
+int maxsess_check_count TAC_ARGS((char *user, struct author_data *data));
+
/*
* See if this user can have more sessions.
*/
/* No max session configured--don't check */
id = data->id;
- maxsess = cfg_get_intvalue(user, TAC_IS_USER, S_maxsess, TAC_PLUS_RECURSE);
+ maxsess = cfg_get_intvalue(S_user, 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",
return (0);
}
-#else /* MAXSESS */
-
-/*
- * The following code is not needed or used. It exists solely to
- * prevent compilers from "helpfully" complaining that this source
- * file is empty when MAXSESS is not defined. This upsets novices
- * building the software, and I get complaints
- */
+#else /* MAXSESS */
-static int dummy = 0;
+TAC_SOURCEFILE_EMPTY
-#endif /* MAXSESS */
+#endif /* MAXSESS */