osi-audit-locking-fix-20060201
[openafs.git] / src / audit / audit.c
index aeea185..440e423 100644 (file)
@@ -257,15 +257,25 @@ printbuf(FILE *out, int rec, char *audEvent, afs_int32 errCode, va_list vaList)
        fprintf(out, "\n");
 }
 
-static struct Lock audlock;
-static afs_int32   lock_init = 0;
+#ifdef AFS_PTHREAD_ENV
+static pthread_mutex_t audit_lock;
+static volatile afs_int32   audit_lock_initialized = 0;
+static pthread_once_t audit_lock_once = PTHREAD_ONCE_INIT;
+
+static void
+osi_audit_init_lock(void)
+{
+    pthread_mutex_init(&audit_lock, NULL);
+    audit_lock_initialized = 1;
+}
+#endif
+
 void
 osi_audit_init(void)
 {
 #ifdef AFS_PTHREAD_ENV
-    if ( !lock_init ) {
-       Lock_Init(&audlock);
-       lock_init = 1;
+    if (!audit_lock_initialized) {
+       pthread_once(&audit_lock_once, osi_audit_init_lock);
     }
 #endif /* AFS_PTHREAD_ENV */
 }
@@ -287,11 +297,10 @@ osi_audit(char *audEvent, /* Event name (15 chars or less) */
     va_list vaList;
 
 #ifdef AFS_PTHREAD_ENV
-    /* This is not thread safe.   Lock initialization should 
-     * be done in a server initialization phase
-     */
-    if ( !lock_init )
-       osi_audit_init();
+    /* 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 
+     * while to make sure */
+    assert(audit_lock_initialized);
 #endif /* AFS_PTHREAD_ENV */
 
     if ((osi_audit_all < 0) || (osi_echo_trail < 0))
@@ -324,7 +333,7 @@ osi_audit(char *audEvent,   /* Event name (15 chars or less) */
     }
 
 #ifdef AFS_PTHREAD_ENV
-    ObtainWriteLock(&audlock);
+    pthread_mutex_lock(&audit_lock);
 #endif
 #ifdef AFS_AIX32_ENV
     bufferPtr = BUFFER;
@@ -361,7 +370,7 @@ osi_audit(char *audEvent,   /* Event name (15 chars or less) */
     }
 #endif
 #ifdef AFS_PTHREAD_ENV
-    ReleaseWriteLock(&audlock);
+    pthread_mutex_unlock(&audit_lock);
 #endif
 
     return 0;
@@ -420,12 +429,43 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
                     }
                     if ((clen = strlen(tcell))) {
 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-                        static char local_realm[AFS_REALM_SZ] = "";
-                        if (!local_realm[0]) {
-                            if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
-                                strncpy(local_realm, "UNKNOWN.LOCAL.REALM", AFS_REALM_SZ);
+                        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;
                         }
-                        if (strcasecmp(local_realm, tcell)) {
+
+                       /* 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, "@");