Fix typos in audit format strings
[openafs.git] / src / audit / audit.c
index 9719b17..1f641f0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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 <roken.h>
 
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef AFS_NT40_ENV
-#include <unistd.h>
-#endif
 #ifdef AFS_AIX32_ENV
 #include <sys/audit.h>
 #else
 #define AUDIT_FAIL_ACCESS 3
 #define AUDIT_FAIL_PRIV 4
 #endif /* AFS_AIX32_ENV */
-#include <errno.h>
 
+#include <afs/opr.h>
 #include "afs/afsint.h"
+#include "afs/butc.h"
 #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
-#include <afs/afsutil.h>
 
-/* C99 requires va_copy.  Older versions of GCC provide __va_copy.  Per t
-   Autoconf manual, memcpy is a generally portable fallback. */          
-#ifndef va_copy              
-# ifdef __va_copy
-#  define va_copy(d, s)         __va_copy((d), (s))             
-# else
-#  define va_copy(d, s)         memcpy(&(d), &(s), sizeof(va_list)) 
-# endif
-#endif      
+#include <afs/afsutil.h>
 
 extern struct osi_audit_ops audit_file_ops;
 #ifdef HAVE_SYS_IPC_H
@@ -57,6 +39,11 @@ extern struct osi_audit_ops audit_sysvmq_ops;
 #endif
 
 static struct {
+    void *rock;
+    int (*islocal)(void *rock, char *name, char *inst, char *cell);
+} audit_user_check = { NULL, NULL };
+
+static struct {
     const char *name;
     const struct osi_audit_ops *ops;
 } audit_interfaces[] = {
@@ -152,6 +139,95 @@ audmakebuf(char *audEvent, va_list vaList)
                bufferPtr += sizeof(struct AFSFid);
                break;
            }
+       /* butc tape label */
+       case AUD_TLBL:
+           {
+               struct tc_tapeLabel *label;
+
+               label = (struct tc_tapeLabel *)va_arg(vaList,
+                                                     struct tc_tapeLabel *);
+               if (label)
+                   memcpy(bufferPtr, label, sizeof(*label));
+               else
+                   memset(bufferPtr, 0, sizeof(*label));
+               bufferPtr += sizeof(label);
+               break;
+           }
+       /* butc dump interface */
+       case AUD_TDI:
+           {
+               struct tc_dumpInterface *di;
+
+               di = (struct tc_dumpInterface *)
+                       va_arg(vaList, struct tc_dumpInterface *);
+               if (di)
+                   memcpy(bufferPtr, di, sizeof(*di));
+               else
+                   memset(bufferPtr, 0, sizeof(*di));
+               bufferPtr += sizeof(*di);
+               break;
+           }
+       /*
+        * butc dump array
+        * An array of dump descriptions, but the AIX audit package assumes fixed
+        * length, so we can only do the first one for now.
+        */
+       case AUD_TDA:
+           {
+               struct tc_dumpArray *da;
+
+               da = (struct tc_dumpArray *)
+                       va_arg(vaList, struct tc_dumpArray *);
+               if (da && da->tc_dumpArray_len) {
+                   memcpy(bufferPtr, &da->tc_dumpArray_len, sizeof(u_int));
+                   bufferPtr += sizeof(u_int);
+                   memcpy(bufferPtr, da->tc_dumpArray_val,
+                          sizeof(da->tc_dumpArray_val[0]));
+               } else {
+                   memset(bufferPtr, 0, sizeof(u_int));
+                   bufferPtr += sizeof(u_int);
+                   memset(bufferPtr, 0, sizeof(da->tc_dumpArray_val[0]));
+               }
+               bufferPtr += sizeof(da->tc_dumpArray_val[0]);
+               break;
+           }
+       /*
+        * butc restore array
+        * An array of restore descriptions, but the AIX audit package assumes
+        * fixed length, so we can only do the first one for now.
+        */
+       case AUD_TRA:
+           {
+               struct tc_restoreArray *ra;
+
+               ra = (struct tc_restoreArray *)
+                       va_arg(vaList, struct tc_restoreArray *);
+               if (ra && ra->tc_restoreArray_len) {
+                   memcpy(bufferPtr, &ra->tc_restoreArray_len, sizeof(u_int));
+                   bufferPtr += sizeof(u_int);
+                   memcpy(bufferPtr, ra->tc_restoreArray_val,
+                          sizeof(ra->tc_restoreArray_val[0]));
+               } else {
+                   memset(bufferPtr, 0, sizeof(u_int));
+                   bufferPtr += sizeof(u_int);
+                   memset(bufferPtr, 0, sizeof(ra->tc_restoreArray_val[0]));
+               }
+               bufferPtr += sizeof(ra->tc_restoreArray_val[0]);
+               break;
+           }
+       /* butc tape controller status */
+           {
+               struct tciStatusS *status;
+
+               status = (struct tciStatusS *)va_arg(vaList,
+                                                    struct tciStatusS *);
+               if (status)
+                   memcpy(bufferPtr, status, sizeof(*status));
+               else
+                   memset(bufferPtr, 0, sizeof(*status));
+               bufferPtr += sizeof(*status);
+               break;
+           }
        default:
 #ifdef AFS_AIX32_ENV
            code =
@@ -177,24 +253,28 @@ printbuf(int rec, char *audEvent, char *afsName, afs_int32 hostId,
     char *vaStr;
     struct AFSFid *vaFid;
     struct AFSCBFids *vaFids;
+    struct tc_tapeLabel *vaLabel;
+    struct tc_dumpInterface *vaDI;
+    struct tc_dumpArray *vaDA;
+    struct tc_restoreArray *vaRA;
+    struct tciStatusS *vaTCstatus;
     int num = LogThreadNum();
     struct in_addr hostAddr;
     time_t currenttime;
-    char *timeStamp;
     char tbuffer[26];
-    
+    struct tm tm;
+
     /* Don't print the timestamp or thread id if we recursed */
     if (rec == 0) {
        currenttime = time(0);
-       timeStamp = afs_ctime(&currenttime, tbuffer,
-                             sizeof(tbuffer));
-       timeStamp[24] = ' ';   /* ts[24] is the newline, 25 is the null */
-       audit_ops->append_msg(timeStamp);
+       if (strftime(tbuffer, sizeof(tbuffer), "%a %b %d %H:%M:%S %Y ",
+                    localtime_r(&currenttime, &tm)) !=0)
+           audit_ops->append_msg(tbuffer);
 
        if (num > -1)
            audit_ops->append_msg("[%d] ", num);
     }
-    
+
     audit_ops->append_msg("EVENT %s CODE %d ", audEvent, errCode);
 
     if (afsName) {
@@ -260,13 +340,12 @@ printbuf(int rec, char *audEvent, char *afsName, afs_int32 hostId,
 
            if (vaFids) {
                 unsigned int i;
-                
+
                 vaFid = vaFids->AFSCBFids_val;
-                
+
                 if (vaFid) {
-                    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++ ) 
+                    audit_ops->append_msg("FIDS %u ", vaFids->AFSCBFids_len);
+                    for ( i = 1; i <= vaFids->AFSCBFids_len; i++, vaFid++ )
                         audit_ops->append_msg("FID %u:%u:%u ", vaFid->Volume,
                                 vaFid->Vnode, vaFid->Unique);
                 } else
@@ -274,6 +353,102 @@ printbuf(int rec, char *audEvent, char *afsName, afs_int32 hostId,
 
             }
            break;
+       case AUD_TLBL:          /* butc tape label */
+           vaLabel = va_arg(vaList, struct tc_tapeLabel *);
+
+           if (vaLabel) {
+               audit_ops->append_msg("TAPELABEL %d:%.*s:%.*s:%u ",
+                                     vaLabel->size,
+                                     TC_MAXTAPELEN, vaLabel->afsname,
+                                     TC_MAXTAPELEN, vaLabel->pname,
+                                     vaLabel->tapeId);
+           } else {
+               audit_ops->append_msg("TAPELABEL <null>");
+           }
+           break;
+       case AUD_TDI:
+           vaDI = va_arg(vaList, struct tc_dumpInterface *);
+
+           if (vaDI) {
+               audit_ops->append_msg(
+    "TCDUMPINTERFACE %.*s:%.*s:%.*s:%d:%d:%d:%d:%.*s:%.*s:%d:%d:%d:%d:%d ",
+    TC_MAXDUMPPATH, vaDI->dumpPath, TC_MAXNAMELEN, vaDI->volumeSetName,
+    TC_MAXNAMELEN, vaDI->dumpName, vaDI->parentDumpId, vaDI->dumpLevel,
+    vaDI->doAppend,
+    vaDI->tapeSet.id, TC_MAXHOSTLEN, vaDI->tapeSet.tapeServer,
+    TC_MAXFORMATLEN, vaDI->tapeSet.format, vaDI->tapeSet.maxTapes,
+    vaDI->tapeSet.a, vaDI->tapeSet.b, vaDI->tapeSet.expDate,
+    vaDI->tapeSet.expType);
+           } else {
+               audit_ops->append_msg("TCDUMPINTERFACE <null>");
+           }
+           break;
+       case AUD_TDA:
+           vaDA = va_arg(vaList, struct tc_dumpArray *);
+
+           if (vaDA) {
+               u_int i;
+               struct tc_dumpDesc *desc;
+               struct in_addr hostAddr;
+
+               desc = vaDA->tc_dumpArray_val;
+               if (desc) {
+                   audit_ops->append_msg("DUMPS %d ", vaDA->tc_dumpArray_len);
+                   for (i = 0; i < vaDA->tc_dumpArray_len; i++, desc++) {
+                       hostAddr.s_addr = desc->hostAddr;
+                       audit_ops->append_msg("DUMP %d:%d:%.*s:%d:%d:%d:%s ",
+                           desc->vid, desc->vtype, TC_MAXNAMELEN, desc->name,
+                           desc->partition, desc->date, desc->cloneDate,
+                           inet_ntoa(hostAddr));
+                   }
+               } else {
+                   audit_ops->append_msg("DUMPS 0 DUMP 0:0::0:0:0:0.0.0.0");
+               }
+           }
+           break;
+       case AUD_TRA:
+           vaRA = va_arg(vaList, struct tc_restoreArray *);
+
+           if (vaRA) {
+               u_int i;
+               struct tc_restoreDesc *desc;
+               struct in_addr hostAddr;
+
+               desc = vaRA->tc_restoreArray_val;
+               if (desc) {
+                   audit_ops->append_msg("RESTORES %d ",
+                                         vaRA->tc_restoreArray_len);
+                   for(i = 0; i < vaRA->tc_restoreArray_len; i++, desc++) {
+                       hostAddr.s_addr = desc->hostAddr;
+                       audit_ops->append_msg(
+                           "RESTORE %d:%.*s:%d:%d:%d:%d:%d:%d:%d:%s:%.*s:%.*s ",
+                           desc->flags, TC_MAXTAPELEN, desc->tapeName,
+                           desc->dbDumpId, desc->initialDumpId,
+                           desc->position, desc->origVid, desc->vid,
+                           desc->partition, desc->dumpLevel,
+                           inet_ntoa(hostAddr), TC_MAXNAMELEN,
+                           desc->oldName, TC_MAXNAMELEN, desc->newName);
+                   }
+               } else {
+                   audit_ops->append_msg(
+                       "RESTORES 0 RESTORE 0::0:0:0:0:0:0:0:0.0.0.0::: ");
+               }
+           }
+           break;
+       case AUD_TSTT:
+           vaTCstatus = va_arg(vaList, struct tciStatusS *);
+
+           if (vaTCstatus)
+               audit_ops->append_msg("TCSTATUS %.*s:%d:%d:%d:%d:%.*s:%d:%d ",
+                                     TC_MAXNAMELEN, vaTCstatus->taskName,
+                                     vaTCstatus->taskId, vaTCstatus->flags,
+                                     vaTCstatus->dbDumpId, vaTCstatus->nKBytes,
+                                     TC_MAXNAMELEN, vaTCstatus->volumeName,
+                                     vaTCstatus->volsFailed,
+                                     vaTCstatus->lastPolled);
+           else
+               audit_ops->append_msg("TCSTATUS <null>");
+           break;
        default:
            audit_ops->append_msg("--badval-- ");
            break;
@@ -292,7 +467,7 @@ static pthread_once_t audit_lock_once = PTHREAD_ONCE_INIT;
 static void
 osi_audit_init_lock(void)
 {
-    pthread_mutex_init(&audit_lock, NULL);
+    MUTEX_INIT(&audit_lock, "audit", MUTEX_DEFAULT, 0);
     audit_lock_initialized = 1;
 }
 #endif
@@ -321,14 +496,14 @@ osi_audit_internal(char *audEvent,        /* Event name (15 chars or less) */
     afs_int32 code;
     afs_int32 err;
     static char BUFFER[32768];
-#endif
     int result;
+#endif
 
 #ifdef AFS_PTHREAD_ENV
     /* i'm pretty sure all the server apps now call osi_audit_init(),
-     * but to be extra careful we'll leave this assert in here for a 
+     * but to be extra careful we'll leave this assert in here for a
      * while to make sure */
-    assert(audit_lock_initialized);
+    opr_Assert(audit_lock_initialized);
 #endif /* AFS_PTHREAD_ENV */
 
     if ((osi_audit_all < 0) || (osi_echo_trail < 0))
@@ -336,6 +511,7 @@ osi_audit_internal(char *audEvent,  /* Event name (15 chars or less) */
     if (!osi_audit_all && !auditout_open)
        return 0;
 
+#ifdef AFS_AIX32_ENV
     switch (errCode) {
     case 0:
        result = AUDIT_OK;
@@ -359,10 +535,9 @@ osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */
        result = AUDIT_FAIL;
        break;
     }
-
-#ifdef AFS_PTHREAD_ENV
-    pthread_mutex_lock(&audit_lock);
 #endif
+
+    MUTEX_ENTER(&audit_lock);
 #ifdef AFS_AIX32_ENV
     bufferPtr = BUFFER;
 
@@ -381,9 +556,7 @@ osi_audit_internal(char *audEvent,  /* Event name (15 chars or less) */
        printbuf(0, audEvent, afsName, hostId, errCode, vaList);
     }
 #endif
-#ifdef AFS_PTHREAD_ENV
-    pthread_mutex_unlock(&audit_lock);
-#endif
+    MUTEX_EXIT(&audit_lock);
 
     return 0;
 }
@@ -407,7 +580,7 @@ osi_audit(char *audEvent,   /* Event name (15 chars or less) */
 }
 
 /* ************************************************************************** */
-/* Given a RPC call structure, this routine extracts the name and host id from the 
+/* Given a RPC call structure, this routine extracts the name and host id from the
  * call and includes it within the audit information.
  * ************************************************************************** */
 int
@@ -417,7 +590,7 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
     struct rx_peer *peer;
     afs_int32 secClass;
     afs_int32 code;
-    char afsName[MAXKTCNAMELEN];
+    char afsName[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
     afs_int32 hostId;
     va_list vaList;
 
@@ -433,15 +606,14 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
        conn = rx_ConnectionOf(call);   /* call -> conn) */
        if (conn) {
             secClass = rx_SecurityClassOf(conn);       /* conn -> securityIndex */
-           if (secClass == 0) {        /* unauthenticated */
+           if (secClass == RX_SECIDX_NULL) {   /* unauthenticated */
                osi_audit("AFS_Aud_Unauth", (-1), AUD_STR, audEvent, AUD_END);
                strcpy(afsName, "--UnAuth--");
-           } else if (secClass == 2) { /* authenticated */
+           } else if (secClass == RX_SECIDX_KAD || secClass == RX_SECIDX_KAE) {
+               /* authenticated with rxkad */
                 char tcell[MAXKTCREALMLEN];
                 char name[MAXKTCNAMELEN];
                 char inst[MAXKTCNAMELEN];
-                char vname[256];
-                int  ilen, clen;
 
                 code =
                    rxkad_GetServerInfo(conn, NULL, NULL, name, inst, tcell,
@@ -450,66 +622,26 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
                    osi_audit("AFS_Aud_NoAFSId", (-1), AUD_STR, audEvent, AUD_END);
                    strcpy(afsName, "--NoName--");
                } else {
-                    strncpy(vname, name, sizeof(vname));
-                    if ((ilen = strlen(inst))) {
-                        if (strlen(vname) + 1 + ilen >= sizeof(vname))
-                            goto done;
-                        strcat(vname, ".");
-                        strcat(vname, inst);
-                    }
-                    if ((clen = strlen(tcell))) {
-#if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-                        static char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
-                       static int  num_lrealms = -1;
-                       int i, lrealm_match;
-
-                       if (num_lrealms == -1) {
-                           for (i = 0; i < AFS_NUM_LREALMS; i++) {
-                               if (afs_krb_get_lrealm(local_realms[i], i) != 0 /*KSUCCESS*/)
-                                   break;
-                           }
-
-                           if (i == 0)
-                               strncpy(local_realms[0], "UNKNOWN.LOCAL.REALM", AFS_REALM_SZ);
-                           num_lrealms = i;
-                        }
-
-                       /* Check to see if the ticket cell matches one of the local realms */
-                       lrealm_match = 0;
-                       for (i = 0; i < num_lrealms ; i++ ) {
-                           if (!strcasecmp(local_realms[i], tcell)) {
-                               lrealm_match = 1;
-                               break;
-                           }
-                       }
-                       /* If yes, then make sure that the name is not present in 
-                        * an exclusion list */
-                       if (lrealm_match) {
-                           char uname[256];
-                           if (inst[0])
-                               snprintf(uname,sizeof(uname),"%s.%s@%s",name,inst,tcell);
-                           else
-                               snprintf(uname,sizeof(uname),"%s@%s",name,tcell);
-
-                           if (afs_krb_exclusion(uname))
-                               lrealm_match = 0;
-                       }
-
-                       if (!lrealm_match) {    
-                            if (strlen(vname) + 1 + clen >= sizeof(vname))
-                                goto done;
-                            strcat(vname, "@");
-                            strcat(vname, tcell);
-                        }
-#endif
-                    }
-                    strcpy(afsName, vname);
-                }
-           } else {            /* Unauthenticated & unknown */
+                   afs_int32 islocal = 0;
+                   if (audit_user_check.islocal) {
+                       islocal =
+                           audit_user_check.islocal(audit_user_check.rock,
+                                                    name, inst, tcell);
+                   }
+                   strlcpy(afsName, name, sizeof(afsName));
+                   if (inst[0]) {
+                       strlcat(afsName, ".", sizeof(afsName));
+                       strlcat(afsName, inst, sizeof(afsName));
+                   }
+                   if (tcell[0] && !islocal) {
+                       strlcat(afsName, "@", sizeof(afsName));
+                       strlcat(afsName, tcell, sizeof(afsName));
+                   }
+               }
+           } else {            /* Unauthenticated and/or unknown */
                osi_audit("AFS_Aud_UnknSec", (-1), AUD_STR, audEvent, AUD_END);
                 strcpy(afsName, "--Unknown--");
            }
-       done:
            peer = rx_PeerOf(conn);     /* conn -> peer */
            if (peer)
                hostId = rx_HostOf(peer);       /* peer -> host */
@@ -529,7 +661,7 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
 
 /* ************************************************************************** */
 /* Determines whether auditing is on or off by looking at the Audit file.
- * If the string AFS_AUDIT_AllEvents is defined in the file, then auditing will be 
+ * If the string AFS_AUDIT_AllEvents is defined in the file, then auditing will be
  * enabled.
  * ************************************************************************** */
 
@@ -594,6 +726,15 @@ osi_audit_interface(const char *interface)
 }
 
 void
+osi_audit_set_user_check(void *rock,
+                        int (*islocal) (void *rock, char *name, char *inst,
+                                        char *cell))
+{
+    audit_user_check.rock = rock;
+    audit_user_check.islocal = islocal;
+}
+
+void
 audit_PrintStats(FILE *out)
 {
     audit_ops->print_interface_stats(out);