Index: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	(revision 263)
+++ trunk/Makefile.in	(revision 264)
@@ -1660,5 +1660,5 @@
 
 samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
-sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
+sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
 sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
Index: trunk/depend.dep
===================================================================
--- trunk/depend.dep	(revision 263)
+++ trunk/depend.dep	(revision 264)
@@ -2,5 +2,5 @@
 # DO NOT DELETE THIS LINE
 samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
-sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
+sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
 sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
Index: trunk/depend.sum
===================================================================
--- trunk/depend.sum	(revision 263)
+++ trunk/depend.sum	(revision 264)
@@ -1,1 +1,1 @@
-2976518268
+188553029
Index: trunk/include/sh_unix.h
===================================================================
--- trunk/include/sh_unix.h	(revision 263)
+++ trunk/include/sh_unix.h	(revision 264)
@@ -156,4 +156,8 @@
 extern int sh_unix_check_acl;
 
+/* destroy userid cache 
+ */
+void sh_userid_destroy ();
+
 /* --- run a command, securely --- 
  */
Index: trunk/src/samhain.c
===================================================================
--- trunk/src/samhain.c	(revision 263)
+++ trunk/src/samhain.c	(revision 264)
@@ -2168,4 +2168,8 @@
 	continue;
       
+      /* reset cache
+       */
+      sh_userid_destroy();
+
       /* go to sleep
        */
Index: trunk/src/sh_forward.c
===================================================================
--- trunk/src/sh_forward.c	(revision 263)
+++ trunk/src/sh_forward.c	(revision 264)
@@ -5380,4 +5380,6 @@
 	  tchkold = tcurrent;
 	  client_time_check(/* all_clients */);
+	  /* reset cache */
+	  sh_userid_destroy();
 	}
       
Index: trunk/src/sh_socket.c
===================================================================
--- trunk/src/sh_socket.c	(revision 263)
+++ trunk/src/sh_socket.c	(revision 264)
@@ -384,4 +384,5 @@
       sl_strlcat(sh_sockname, _(".sock"), size);
     }
+
 
   pf_unix_fd = socket (PF_UNIX, SOCK_STREAM, 0);
Index: trunk/src/sh_unix.c
===================================================================
--- trunk/src/sh_unix.c	(revision 263)
+++ trunk/src/sh_unix.c	(revision 264)
@@ -1499,6 +1499,9 @@
 #endif
   int  test;
-  struct sigaction act, oldact;
   int  status;
+  struct sigaction act;
+#if !defined(SH_PROFILE)
+  struct sigaction oldact;
+#endif
 
   sigset_t set_proc;
@@ -2480,4 +2483,5 @@
   struct passwd * tempres;
   int    status = 0;
+
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
   struct passwd pwd;
@@ -2524,6 +2528,129 @@
 }
 
-SH_MUTEX_STATIC(mutex_getUIDname, PTHREAD_MUTEX_INITIALIZER);
-
+/* ------------------- Caching ----------------*/
+#include "zAVLTree.h"
+
+#define CACHE_GID 0
+#define CACHE_UID 1
+
+struct user_id {
+  char  * name;
+  uid_t   id;
+  struct user_id * next;
+};
+
+static struct user_id  * uid_list = NULL;
+static struct user_id  * gid_list = NULL;
+
+SH_MUTEX_STATIC(mutex_cache, PTHREAD_MUTEX_INITIALIZER);
+
+static void sh_userid_free(struct user_id * item)
+{
+  while (item)
+    {
+      struct user_id * user = item;
+      item = item->next;
+
+      SH_FREE(user->name);
+      SH_FREE(user);
+    }
+  return;
+}
+
+void sh_userid_destroy ()
+{
+  struct user_id * tmp_uid;
+  struct user_id * tmp_gid;
+
+  SH_MUTEX_LOCK_UNSAFE(mutex_cache);
+  tmp_gid  = gid_list;
+  gid_list = NULL;
+  tmp_uid  = uid_list;
+  uid_list = NULL;
+  SH_MUTEX_UNLOCK_UNSAFE(mutex_cache);
+
+  sh_userid_free(tmp_uid);
+  sh_userid_free(tmp_gid);
+  return;
+}
+
+static void sh_userid_additem(struct user_id * list, struct user_id * item)
+{
+  while (list && list->next)
+    list = list->next;
+  list->next = item;
+  return;
+}
+
+static void sh_userid_add(uid_t id, char * username, int which)
+{
+  size_t len;
+  struct user_id * user = SH_ALLOC(sizeof(struct user_id));
+
+  if (username)
+    len  = strlen(username) + 1;
+  else
+    len = 1;
+
+  user->name = SH_ALLOC(len);
+  user->id   = id;
+  if (username)
+    sl_strlcpy(user->name, username, len);
+  else
+    user->name[0] = '\0';
+  user->next = NULL;
+
+  SH_MUTEX_LOCK(mutex_cache);
+  if (which == CACHE_UID)
+    {
+      if (!uid_list)
+	uid_list = user;
+      else
+	sh_userid_additem(uid_list, user);
+    }
+  else
+    {
+      if (!gid_list)
+	gid_list = user;
+      else
+	sh_userid_additem(gid_list, user);
+    }
+  SH_MUTEX_UNLOCK(mutex_cache);
+
+  return;
+}
+
+static char * sh_userid_search(struct user_id * list, uid_t id)
+{
+  while (list)
+    {
+      if (list->id == id)
+	return list->name;
+      list = list->next;
+    }
+  return NULL;
+}
+
+static char * sh_userid_get (uid_t id, int which, char * out, size_t len)
+{
+  char * user = NULL;
+
+  SH_MUTEX_LOCK_UNSAFE(mutex_cache);
+  if (which == CACHE_UID)
+    user = sh_userid_search(uid_list, id);
+  else
+    user = sh_userid_search(gid_list, id);
+  if (user)
+    {
+      sl_strlcpy(out, user, len);
+      user = out;
+    }
+  SH_MUTEX_UNLOCK_UNSAFE(mutex_cache);
+
+  return user;
+}
+
+/* --------- end caching code --------- */
+  
 char *  sh_unix_getUIDname (int level, uid_t uid, char * out, size_t len)
 {
@@ -2534,20 +2661,22 @@
 #endif
   int             status = 0;
-  static uid_t    old_uid;
-  static char     name[32] = { '\0' };
   char errbuf[SH_ERRBUF_SIZE];
+  char * tmp;
 
   SL_ENTER(_("sh_unix_getUIDname"));
 
-  if ((uid == old_uid) && (name[0] != '\0')) {
-    out[0] = '\0';
-    SH_MUTEX_LOCK_UNSAFE(mutex_getUIDname);
-    if ((uid == old_uid) && (name[0] != '\0')) {
-      sl_strlcpy(out, name, len);
-    }
-    SH_MUTEX_UNLOCK_UNSAFE(mutex_getUIDname);
-    if (out[0] != '\0')
-      SL_RETURN( out, _("sh_unix_getUIDname"));
-  }
+  tmp = sh_userid_get(uid, CACHE_UID, out, len);
+
+  if (tmp)
+    {
+      if (tmp[0] != '\0')
+	{
+	  SL_RETURN( out, _("sh_unix_getUIDname"));
+	}
+      else
+	{
+	  SL_RETURN( NULL, _("sh_unix_getUIDname"));
+	}
+    }
 
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
@@ -2560,37 +2689,41 @@
 #endif
  
-  if (tempres == NULL) {
-    sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_PWNULL,
-		     sh_error_message(status, errbuf, sizeof(errbuf)),
-		     _("getpwuid"), (long) uid, _("completely missing"));
+  if (tempres == NULL) 
+    {
+      sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_PWNULL,
+		       sh_error_message(status, errbuf, sizeof(errbuf)),
+		       _("getpwuid"), (long) uid, _("completely missing"));
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( NULL, _("sh_unix_getUIDname"));
-  }
-
-
-  if (tempres->pw_name != NULL) {
-    SH_MUTEX_LOCK_UNSAFE(mutex_getUIDname);
-    sl_strlcpy(name, tempres->pw_name, sizeof(name));
-    old_uid = uid;
-    sl_strlcpy(out, name, len);
-    SH_MUTEX_UNLOCK_UNSAFE(mutex_getUIDname);
+      SH_FREE(buffer);
+#endif
+      sh_userid_add(uid, NULL, CACHE_UID);
+      SL_RETURN( NULL, _("sh_unix_getUIDname"));
+    }
+
+
+  if (tempres->pw_name != NULL) 
+    {
+
+      sl_strlcpy(out, tempres->pw_name, len);
+      sh_userid_add(uid, out, CACHE_UID);
+      
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( out, _("sh_unix_getUIDname"));
-  } else {
-    sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_PWNULL,
-		     sh_error_message(status, errbuf, sizeof(errbuf)),
-		     _("getpwuid"), (long) uid, _("pw_user"));
+      SH_FREE(buffer);
+#endif
+
+      SL_RETURN( out, _("sh_unix_getUIDname"));
+    } 
+  else 
+    {
+      sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_PWNULL,
+		       sh_error_message(status, errbuf, sizeof(errbuf)),
+		       _("getpwuid"), (long) uid, _("pw_user"));
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( NULL, _("sh_unix_getUIDname"));
-  }
-}
-
-SH_MUTEX_STATIC(mutex_getGIDname, PTHREAD_MUTEX_INITIALIZER);
+      SH_FREE(buffer);
+#endif
+      SL_RETURN( NULL, _("sh_unix_getUIDname"));
+    }
+  /* notreached */
+}
 
 char *  sh_unix_getGIDname (int level, gid_t gid, char * out, size_t len)
@@ -2598,6 +2731,5 @@
   struct group  * tempres;
   int             status = 0;
-  static gid_t    old_gid;
-  static char     name[32] = { '\0' };
+
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
   struct group    grp;
@@ -2605,18 +2737,21 @@
 #endif
   char errbuf[SH_ERRBUF_SIZE];
+  char * tmp;
   
-
   SL_ENTER(_("sh_unix_getGIDname"));
 
-  if ((gid == old_gid) && (name[0] != '\0')) {
-    out[0] = '\0';
-    SH_MUTEX_LOCK_UNSAFE(mutex_getGIDname);
-    if ((gid == old_gid) && (name[0] != '\0')) {
-      sl_strlcpy(out, name, len);
-    }
-    SH_MUTEX_UNLOCK_UNSAFE(mutex_getGIDname);
-    if (out[0] != '\0')
-      SL_RETURN( out, _("sh_unix_getGIDname"));
-  }
+  tmp = sh_userid_get((uid_t)gid, CACHE_GID, out, len);
+
+  if (tmp)
+    {
+      if (tmp[0] != '\0')
+	{
+	  SL_RETURN( out, _("sh_unix_getGIDname"));
+	}
+      else
+	{
+	  SL_RETURN( NULL, _("sh_unix_getGIDname"));
+	}
+    }
 
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
@@ -2629,34 +2764,43 @@
 #endif
 
-  if (tempres == NULL) {
-    sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_GRNULL,
-		     sh_error_message(status, errbuf, sizeof(errbuf)),
-		     _("getgrgid"), (long) gid, _("completely missing"));
+  if (tempres == NULL) 
+    {
+      sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_GRNULL,
+		       sh_error_message(status, errbuf, sizeof(errbuf)),
+		       _("getgrgid"), (long) gid, _("completely missing"));
       
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( NULL, _("sh_unix_getGIDname"));
-  }
-
-  if (tempres->gr_name != NULL) {
-    SH_MUTEX_LOCK_UNSAFE(mutex_getGIDname);
-    sl_strlcpy(name, tempres->gr_name, sizeof(name));
-    old_gid = gid;
-    sl_strlcpy(out, name, len);
-    SH_MUTEX_UNLOCK_UNSAFE(mutex_getGIDname);
+      SH_FREE(buffer);
+#endif
+
+      sh_userid_add(gid, NULL, CACHE_GID);
+      SL_RETURN( NULL, _("sh_unix_getGIDname"));
+    }
+
+  if (tempres->gr_name != NULL) 
+    {
+
+      sl_strlcpy(out, tempres->gr_name, len);
+      sh_userid_add((uid_t)gid, out, CACHE_GID);
+      
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( out, _("sh_unix_getGIDname"));
-  } else {
-    sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_GRNULL,
-		     sh_error_message(status, errbuf, sizeof(errbuf)),
-		     _("getgrgid"), (long) gid, _("gr_name"));
+      SH_FREE(buffer);
+#endif
+
+      SL_RETURN( out, _("sh_unix_getGIDname"));
+    } 
+  else 
+    {
+      sh_error_handle (level, FIL__, __LINE__, EINVAL, MSG_E_GRNULL,
+		       sh_error_message(status, errbuf, sizeof(errbuf)),
+		       _("getgrgid"), (long) gid, _("gr_name"));
+
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
-    SH_FREE(buffer);
-#endif
-    SL_RETURN( NULL, _("sh_unix_getGIDname"));
-  }
+      SH_FREE(buffer);
+#endif
+
+      SL_RETURN( NULL, _("sh_unix_getGIDname"));
+    }
+  /* notreached */
 }
 
