Enhance audit logs to support SysV message queues
authorAndrew Deason <adeason@sinenomine.net>
Wed, 24 Jun 2009 21:46:27 +0000 (17:46 -0400)
committerDerrick Brashear <shadow@dementia.org>
Fri, 24 Jul 2009 19:39:57 +0000 (12:39 -0700)
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 <adeason@sinenomine.net>
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

22 files changed:
acinclude.m4
doc/man-pages/pod8/bosserver.pod
doc/man-pages/pod8/buserver.pod
doc/man-pages/pod8/fileserver.pod
doc/man-pages/pod8/kaserver.pod
doc/man-pages/pod8/ptserver.pod
doc/man-pages/pod8/vlserver.pod
doc/man-pages/pod8/volserver.pod
src/audit/Makefile.in
src/audit/audit-api.h [new file with mode: 0644]
src/audit/audit-file.c [new file with mode: 0644]
src/audit/audit-sysvmq.c [new file with mode: 0644]
src/audit/audit.c
src/audit/audit.h
src/bozo/bosserver.c
src/budb/server.c
src/kauth/kaserver.c
src/libafsauthent/Makefile.in
src/ptserver/ptserver.c
src/viced/viced.c
src/vlserver/vlserver.c
src/volser/volmain.c

index 4eec8ac..0ec466f 100644 (file)
@@ -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 <linux/types.h>])
 
index 5a1402d..27dc055 100644 (file)
@@ -8,6 +8,7 @@ bosserver - Initializes the BOS Server
 <div class="synopsis">
 
 B<bosserver> [B<-noauth>] [B<-log>] [B<-enable_peer_stats>]
+    S<<< [B<-auditlog> <I<log path>>] >>> [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</usr/afs/logs/BosLog> file the names of all users who
 successfully issue a privileged B<bos> command (one that requires being
 listed in the F</usr/afs/etc/UserList> file).
 
+=item B<-auditlog> <I<log path>>
+
+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<file>. See
+L<fileserver(8)> for an explanation of each interface.
+
 =item B<-enable_peer_stats>
 
 Activates the collection of Rx statistics and allocates memory for their
index be8adce..38af3e6 100644 (file)
@@ -8,6 +8,7 @@ buserver - Initializes the Backup Server
 <div class="synopsis">
 
 B<buserver> S<<< [B<-database> <I<database directory>>] >>>
+    S<<< [B<-auditlog> <I<log path>>] >>> [B<-audit-interface> (file | sysvmq)]
     S<<< [B<-cellservdb> <I<cell configuration directory>>] >>> [B<-resetdb>]
     [B<-noauth>] [B<-smallht>] [B<-servers> <I<list of ubik database 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</usr/afs/db> directory.
 
+=item B<-auditlog> <I<log path>>
+
+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<file>. See
+L<fileserver(8)> for an explanation of each interface.
+
 =item B<-cellservdb> <I<cell configuration directory>>
 
 Specifies the pathname of the directory from which the Backup Server reads
index e521669..9cf1a78 100644 (file)
@@ -8,6 +8,7 @@ fileserver - Initializes the File Server component of the fs process
 <div class="synopsis">
 
 B<fileserver> S<<< [B<-auditlog> <I<path to log file>>] >>>
+    S<<< [B<-audit-interface> (file | sysvmq)] >>>
     S<<< [B<-d> <I<debug level>>] >>>
     S<<< [B<-p> <I<number of processes>>] >>>
     S<<< [B<-spare> <I<number of spare blocks>>] >>>
@@ -257,6 +258,17 @@ length.
 
 Set and enable auditing.
 
+=item B<-audit-interface> (file | sysvmq)
+
+Specifies what audit interface to use. The C<file> interface writes audit
+messages to the file passed to B<-auditlog>. The C<sysvmq> interface
+writes audit messages to a SYSV message (see L<msgget(2)> and
+L<msgrcv(2)>). The message queue the C<sysvmq> interface writes to has the
+key C<ftok(path, 1)>, where C<path> is the path specified in the
+B<-auditlog> option.
+
+Defaults to C<file>.
+
 =item B<-d> <I<debug level>>
 
 Sets the detail level for the debugging trace written to the
index 252e961..48fc766 100644 (file)
@@ -8,6 +8,7 @@ kaserver - Initializes the Authentication Server
 <div class="synopsis">
 
 B<kaserver> [B<-noAuth>] [B<-fastKeys>] [B<-database> <I<dbpath>>]
+    S<<< [B<-auditlog> <I<log path>>] >>> [B<-audit-interface> (file | sysvmq)]
     S<<< [B<-localfiles> <I<lclpath>>] >>> S<<< [B<-minhours> <I<n>>] >>>
     S<<< [B<-servers> <I<serverlist>>] >>> [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> <I<log path>>
+
+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<file>. See
+L<fileserver(8)> for an explanation of each interface.
+
 =item B<-localfiles> <I<lclpath>>
 
 Specifies the pathname of an alternate directory in which the auxiliary
index dcc2dcb..43eb359 100644 (file)
@@ -13,6 +13,7 @@ B<ptserver> S<<< [B<-database> | B<-db> <I<db path>>] >>> S<<< [B<-p> <I<number
     [B<-restricted>] [B<-enable_peer_stats>]
     [B<-enable_process_stats>] [B<-allow-dotted-principals>]
     [B<-rxbind>] S<<< [B<-auditlog> <I<file path>>] >>>
+    S<<< [B<-audit-interface> (file | sysvmq)] >>>
     S<<< [B<-syslog>[=<I<FACILITY>>]] >>> S<<< [B<-rxmaxmtu> <I<bytes>>] >>>
     [B<-help>]
 
@@ -150,9 +151,14 @@ log file.  B<-syslog>=I<FACILITY> 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> <I<file path>>
+=item B<-auditlog> <I<log path>>
 
-Specifies the full pathname for the B<AuditLog> 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<file>. See
+L<fileserver(8)> for an explanation of each interface.
 
 =item B<-rxmaxmtu> <I<bytes>>
 
index 15ef3b4..bb100e2 100644 (file)
@@ -9,6 +9,7 @@ vlserver - Initializes the Volume Location Server
 
 B<vlserver> S<<< [B<-p> <I<number of threads>>] >>> [B<-nojumbo>] [B<-jumbo>] [B<-rxbind>] S<<< [B<-d> <I<debug level>>] >>>
     [B<-allow-dotted-principals>] [B<-enable_peer_stats>] [B<-enable_process_stats>] 
+        S<<< [B<-auditlog> <I<log path>>] >>> [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> <I<log path>>
+
+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<file>. See
+L<fileserver(8)> for an explanation of each interface.
+
 =item B<-rxbind>
 
 Bind the Rx socket to the primary interface only.  (If not specified, the
index 6f11701..3f8c4e9 100644 (file)
@@ -8,6 +8,7 @@ volserver - Initializes the Volume Server component of the fs process
 <div class="synopsis">
 
 B<volserver> [B<-log>] S<<< [B<-p> <I<number of processes>>] >>>
+    S<<< [B<-auditlog> <I<log path>>] >>> [B<-audit-interface> (file | sysvmq)]
     S<<< [B<-udpsize> <I<size of socket buffer in bytes>>] >>>
     S<<< [B<-d> <I<debug level>>] >>>
     [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> <I<log path>>
+
+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<file>. See
+L<fileserver(8)> for an explanation of each interface.
+
 =item B<-udpsize> <I<size of socket buffer>>
 
 Sets the size of the UDP buffer in bytes, which is 64 KB by
index 89da442..2eed8e1 100644 (file)
@@ -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 (file)
index 0000000..f7f024e
--- /dev/null
@@ -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 (file)
index 0000000..c6a7150
--- /dev/null
@@ -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 <afsconfig.h>
+#include <afs/param.h>
+#include <afs/afsutil.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#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 (file)
index 0000000..327bdda
--- /dev/null
@@ -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 <afsconfig.h>
+
+/* only build on platforms that have SysV IPC support; i.e., when we
+ * have sys/ipc.h */
+#ifdef HAVE_SYS_IPC_H
+
+#include <afs/param.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#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 */
index bc7ea94..f4502dc 100644 (file)
@@ -36,6 +36,7 @@
 #include <rx/rx.h>
 #include <rx/rxkad.h>
 #include "audit.h"
+#include "audit-api.h"
 #include "lock.h"
 #ifdef AFS_AIX32_ENV
 #include <sys/audit.h>
 # 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(&currenttime, 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 <null>");
+               audit_ops->append_msg("STR <null>");
            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 <null>");
+               audit_ops->append_msg("NAME <null>");
            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 <null>");
+               audit_ops->append_msg("ACL <null>");
            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; i<AFS_NUM_LREALMS; i++) {
+                           for (i = 0; i < AFS_NUM_LREALMS; i++) {
                                if (afs_krb_get_lrealm(local_realms[i], i) != 0 /*KSUCCESS*/)
                                    break;
                            }
@@ -466,7 +478,7 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
 
                        /* Check to see if the ticket cell matches one of the local realms */
                        lrealm_match = 0;
-                       for ( i=0;i<num_lrealms;i++ ) {
+                       for (i = 0; i < num_lrealms ; i++ ) {
                            if (!strcasecmp(local_realms[i], tcell)) {
                                lrealm_match = 1;
                                break;
@@ -560,35 +572,31 @@ osi_audit_check(void)
 }
 
 int
-osi_audit_file(char *fileName)
+osi_audit_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;
+    if(!audit_ops->open_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);
 }
index bed4b53..20c6f0b 100644 (file)
 /* 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);
index 1b501e6..20d1a03 100644 (file)
@@ -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 <log path>] "
+                  "[-audit-interafce <file|sysvmq> (default is file)] "
                   "[-rxmaxmtu <bytes>] [-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 <log path>] "
+                  "[-audit-interafce <file|sysvmq> (default is file)] "
                   "[-rxmaxmtu <bytes>] [-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) {
index d63591b..a9d5af6 100644 (file)
@@ -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;
 }
 
index 535387f..8c0b282 100644 (file)
@@ -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 <dbpath>] "
-              "[-auditlog <log path>] [-rxbind] "
-              "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
-              "[-crossrealm]"
+              "[-auditlog <log path>] [-audit-interface <file|sysvmq>] "
+              "[-rxbind] [-localfiles <lclpath>] [-minhours <n>] "
+              "[-servers <serverlist>] [-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();
index 413ef8c..6b11521 100644 (file)
@@ -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}
 
index 745e5e0..5ea4d6a 100644 (file)
@@ -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 <db path>] "
                   "[-auditlog <log path>] "
+                  "[-audit-interface <file|sysvmq> (default is file)] "
                   "[-syslog[=FACILITY]] [-d <debug level>] "
                   "[-p <number of processes>] [-rebuild] "
                   "[-groupdepth <depth>] "
@@ -365,7 +372,9 @@ main(int argc, char **argv)
                   "[-help]\n");
 #else /* AFS_NT40_ENV */
            printf("Usage: ptserver [-database <db path>] "
-                  "[-auditlog <log path>] [-d <debug level>] "
+                  "[-auditlog <log path>] "
+                  "[-audit-interface <file|sysvmq> (default is file)] "
+                  "[-d <debug level>] "
                   "[-p <number of processes>] [-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 <db path>] "
-                  "[-auditlog <log path>] [-d <debug level>] "
+                  "[-auditlog <log path>] "
+                  "[-audit-interface <file|sysvmq> (default is file)] "
+                  "[-d <debug level>] "
                   "[-syslog[=FACILITY]] "
                   "[-p <number of processes>] [-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
index 45bb1f3..720d9d1 100644 (file)
@@ -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 <log path>] ", stdout);
+    fputs("[-audit-interface <file|sysvmq> (default is file)] ", stdout);
     fputs("[-d <debug level>] ", stdout);
     fputs("[-p <number of processes>] ", stdout);
     fputs("[-spare <number of spare blocks>] ", 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);
 
index 1151759..155884b 100644 (file)
@@ -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
index b78085e..ee75860 100644 (file)
@@ -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