From 7b0b6a0ce9b320a3145f9d600596946230d815f0 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 24 Jun 2009 17:46:27 -0400 Subject: [PATCH] Enhance audit logs to support SysV message queues Adds support for sysv message queues for fileserver audit logs. This also organizes the audit log code into various 'interfaces', of which there are two: the original 'file' interface, and the 'sysvmq' interface that this adds. The interface is configurable at runtime with the -audit-interface switch. FIXES 124674 Reviewed-on: http://gerrit.openafs.org/82 Tested-by: Andrew Deason Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear --- acinclude.m4 | 2 +- doc/man-pages/pod8/bosserver.pod | 10 ++ doc/man-pages/pod8/buserver.pod | 10 ++ doc/man-pages/pod8/fileserver.pod | 12 +++ doc/man-pages/pod8/kaserver.pod | 10 ++ doc/man-pages/pod8/ptserver.pod | 10 +- doc/man-pages/pod8/vlserver.pod | 10 ++ doc/man-pages/pod8/volserver.pod | 10 ++ src/audit/Makefile.in | 12 ++- src/audit/audit-api.h | 20 ++++ src/audit/audit-file.c | 89 +++++++++++++++++ src/audit/audit-sysvmq.c | 135 +++++++++++++++++++++++++ src/audit/audit.c | 160 ++++++++++++++++-------------- src/audit/audit.h | 5 +- src/bozo/bosserver.c | 16 ++- src/budb/server.c | 27 ++++- src/kauth/kaserver.c | 23 ++++- src/libafsauthent/Makefile.in | 8 +- src/ptserver/ptserver.c | 26 ++++- src/viced/viced.c | 15 ++- src/vlserver/vlserver.c | 18 +++- src/volser/volmain.c | 17 +++- 22 files changed, 535 insertions(+), 110 deletions(-) create mode 100644 src/audit/audit-api.h create mode 100644 src/audit/audit-file.c create mode 100644 src/audit/audit-sysvmq.c diff --git a/acinclude.m4 b/acinclude.m4 index 4eec8ac89..0ec466ffd 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1550,7 +1550,7 @@ AC_CHECK_HEADERS(stdlib.h string.h unistd.h poll.h fcntl.h sys/time.h sys/file.h AC_CHECK_HEADERS(netinet/in.h netdb.h sys/fcntl.h sys/mnttab.h sys/mntent.h) AC_CHECK_HEADERS(mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h) AC_CHECK_HEADERS(sys/mount.h strings.h termios.h signal.h poll.h sys/pag.h) -AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h sys/user.h) +AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h sys/user.h sys/ipc.h) AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h values.h sys/statvfs.h sys/statfs.h sys/bitypes.h) AC_CHECK_HEADERS(linux/errqueue.h,,,[#include ]) diff --git a/doc/man-pages/pod8/bosserver.pod b/doc/man-pages/pod8/bosserver.pod index 5a1402d6c..27dc055c6 100644 --- a/doc/man-pages/pod8/bosserver.pod +++ b/doc/man-pages/pod8/bosserver.pod @@ -8,6 +8,7 @@ bosserver - Initializes the BOS Server
B [B<-noauth>] [B<-log>] [B<-enable_peer_stats>] + S<<< [B<-auditlog> >] >>> [B<-audit-interface> (file | sysvmq)] [B<-enable_process_stats>] [B<-allow-dotted-principals>] [B<-help>] =for html @@ -92,6 +93,15 @@ Records in the F file the names of all users who successfully issue a privileged B command (one that requires being listed in the F file). +=item B<-auditlog> > + +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. + =item B<-enable_peer_stats> Activates the collection of Rx statistics and allocates memory for their diff --git a/doc/man-pages/pod8/buserver.pod b/doc/man-pages/pod8/buserver.pod index be8adce42..38af3e60b 100644 --- a/doc/man-pages/pod8/buserver.pod +++ b/doc/man-pages/pod8/buserver.pod @@ -8,6 +8,7 @@ buserver - Initializes the Backup Server
B S<<< [B<-database> >] >>> + S<<< [B<-auditlog> >] >>> [B<-audit-interface> (file | sysvmq)] S<<< [B<-cellservdb> >] >>> [B<-resetdb>] [B<-noauth>] [B<-smallht>] [B<-servers> >+] [B<-enable_peer_stats>] [B<-enable_process_stats>] [B<-rxbind>] @@ -59,6 +60,15 @@ Specifies the pathname of an alternate directory for the Backup Database files, ending in a final slash (C). If this argument is not provided, the default is the F directory. +=item B<-auditlog> > + +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. + =item B<-cellservdb> > Specifies the pathname of the directory from which the Backup Server reads diff --git a/doc/man-pages/pod8/fileserver.pod b/doc/man-pages/pod8/fileserver.pod index e52166965..9cf1a78b2 100644 --- a/doc/man-pages/pod8/fileserver.pod +++ b/doc/man-pages/pod8/fileserver.pod @@ -8,6 +8,7 @@ fileserver - Initializes the File Server component of the fs process
B S<<< [B<-auditlog> >] >>> + S<<< [B<-audit-interface> (file | sysvmq)] >>> S<<< [B<-d> >] >>> S<<< [B<-p> >] >>> S<<< [B<-spare> >] >>> @@ -257,6 +258,17 @@ length. Set and enable auditing. +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. The C interface writes audit +messages to the file passed to B<-auditlog>. The C interface +writes audit messages to a SYSV message (see L and +L). The message queue the C interface writes to has the +key C, where C is the path specified in the +B<-auditlog> option. + +Defaults to C. + =item B<-d> > Sets the detail level for the debugging trace written to the diff --git a/doc/man-pages/pod8/kaserver.pod b/doc/man-pages/pod8/kaserver.pod index 252e96140..48fc76619 100644 --- a/doc/man-pages/pod8/kaserver.pod +++ b/doc/man-pages/pod8/kaserver.pod @@ -8,6 +8,7 @@ kaserver - Initializes the Authentication Server
B [B<-noAuth>] [B<-fastKeys>] [B<-database> >] + S<<< [B<-auditlog> >] >>> [B<-audit-interface> (file | sysvmq)] S<<< [B<-localfiles> >] >>> S<<< [B<-minhours> >] >>> S<<< [B<-servers> >] >>> [B<-enable_peer_stats>] [B<-enable_process_stats>] [B<-help>] @@ -91,6 +92,15 @@ Provide the B<-localfiles> argument along with this one; otherwise, the B<-localfiles> argument is also set to the value of this argument, which is probably inappropriate. +=item B<-auditlog> > + +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. + =item B<-localfiles> > Specifies the pathname of an alternate directory in which the auxiliary diff --git a/doc/man-pages/pod8/ptserver.pod b/doc/man-pages/pod8/ptserver.pod index dcc2dcb30..43eb359da 100644 --- a/doc/man-pages/pod8/ptserver.pod +++ b/doc/man-pages/pod8/ptserver.pod @@ -13,6 +13,7 @@ B S<<< [B<-database> | B<-db> >] >>> S<<< [B<-p> ] [B<-enable_peer_stats>] [B<-enable_process_stats>] [B<-allow-dotted-principals>] [B<-rxbind>] S<<< [B<-auditlog> >] >>> + S<<< [B<-audit-interface> (file | sysvmq)] >>> S<<< [B<-syslog>[=>]] >>> S<<< [B<-rxmaxmtu> >] >>> [B<-help>] @@ -150,9 +151,14 @@ log file. B<-syslog>=I can be used to specify to which facility the log message should be sent. Logging message sent to syslog are tagged with the string "ptserver". -=item B<-auditlog> > +=item B<-auditlog> > -Specifies the full pathname for the B file. +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. =item B<-rxmaxmtu> > diff --git a/doc/man-pages/pod8/vlserver.pod b/doc/man-pages/pod8/vlserver.pod index 15ef3b41f..bb100e2aa 100644 --- a/doc/man-pages/pod8/vlserver.pod +++ b/doc/man-pages/pod8/vlserver.pod @@ -9,6 +9,7 @@ vlserver - Initializes the Volume Location Server B S<<< [B<-p> >] >>> [B<-nojumbo>] [B<-jumbo>] [B<-rxbind>] S<<< [B<-d> >] >>> [B<-allow-dotted-principals>] [B<-enable_peer_stats>] [B<-enable_process_stats>] + S<<< [B<-auditlog> >] >>> [B<-audit-interface> (file | sysvmq)] [B<-help>] =for html @@ -104,6 +105,15 @@ user.admin PTS entry. Sites whose Kerberos realms don't have these collisions between principal names may disable this check by starting the server with this option. +=item B<-auditlog> > + +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. + =item B<-rxbind> Bind the Rx socket to the primary interface only. (If not specified, the diff --git a/doc/man-pages/pod8/volserver.pod b/doc/man-pages/pod8/volserver.pod index 6f1170100..3f8c4e9b1 100644 --- a/doc/man-pages/pod8/volserver.pod +++ b/doc/man-pages/pod8/volserver.pod @@ -8,6 +8,7 @@ volserver - Initializes the Volume Server component of the fs process
B [B<-log>] S<<< [B<-p> >] >>> + S<<< [B<-auditlog> >] >>> [B<-audit-interface> (file | sysvmq)] S<<< [B<-udpsize> >] >>> S<<< [B<-d> >] >>> [B<-nojumbo>] [B<-jumbo>] @@ -66,6 +67,15 @@ B<-f> flag. Sets the number of server lightweight processes (LWPs) to run. Provide an integer between C<4> and C<16>. The default is C<9>. +=item B<-auditlog> > + +Turns on audit logging, and sets the path for the audit log. + +=item B<-audit-interface> (file | sysvmq) + +Specifies what audit interface to use. Defaults to C. See +L for an explanation of each interface. + =item B<-udpsize> > Sets the size of the UDP buffer in bytes, which is 64 KB by diff --git a/src/audit/Makefile.in b/src/audit/Makefile.in index 89da44299..2eed8e140 100644 --- a/src/audit/Makefile.in +++ b/src/audit/Makefile.in @@ -29,14 +29,20 @@ ${TOP_LIBDIR}/libaudit.a: libaudit.a ${TOP_INCDIR}/afs/audit.h: audit.h ${INSTALL_DATA} $? $@ -libaudit.a: audit.o AFS_component_version_number.o +libaudit.a: audit.o audit-file.o audit-sysvmq.o AFS_component_version_number.o $(RM) -f libaudit.a - ar r libaudit.a audit.o AFS_component_version_number.o + ar r libaudit.a audit.o audit-file.o audit-sysvmq.o AFS_component_version_number.o $(RANLIB) libaudit.a -audit.o: audit.c audit.h +audit.o: audit.c audit.h audit-api.h ${CC} ${CFLAGS} -c ${srcdir}/audit.c +audit-file.o: audit-file.c audit.h audit-api.h + ${CC} ${CFLAGS} -c ${srcdir}/audit-file.c + +audit-sysvmq.o: audit-sysvmq.c audit.h audit-api.h + ${CC} ${CFLAGS} -c ${srcdir}/audit-sysvmq.c + # XXX-INST: where to install the AIX audit files? install: audit.h libaudit.a ${INSTALL} -d ${DESTDIR}${libdir}/afs diff --git a/src/audit/audit-api.h b/src/audit/audit-api.h new file mode 100644 index 000000000..f7f024ece --- /dev/null +++ b/src/audit/audit-api.h @@ -0,0 +1,20 @@ +/* + * Copyright 2009, Sine Nomine Associates and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#ifndef _AUDIT_API_H +#define _AUDIT_API_H + +struct osi_audit_ops { + void (*send_msg)(void); + void (*append_msg)(const char *format, ...); + int (*open_file)(const char *fileName); + void (*print_interface_stats)(FILE *out); +}; + +#endif /* _AUDIT_API_H */ diff --git a/src/audit/audit-file.c b/src/audit/audit-file.c new file mode 100644 index 000000000..c6a715083 --- /dev/null +++ b/src/audit/audit-file.c @@ -0,0 +1,89 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "audit-api.h" + +static FILE *auditout; + +static void +send_msg(void) +{ + fprintf(auditout, "\n"); + fflush(auditout); +} + +static void +append_msg(const char *format, ...) +{ + va_list vaList; + + va_start(vaList, format); + vfprintf(auditout, format, vaList); + va_end(vaList); +} + +static int +open_file(const char *fileName) +{ + int tempfd, flags; + char oldName[MAXPATHLEN]; + +#ifndef AFS_NT40_ENV + struct stat statbuf; + + if ((lstat(fileName, &statbuf) == 0) + && (S_ISFIFO(statbuf.st_mode))) { + flags = O_WRONLY | O_NONBLOCK; + } else +#endif + { + strcpy(oldName, fileName); + strcat(oldName, ".old"); + renamefile(fileName, oldName); + flags = O_WRONLY | O_TRUNC | O_CREAT; + } + tempfd = open(fileName, flags, 0666); + if (tempfd > -1) { + auditout = fdopen(tempfd, "a"); + if (!auditout) { + printf("Warning: auditlog %s not writable, ignored.\n", fileName); + return 1; + } + } else { + printf("Warning: auditlog %s not writable, ignored.\n", fileName); + return 1; + } + return 0; +} + +static void +print_interface_stats(FILE *out) +{ + return; +} + +const struct osi_audit_ops audit_file_ops = { + &send_msg, + &append_msg, + &open_file, + &print_interface_stats, +}; diff --git a/src/audit/audit-sysvmq.c b/src/audit/audit-sysvmq.c new file mode 100644 index 000000000..327bdda7d --- /dev/null +++ b/src/audit/audit-sysvmq.c @@ -0,0 +1,135 @@ +/* + * Copyright 2009, Sine Nomine Associates and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include + +/* only build on platforms that have SysV IPC support; i.e., when we + * have sys/ipc.h */ +#ifdef HAVE_SYS_IPC_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "audit-api.h" + +/* solaris default is 2048 */ +#define MAXMSG 2048 + +/* message queue size will be increased to this value + if not already bigger */ +#define MSGMNB (2*1024*1024) + +static struct my_msgbuf { + long mtype; + char mtext[MAXMSG]; +} msgbuffer; + +static int mqid; + +static struct mqaudit_stats { + long all; + long truncated; + long lost; +} myauditstats; + +static int truncated; + +static void +send_msg(void) +{ + /* +1 to send the trailing '\0' in the message too so the + receiver doesn't need to bother with it */ + if (msgsnd(mqid, &msgbuffer, strlen(msgbuffer.mtext)+1, IPC_NOWAIT) == -1) { + myauditstats.lost++; + } else if (truncated) { + myauditstats.truncated++; + } + myauditstats.all++; + msgbuffer.mtext[0] = 0; + truncated = 0; +} + +static void +append_msg(const char *format, ...) +{ + va_list vaList; + int size, printed; + + size = MAXMSG - strlen(msgbuffer.mtext); + + va_start(vaList, format); + printed = vsnprintf(&msgbuffer.mtext[strlen(msgbuffer.mtext)], size, format, vaList); + va_end(vaList); + + /* A return value of size or more means that the output was truncated. + If an output error is encountered, a negative value is returned. */ + if (size <= printed || printed == -1) { + truncated = 1; + } +} + +static int +open_file(const char *fileName) +{ + int tempfd; + struct msqid_ds msqdesc; + + msgbuffer.mtext[0] = 0; + msgbuffer.mtype = 1; + + truncated = 0; + myauditstats.all = 0; + myauditstats.lost = 0; + myauditstats.truncated = 0; + + /* try to create file for ftok if it doesn't already exist */ + tempfd = open(fileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if(tempfd != -1) + close(tempfd); + + mqid = msgget(ftok(fileName, 1), S_IRUSR | S_IWUSR | IPC_CREAT); + if (mqid == -1) { + printf("Warning: auditlog message queue %s cannot be opened.\n", fileName); + return 1; + } + + /* increase message queue size */ + msgctl(mqid, IPC_STAT, &msqdesc); + if (msqdesc.msg_qbytes < MSGMNB) { + msqdesc.msg_qbytes = MSGMNB; + msgctl(mqid, IPC_SET, &msqdesc); + } + + return 0; +} + +static void +print_interface_stats(FILE *out) +{ + fprintf(out, "audit statistics: %ld messages total, %ld truncated, %ld lost\n", + myauditstats.all, myauditstats.truncated, myauditstats.lost); +} + +const struct osi_audit_ops audit_sysvmq_ops = { + &send_msg, + &append_msg, + &open_file, + &print_interface_stats, +}; + +#endif /* HAVE_SYS_IPC_H */ diff --git a/src/audit/audit.c b/src/audit/audit.c index bc7ea94ff..f4502dc9e 100644 --- a/src/audit/audit.c +++ b/src/audit/audit.c @@ -36,6 +36,7 @@ #include #include #include "audit.h" +#include "audit-api.h" #include "lock.h" #ifdef AFS_AIX32_ENV #include @@ -52,22 +53,42 @@ # endif #endif -char *bufferPtr; -int bufferLen; -int osi_audit_all = (-1); /* Not determined yet */ -int osi_echo_trail = (-1); +extern struct osi_audit_ops audit_file_ops; +#ifdef HAVE_SYS_IPC_H +extern struct osi_audit_ops audit_sysvmq_ops; +#endif + +static struct { + const char *name; + const struct osi_audit_ops *ops; +} audit_interfaces[] = { + + { "file", &audit_file_ops }, +#ifdef HAVE_SYS_IPC_H + { "sysvmq", &audit_sysvmq_ops }, +#endif +}; -FILE *auditout = NULL; +#define N_INTERFACES (sizeof(audit_interfaces) / sizeof(audit_interfaces[0])) -int osi_audit_check(void); +/* default to `file' audit interface */ +static const struct osi_audit_ops *audit_ops = &audit_file_ops; + +static int osi_audit_all = (-1); /* Not determined yet */ +static int osi_echo_trail = (-1); + +static int auditout_open = 0; + +static int osi_audit_check(void); #ifdef AFS_AIX32_ENV +static char *bufferPtr; +static int bufferLen; + static void audmakebuf(char *audEvent, va_list vaList) { -#ifdef AFS_AIX32_ENV int code; -#endif int vaEntry; int vaInt; afs_int32 vaLong; @@ -149,7 +170,7 @@ audmakebuf(char *audEvent, va_list vaList) #endif static void -printbuf(FILE *out, int rec, char *audEvent, char *afsName, afs_int32 hostId, +printbuf(int rec, char *audEvent, char *afsName, afs_int32 hostId, afs_int32 errCode, va_list vaList) { int vaEntry; @@ -170,17 +191,17 @@ printbuf(FILE *out, int rec, char *audEvent, char *afsName, afs_int32 hostId, timeStamp = afs_ctime(¤ttime, tbuffer, sizeof(tbuffer)); timeStamp[24] = ' '; /* ts[24] is the newline, 25 is the null */ - fprintf(out, timeStamp); + audit_ops->append_msg(timeStamp); if (num > -1) - fprintf(out, "[%d] ", num); + audit_ops->append_msg("[%d] ", num); } - fprintf(out, "EVENT %s CODE %d ", audEvent, errCode); + audit_ops->append_msg("EVENT %s CODE %d ", audEvent, errCode); if (afsName) { hostAddr.s_addr = hostId; - fprintf(out, "NAME %s HOST %s ", afsName, inet_ntoa(hostAddr)); + audit_ops->append_msg("NAME %s HOST %s ", afsName, inet_ntoa(hostAddr)); } vaEntry = va_arg(vaList, int); @@ -189,52 +210,52 @@ printbuf(FILE *out, int rec, char *audEvent, char *afsName, afs_int32 hostId, case AUD_STR: /* String */ vaStr = (char *)va_arg(vaList, char *); if (vaStr) - fprintf(out, "STR %s ", vaStr); + audit_ops->append_msg("STR %s ", vaStr); else - fprintf(out, "STR "); + audit_ops->append_msg("STR "); break; case AUD_NAME: /* Name */ vaStr = (char *)va_arg(vaList, char *); if (vaStr) - fprintf(out, "NAME %s ", vaStr); + audit_ops->append_msg("NAME %s ", vaStr); else - fprintf(out, "NAME "); + audit_ops->append_msg("NAME "); break; case AUD_ACL: /* ACL */ vaStr = (char *)va_arg(vaList, char *); if (vaStr) - fprintf(out, "ACL %s ", vaStr); + audit_ops->append_msg("ACL %s ", vaStr); else - fprintf(out, "ACL "); + audit_ops->append_msg("ACL "); break; case AUD_INT: /* Integer */ vaInt = va_arg(vaList, int); - fprintf(out, "INT %d ", vaInt); + audit_ops->append_msg("INT %d ", vaInt); break; case AUD_ID: /* ViceId */ vaInt = va_arg(vaList, int); - fprintf(out, "ID %d ", vaInt); + audit_ops->append_msg("ID %d ", vaInt); break; case AUD_DATE: /* Date */ vaLong = va_arg(vaList, afs_int32); - fprintf(out, "DATE %u ", vaLong); + audit_ops->append_msg("DATE %u ", vaLong); break; case AUD_HOST: /* Host ID */ vaLong = va_arg(vaList, afs_int32); hostAddr.s_addr = vaLong; - fprintf(out, "HOST %s ", inet_ntoa(hostAddr)); + audit_ops->append_msg("HOST %s ", inet_ntoa(hostAddr)); break; case AUD_LONG: /* afs_int32 */ vaLong = va_arg(vaList, afs_int32); - fprintf(out, "LONG %d ", vaLong); + audit_ops->append_msg("LONG %d ", vaLong); break; case AUD_FID: /* AFSFid - contains 3 entries */ vaFid = va_arg(vaList, struct AFSFid *); if (vaFid) - fprintf(out, "FID %u:%u:%u ", vaFid->Volume, vaFid->Vnode, + audit_ops->append_msg("FID %u:%u:%u ", vaFid->Volume, vaFid->Vnode, vaFid->Unique); else - fprintf(out, "FID %u:%u:%u ", 0, 0, 0); + audit_ops->append_msg("FID %u:%u:%u ", 0, 0, 0); break; case AUD_FIDS: /* array of Fids */ vaFids = va_arg(vaList, struct AFSCBFids *); @@ -245,24 +266,24 @@ printbuf(FILE *out, int rec, char *audEvent, char *afsName, afs_int32 hostId, vaFid = vaFids->AFSCBFids_val; if (vaFid) { - fprintf(out, "FIDS %u FID %u:%u:%u ", vaFids->AFSCBFids_len, vaFid->Volume, + audit_ops->append_msg("FIDS %u FID %u:%u:%u ", vaFids->AFSCBFids_len, vaFid->Volume, vaFid->Vnode, vaFid->Unique); for ( i = 1; i < vaFids->AFSCBFids_len; i++, vaFid++ ) - fprintf(out, "FID %u:%u:%u ", vaFid->Volume, + audit_ops->append_msg("FID %u:%u:%u ", vaFid->Volume, vaFid->Vnode, vaFid->Unique); } else - fprintf(out, "FIDS 0 FID 0:0:0 "); + audit_ops->append_msg("FIDS 0 FID 0:0:0 "); } break; default: - fprintf(out, "--badval-- "); + audit_ops->append_msg("--badval-- "); break; } /* end switch */ vaEntry = va_arg(vaList, int); } /* end while */ - fprintf(out, "\n"); + audit_ops->send_msg(); } #ifdef AFS_PTHREAD_ENV @@ -291,7 +312,7 @@ osi_audit_init(void) /* ************************************************************************** */ /* The routine that acually does the audit call. * ************************************************************************** */ -int +static int osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */ afs_int32 errCode, /* The error code */ char *afsName, @@ -304,7 +325,6 @@ osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */ static char BUFFER[32768]; #endif int result; - va_list vaCopy; #ifdef AFS_PTHREAD_ENV /* i'm pretty sure all the server apps now call osi_audit_init(), @@ -315,11 +335,9 @@ osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */ if ((osi_audit_all < 0) || (osi_echo_trail < 0)) osi_audit_check(); - if (!osi_audit_all && !auditout) + if (!osi_audit_all && !auditout_open) return 0; - va_copy(vaCopy, vaList); - switch (errCode) { case 0: result = AUDIT_OK; @@ -357,18 +375,12 @@ osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */ audmakebuf(audEvent, vaList); #endif - if (osi_echo_trail) { - printbuf(stdout, 0, audEvent, afsName, hostId, errCode, vaList); - } - va_end(vaCopy); - #ifdef AFS_AIX32_ENV bufferLen = (int)((afs_int32) bufferPtr - (afs_int32) & BUFFER[0]); code = auditlog(audEvent, result, BUFFER, bufferLen); #else - if (auditout) { - printbuf(auditout, 0, audEvent, afsName, hostId, errCode, vaList); - fflush(auditout); + if (auditout_open) { + printbuf(0, audEvent, afsName, hostId, errCode, vaList); } #endif #ifdef AFS_PTHREAD_ENV @@ -386,7 +398,7 @@ osi_audit(char *audEvent, /* Event name (15 chars or less) */ if ((osi_audit_all < 0) || (osi_echo_trail < 0)) osi_audit_check(); - if (!osi_audit_all && !auditout) + if (!osi_audit_all && !auditout_open) return 0; va_start(vaList, errCode); @@ -413,7 +425,7 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...) if (osi_audit_all < 0) osi_audit_check(); - if (!osi_audit_all && !auditout) + if (!osi_audit_all && !auditout_open) return 0; strcpy(afsName, "--Unknown--"); @@ -454,7 +466,7 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...) int i, lrealm_match; if (num_lrealms == -1) { - for (i=0; iopen_file(fileName)) { + auditout_open = 1; + return 0; } - tempfd = open(fileName, flags, 0666); - if (tempfd > -1) { - auditout = fdopen(tempfd, "a"); - if (!auditout) { - printf("Warning: auditlog %s not writable, ignored.\n", fileName); - return 1; - } - } else { - printf("Warning: auditlog %s not writable, ignored.\n", fileName); - return 1; + return 1; +} + +int +osi_audit_interface(const char *interface) +{ + int i; + for (i = 0; i < N_INTERFACES; ++i) { + if (strcmp(interface, audit_interfaces[i].name) == 0) { + audit_ops = audit_interfaces[i].ops; + return 0; + } } - return 0; + + return 1; +} + +void +audit_PrintStats(FILE *out) +{ + audit_ops->print_interface_stats(out); } diff --git a/src/audit/audit.h b/src/audit/audit.h index bed4b53dd..20c6f0b5b 100644 --- a/src/audit/audit.h +++ b/src/audit/audit.h @@ -291,6 +291,7 @@ /* prototypes for audit functions */ int osi_audit(char *audEvent, afs_int32 errCode, ...); int osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...); -int osi_audit_file(char *filename); +int osi_audit_file(const char *filename); void osi_audit_init(void); - +int osi_audit_interface(const char *interface); +void audit_PrintStats(FILE *out); diff --git a/src/bozo/bosserver.c b/src/bozo/bosserver.c index 1b501e6f7..20d1a0397 100644 --- a/src/bozo/bosserver.c +++ b/src/bozo/bosserver.c @@ -726,6 +726,7 @@ main(int argc, char **argv, char **envp) char namebuf[AFSDIR_PATH_MAX]; int rxMaxMTU = -1; afs_uint32 host = htonl(INADDR_ANY); + char *auditFileName = NULL; #ifndef AFS_NT40_ENV int nofork = 0; struct stat sb; @@ -841,9 +842,15 @@ main(int argc, char **argv, char **envp) } } else if (strcmp(argv[code], "-auditlog") == 0) { - char *fileName = argv[++code]; + auditFileName = argv[++code]; - osi_audit_file(fileName); + } else if (strcmp(argv[code], "-audit-interface") == 0) { + char *interface = argv[++code]; + + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + exit(1); + } } else { @@ -852,6 +859,7 @@ main(int argc, char **argv, char **envp) #ifndef AFS_NT40_ENV printf("Usage: bosserver [-noauth] [-log] " "[-auditlog ] " + "[-audit-interafce (default is file)] " "[-rxmaxmtu ] [-rxbind] [-allow-dotted-principals]" "[-syslog[=FACILITY]] " "[-enable_peer_stats] [-enable_process_stats] " @@ -859,6 +867,7 @@ main(int argc, char **argv, char **envp) #else printf("Usage: bosserver [-noauth] [-log] " "[-auditlog ] " + "[-audit-interafce (default is file)] " "[-rxmaxmtu ] [-rxbind] [-allow-dotted-principals]" "[-enable_peer_stats] [-enable_process_stats] " "[-help]\n"); @@ -868,6 +877,9 @@ main(int argc, char **argv, char **envp) exit(0); } } + if (auditFileName) { + osi_audit_file(auditFileName); + } #ifndef AFS_NT40_ENV if (geteuid() != 0) { diff --git a/src/budb/server.c b/src/budb/server.c index d63591b2a..a9d5af648 100644 --- a/src/budb/server.c +++ b/src/budb/server.c @@ -175,6 +175,8 @@ initializeArgHandler(void) cmd_AddParm(cptr, "-rxbind", CMD_FLAG, CMD_OPTIONAL, "bind the Rx socket (primary interface only)"); + cmd_AddParm(cptr, "-audit-interface", CMD_SINGLE, CMD_OPTIONAL, + "audit interface (file or sysvmq)"); } int @@ -226,11 +228,7 @@ argHandler(struct cmd_syndesc *as, void *arock) else ubik_nBuffers = 0; - if (as->parms[7].items != 0) { - char *fileName = as->parms[7].items->data; - - osi_audit_file(fileName); - } + /* param 7 (-auditlog) handled below */ /* user provided the number of threads */ if (as->parms[8].items != 0) { @@ -252,6 +250,25 @@ argHandler(struct cmd_syndesc *as, void *arock) rxBind = 1; } + /* -audit-interface */ + if (as->parms[10].items != 0) { + char *interface = as->parms[10].items->data; + + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + BUDB_EXIT(-1); + } + } + + /* -auditlog */ + /* needs to be after -audit-interface, so we osi_audit_interface + * before we osi_audit_file */ + if (as->parms[7].items != 0) { + char *fileName = as->parms[7].items->data; + + osi_audit_file(fileName); + } + return 0; } diff --git a/src/kauth/kaserver.c b/src/kauth/kaserver.c index 535387f36..8c0b282de 100644 --- a/src/kauth/kaserver.c +++ b/src/kauth/kaserver.c @@ -161,6 +161,7 @@ main(int argc, char *argv[]) afs_int32 i; char clones[MAXHOSTSPERCELL]; afs_uint32 host = ntohl(INADDR_ANY); + char *auditFileName = NULL; struct rx_service *tservice; struct rx_securityClass *sca[1]; @@ -192,9 +193,9 @@ main(int argc, char *argv[]) if (argc == 0) { usage: printf("Usage: kaserver [-noAuth] [-fastKeys] [-database ] " - "[-auditlog ] [-rxbind] " - "[-localfiles ] [-minhours ] [-servers ] " - "[-crossrealm]" + "[-auditlog ] [-audit-interface ] " + "[-rxbind] [-localfiles ] [-minhours ] " + "[-servers ] [-crossrealm] " /*" [-enable_peer_stats] [-enable_process_stats] " */ "[-help]\n"); exit(1); @@ -238,9 +239,16 @@ main(int argc, char *argv[]) lclpath = dbpath; } else if (strncmp(arg, "-auditlog", arglen) == 0) { - char *fileName = argv[++a]; + auditFileName = argv[++a]; + + } else if (strncmp(arg, "-audit-interface", arglen) == 0) { + char *interface = argv[++a]; + + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + exit(1); + } - osi_audit_file(fileName); } else if (strcmp(arg, "-localfiles") == 0) lclpath = argv[++a]; else if (strcmp(arg, "-servers") == 0) @@ -282,6 +290,11 @@ main(int argc, char *argv[]) goto usage; } } + + if (auditFileName) { + osi_audit_file(auditFileName); + } + if ((code = ka_CellConfig(cellservdb))) goto abort; cell = ka_LocalCell(); diff --git a/src/libafsauthent/Makefile.in b/src/libafsauthent/Makefile.in index 413ef8cd7..6b11521d7 100644 --- a/src/libafsauthent/Makefile.in +++ b/src/libafsauthent/Makefile.in @@ -27,7 +27,7 @@ RXKAD = ../rxkad PTSERVER = ../ptserver SYS = ../sys -AUDITOBJS = audit.o +AUDITOBJS = audit.o audit-file.o audit-sysvmq.o AUTHOBJS = \ cellconfig.o \ @@ -112,6 +112,12 @@ libafsauthent.a: ${LIBOBJS} audit.o: ${AUDIT}/audit.c ${CCRULE} +audit-file.o: ${AUDIT}/audit-file.c + ${CCRULE} + +audit-sysvmq.o: ${AUDIT}/audit-sysvmq.c + ${CCRULE} + cellconfig.o: ${AUTH}/cellconfig.c ${CCRULE} diff --git a/src/ptserver/ptserver.c b/src/ptserver/ptserver.c index 745e5e02c..5ea4d6ac9 100644 --- a/src/ptserver/ptserver.c +++ b/src/ptserver/ptserver.c @@ -225,6 +225,8 @@ main(int argc, char **argv) int a; char arg[100]; + char *auditFileName = NULL; + #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a @@ -329,10 +331,14 @@ main(int argc, char **argv) } #endif else if (strncmp(arg, "-auditlog", alen) == 0) { - char *fileName = argv[++a]; + auditFileName = argv[++a]; - osi_audit_file(fileName); - osi_audit(PTS_StartEvent, 0, AUD_END); + } else if (strncmp(arg, "-audit-interface", alen) == 0) { + char *interface = argv[++a]; + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + PT_EXIT(1); + } } else if (!strncmp(arg, "-rxmaxmtu", alen)) { if ((a + 1) >= argc) { @@ -355,6 +361,7 @@ main(int argc, char **argv) #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database ] " "[-auditlog ] " + "[-audit-interface (default is file)] " "[-syslog[=FACILITY]] [-d ] " "[-p ] [-rebuild] " "[-groupdepth ] " @@ -365,7 +372,9 @@ main(int argc, char **argv) "[-help]\n"); #else /* AFS_NT40_ENV */ printf("Usage: ptserver [-database ] " - "[-auditlog ] [-d ] " + "[-auditlog ] " + "[-audit-interface (default is file)] " + "[-d ] " "[-p ] [-rebuild] [-rxbind] " "[-allow-dotted-principals] " "[-default_access default_user_access default_group_access] " @@ -375,7 +384,9 @@ main(int argc, char **argv) #else #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database ] " - "[-auditlog ] [-d ] " + "[-auditlog ] " + "[-audit-interface (default is file)] " + "[-d ] " "[-syslog[=FACILITY]] " "[-p ] [-rebuild] " "[-enable_peer_stats] [-enable_process_stats] " @@ -403,6 +414,11 @@ main(int argc, char **argv) #endif } + if (auditFileName) { + osi_audit_file(auditFileName); + osi_audit(PTS_StartEvent, 0, AUD_END); + } + #ifndef AFS_NT40_ENV serverLogSyslogTag = "ptserver"; #endif diff --git a/src/viced/viced.c b/src/viced/viced.c index 45bb1f3a3..720d9d164 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -731,6 +731,7 @@ PrintCounters(void) ("With %d directory buffers; %d reads resulted in %d read I/Os\n", dirbuff, dircall, dirio)); rx_PrintStats(stderr); + audit_PrintStats(stderr); h_PrintStats(); PrintCallBackStats(); #ifdef AFS_NT40_ENV @@ -878,6 +879,7 @@ FlagMsg(void) fputs("Usage: fileserver ", stdout); fputs("[-auditlog ] ", stdout); + fputs("[-audit-interface (default is file)] ", stdout); fputs("[-d ] ", stdout); fputs("[-p ] ", stdout); fputs("[-spare ] ", stdout); @@ -1043,6 +1045,7 @@ ParseArgs(int argc, char *argv[]) int Sawbusy = 0; int i; int bufSize = 0; /* temp variable to read in udp socket buf size */ + char *auditFileName = NULL; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) { @@ -1350,9 +1353,15 @@ ParseArgs(int argc, char *argv[]) rx_enableProcessRPCStats(); } else if (strcmp(argv[i], "-auditlog") == 0) { - char *fileName = argv[++i]; + auditFileName = argv[++i]; + } + else if (strcmp(argv[i], "-audit-interface") == 0) { + char *interface = argv[++i]; - osi_audit_file(fileName); + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + return -1; + } } #ifndef AFS_NT40_ENV else if (strcmp(argv[i], "-syslog") == 0) { @@ -1412,6 +1421,8 @@ ParseArgs(int argc, char *argv[]) } if (!Sawbusy) busy_threshold = 3 * rxpackets / 2; + if (auditFileName) + osi_audit_file(auditFileName); return (0); diff --git a/src/vlserver/vlserver.c b/src/vlserver/vlserver.c index 115175907..155884b31 100644 --- a/src/vlserver/vlserver.c +++ b/src/vlserver/vlserver.c @@ -141,6 +141,7 @@ main(int argc, char **argv) int noAuth = 0, index, i; char commandLine[150]; char clones[MAXHOSTSPERCELL]; + char *auditFileName = NULL; afs_uint32 host = ntohl(INADDR_ANY); #ifdef AFS_AIX32_ENV @@ -208,10 +209,17 @@ main(int argc, char **argv) extern char rxi_tracename[80]; strcpy(rxi_tracename, argv[++index]); - } else if (strcmp(argv[index], "-auditlog") == 0) { - char *fileName = argv[++index]; + } else if (strcmp(argv[index], "-auditlog") == 0) { + auditFileName = argv[++index]; + + } else if (strcmp(argv[index], "-audit-interface") == 0) { + char *interface = argv[++index]; + + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + return -1; + } - osi_audit_file(fileName); } else if (strcmp(argv[index], "-enable_peer_stats") == 0) { rx_enablePeerRPCStats(); } else if (strcmp(argv[index], "-enable_process_stats") == 0) { @@ -245,6 +253,10 @@ main(int argc, char **argv) } } + if (auditFileName) { + osi_audit_file(auditFileName); + } + /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV diff --git a/src/volser/volmain.c b/src/volser/volmain.c index b78085ed9..ee758607a 100644 --- a/src/volser/volmain.c +++ b/src/volser/volmain.c @@ -245,6 +245,7 @@ main(int argc, char **argv) int rxMaxMTU = -1; int bufSize = 0; /* temp variable to read in udp socket buf size */ afs_uint32 host = ntohl(INADDR_ANY); + char *auditFileName = NULL; #ifdef AFS_AIX32_ENV /* @@ -308,10 +309,15 @@ main(int argc, char **argv) lwps = MAXLWP; } } else if (strcmp(argv[code], "-auditlog") == 0) { - char *fileName = argv[++code]; + auditFileName = argv[++code]; - osi_audit_file(fileName); - osi_audit(VS_StartEvent, 0, AUD_END); + } else if (strcmp(argv[code], "-audit-interface") == 0) { + char *interface = argv[++code]; + + if (osi_audit_interface(interface)) { + printf("Invalid audit interface '%s'\n", interface); + return -1; + } } else if (strcmp(argv[code], "-nojumbo") == 0) { rxJumbograms = 0; } else if (strcmp(argv[code], "-jumbo") == 0) { @@ -384,6 +390,11 @@ main(int argc, char **argv) VS_EXIT(1); } } + + if (auditFileName) { + osi_audit_file(auditFileName); + osi_audit(VS_StartEvent, 0, AUD_END); + } #ifdef AFS_SGI_VNODE_GLUE if (afs_init_kernel_config(-1) < 0) { printf -- 2.39.5