Index: pvfs2_src/configure.in
===================================================================
--- pvfs2_src/configure.in	(revision 13184)
+++ pvfs2_src/configure.in	(revision 13185)
@@ -44,6 +44,8 @@
 
 AC_CONFIG_HEADER(pvfs2-config.h)
 
+AC_CHECK_HEADER([pwd.h],
+    [AC_DEFINE(HAVE_GETPWUID, 1, Define if pwd.h exists)])
 AC_CHECK_HEADER([sys/vfs.h],
 		[AC_DEFINE(HAVE_SYS_VFS_H, 1, Define if sys/vfs.h exists)])
 AC_CHECK_HEADER([sys/mount.h],
Index: pvfs2_src/src/server/check.c
===================================================================
--- pvfs2_src/src/server/check.c	(revision 13184)
+++ pvfs2_src/src/server/check.c	(revision 13185)
@@ -197,6 +197,7 @@
  */
 static int PINT_check_group(uid_t uid, gid_t gid)
 {
+#ifdef HAVE_GETPWUID
     struct passwd pwd;
     struct passwd* pwd_p = NULL;
     struct group grp;
@@ -280,6 +281,9 @@
 
     gen_mutex_unlock(&check_group_mutex);
     return(-PVFS_ENOENT);
+#else
+    return 0
+#endif
 }
 
 /* Checks if a given user is part of any groups that matches the file gid */
Index: pvfs2_src/pvfs2-config.h.in
===================================================================
--- pvfs2_src/pvfs2-config.h.in	(revision 13184)
+++ pvfs2_src/pvfs2-config.h.in	(revision 13185)
@@ -372,6 +372,9 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
+/* Define if pwd.h exists */
+#undef HAVE_GETPWUID
+
 /* Define if sys/vfs.h exists */
 #undef HAVE_SYS_VFS_H
 
Index: pvfs2_src/src/server/check.c
===================================================================
--- pvfs2_src/src/server/check.c	(revision 13261)
+++ pvfs2_src/src/server/check.c	(revision 13262)
@@ -282,7 +282,7 @@
     gen_mutex_unlock(&check_group_mutex);
     return(-PVFS_ENOENT);
 #else
-    return 0
+    return 0;
 #endif
 }
 
Index: pvfs2_src/src/server/check.c
===================================================================
--- pvfs2_src/src/server/check.c	(revision 13267)
+++ pvfs2_src/src/server/check.c	(revision 13268)
@@ -1,433 +0,0 @@
-/*
- * (C) 2001 Clemson University and The University of Chicago
- *
- * Changes by Acxiom Corporation to add PINT_check_mode() helper function
- * as a replacement for check_mode() in permission checking, also added
- * PINT_check_group() for supplimental group support 
- * Copyright © Acxiom Corporation, 2005.
- *
- * See COPYING in top-level directory.
- */
-
-/*
- * Server-specific utility functions, to check modes and ACLs.
- */
-#include <string.h>
-#include <assert.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include "pvfs2-debug.h"
-#include "gen-locks.h"
-#include "gossip.h"
-#include "bmi-byteswap.h"
-#include "check.h"
-
-static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
-static int pw_buf_size = 1024;      // 1 KB
-static int gr_buf_size = 1024*1024; // 1 MB
-static char* check_group_pw_buffer = NULL;
-static char* check_group_gr_buffer = NULL;
-static int PINT_check_group(uid_t uid, gid_t gid);
-
-/* PINT_check_mode()
- *
- * checks to see if the type of access described by "access_type" is permitted 
- * for user "uid" of group "gid" on the object with attributes "attr"
- *
- * returns 0 on success, -PVFS_EACCES if permission is not granted
- */
-int PINT_check_mode(
-    PVFS_object_attr *attr,
-    PVFS_uid uid, PVFS_gid gid,
-    enum PINT_access_type access_type)
-{
-    int in_group_flag = 0;
-    int ret = 0;
-
-    /* if we don't have masks for the permission information that we
-     * need, then the system is broken
-     */
-    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
-           attr->mask & PVFS_ATTR_COMMON_GID &&
-           attr->mask & PVFS_ATTR_COMMON_PERM);
-
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - check_mode called --- "
-                 "(uid=%d,gid=%d,access_type=%d)\n", uid, gid, access_type);
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - object attributes --- "
-                 "(uid=%d,gid=%d,mode=%d)\n", attr->owner, attr->group,
-                 attr->perms);
-
-    /* give root permission, no matter what */
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG,
-                 " - checking if uid (%d) is root ...\n", uid);
-    if (uid == 0)
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        return 0;
-    }
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-
-    /* see if uid matches object owner */
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if owner (%d) "
-        "matches uid (%d)...\n", attr->owner, uid);
-    if(attr->owner == uid)
-    {
-        /* see if object user permissions match access type */
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
-            "(%d) allows access type (%d) for user...\n", attr->perms, access_type);
-        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
-            PVFS_U_READ))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
-            PVFS_U_WRITE))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
-            PVFS_U_EXECUTE))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-    }
-    else
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-    }
-
-    /* see if other bits allow access */
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
-        "(%d) allows access type (%d) by others...\n", attr->perms, access_type);
-    if(access_type == PINT_ACCESS_READABLE && (attr->perms &
-        PVFS_O_READ))
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        return(0);
-    }
-    if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
-        PVFS_O_WRITE))
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        return(0);
-    }
-    if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
-        PVFS_O_EXECUTE))
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        return(0);
-    }
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-
-    /* see if gid matches object group */
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if group (%d) "
-        "matches gid (%d)...\n", attr->group, gid);
-    if(attr->group == gid)
-    {
-        /* default group match */
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-        in_group_flag = 1;
-    }
-    else
-    {
-        /* no default group match, check supplementary groups */
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking for"
-            " supplementary group match...\n");
-        ret = PINT_check_group(uid, attr->group);
-        if(ret == 0)
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            in_group_flag = 1;
-        }
-        else
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-            if(ret != -PVFS_ENOENT)
-            {
-                /* system error; not just failed match */
-                return(ret);
-            }
-        }
-    }
-
-    if(in_group_flag)
-    {
-        /* see if object group permissions match access type */
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
-            "(%d) allows access type (%d) for group...\n", attr->perms, access_type);
-        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
-            PVFS_G_READ))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
-            PVFS_G_WRITE))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
-            PVFS_G_EXECUTE))
-        {
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
-            return(0);
-        }
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
-    }
-  
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "******PINT_check_mode: denying access\n");
-    /* default case: access denied */
-    return -PVFS_EACCES;
-}
-
-/* PINT_check_group()
- *
- * checks to see if uid is a member of gid
- * 
- * returns 0 on success, -PVFS_ENOENT if not a member, other PVFS error codes
- * on system failure
- */
-static int PINT_check_group(uid_t uid, gid_t gid)
-{
-#ifdef HAVE_GETPWUID
-    struct passwd pwd;
-    struct passwd* pwd_p = NULL;
-    struct group grp;
-    struct group* grp_p = NULL;
-    int i = 0;
-    int ret = -1;
-
-    /* Explanation: 
-     *
-     * We use the _r variants of getpwuid and getgrgid in order to insure
-     * thread safety; particularly if this function ever gets called in a
-     * client side situation in which we can't prevent the application from
-     * making conflicting calls.
-     *
-     * These _r functions require that a buffer be supplied for the user and
-     * group information, however.  These buffers may be unconfortably large
-     * for the stack, so we malloc them on a static pointer and then mutex
-     * lock this function so that it can still be reentrant.
-     */
-
-    gen_mutex_lock(&check_group_mutex);
-
-    if(!check_group_pw_buffer)
-    {
-        check_group_pw_buffer = (char*)malloc(pw_buf_size);
-        check_group_gr_buffer = (char*)malloc(gr_buf_size);
-        if(!check_group_pw_buffer || !check_group_gr_buffer)
-        {
-            if(check_group_pw_buffer)
-            {
-                free(check_group_pw_buffer);
-                check_group_pw_buffer = NULL;
-            }
-            if(check_group_gr_buffer)
-            {
-                free(check_group_gr_buffer);
-                check_group_gr_buffer = NULL;
-            }
-            gen_mutex_unlock(&check_group_mutex);
-            return(-PVFS_ENOMEM);
-        }
-    }
-
-    /* get user information */
-    ret = getpwuid_r(uid, &pwd, check_group_pw_buffer, pw_buf_size, &pwd_p);
-    if(ret != 0 || pwd_p == NULL)
-    {
-        gen_mutex_unlock(&check_group_mutex);
-        gossip_err("Get user info for (uid=%d) failed."
-                   "errno [%d] error_msg [%s]\n",
-                   uid, ret, strerror(ret));
-        return(-PVFS_EINVAL);
-    }
-
-    /* check primary group */
-    if(pwd.pw_gid == gid)
-    {
-        gen_mutex_unlock(&check_group_mutex);
-        return 0;
-    }
-
-    /* get the members of the group */
-    ret = getgrgid_r(gid, &grp, check_group_gr_buffer, gr_buf_size, &grp_p);
-    if(ret != 0 || grp_p == NULL)
-    {
-      gen_mutex_unlock(&check_group_mutex);
-      gossip_err("Get members for group (gid=%d) failed."
-                 "errno [%d] error_msg [%s]\n",
-                 gid, ret, strerror(ret));
-      return(-PVFS_EINVAL);
-    }
-
-    for(i = 0; grp.gr_mem[i] != NULL; i++)
-    {
-        if(0 == strcmp(pwd.pw_name, grp.gr_mem[i]))
-        {
-            gen_mutex_unlock(&check_group_mutex);
-            return 0;
-        } 
-    }
-
-    gen_mutex_unlock(&check_group_mutex);
-    return(-PVFS_ENOENT);
-#else
-    return 0;
-#endif
-}
-
-/* Checks if a given user is part of any groups that matches the file gid */
-static int in_group_p(PVFS_uid uid, PVFS_gid gid, PVFS_gid attr_group)
-{
-    if (attr_group == gid)
-        return 1;
-    if (PINT_check_group(uid, attr_group) == 0)
-        return 1;
-    return 0;
-}
-
-/*
- * Return 0 if requesting clients is granted want access to the object
- * by the acl. Returns -PVFS_E... otherwise.
- */
-int PINT_check_acls(void *acl_buf, size_t acl_size, 
-    PVFS_object_attr *attr,
-    PVFS_uid uid, PVFS_gid gid, int want)
-{
-    pvfs2_acl_entry pe, *pa;
-    int i = 0, found = 0, count = 0;
-    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
-           attr->mask & PVFS_ATTR_COMMON_GID &&
-           attr->mask & PVFS_ATTR_COMMON_PERM);
-
-    if (acl_size == 0)
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "no acl's present.. denying access\n");
-        return -PVFS_EACCES;
-    }
-
-    /* keyval for ACLs includes a \0. so subtract the thingie */
-    acl_size--;
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "PINT_check_acls: read keyval size "
-    " %d (%d acl entries)\n",
-        (int) acl_size, 
-        (int) (acl_size / sizeof(pvfs2_acl_entry)));
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "uid = %d, gid = %d, want = %d\n",
-        uid, gid, want);
-
-    assert(acl_buf);
-    /* if the acl format doesn't look valid, then return an error rather than
-     * asserting; we don't want the server to crash due to an invalid keyval
-     */
-    if((acl_size % sizeof(pvfs2_acl_entry)) != 0)
-    {
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "invalid acls on object\n");
-        return(-PVFS_EACCES);
-    }
-    count = acl_size / sizeof(pvfs2_acl_entry);
-
-    for (i = 0; i < count; i++)
-    {
-        pa = (pvfs2_acl_entry *) acl_buf + i;
-        /* 
-           NOTE: Remember that keyval is encoded as lebf, so convert it 
-           to host representation 
-        */
-        pe.p_tag  = bmitoh32(pa->p_tag);
-        pe.p_perm = bmitoh32(pa->p_perm);
-        pe.p_id   = bmitoh32(pa->p_id);
-        pa = &pe;
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded ACL entry %d "
-            "(p_tag %d, p_perm %d, p_id %d)\n",
-            i, pa->p_tag, pa->p_perm, pa->p_id);
-        switch(pa->p_tag) 
-        {
-            case PVFS2_ACL_USER_OBJ:
-                /* (May have been checked already) */
-                if (attr->owner == uid)
-                    goto check_perm;
-                break;
-            case PVFS2_ACL_USER:
-                if (pa->p_id == uid)
-                    goto mask;
-                break;
-            case PVFS2_ACL_GROUP_OBJ:
-                if (in_group_p(uid, gid, attr->group)) 
-                {
-                    found = 1;
-                    if ((pa->p_perm & want) == want)
-                        goto mask;
-                }
-                break;
-            case PVFS2_ACL_GROUP:
-                if (in_group_p(uid, gid, pa->p_id)) {
-                    found = 1;
-                    if ((pa->p_perm & want) == want)
-                        goto mask;
-                }
-                break;
-            case PVFS2_ACL_MASK:
-                break;
-            case PVFS2_ACL_OTHER:
-                if (found)
-                {
-                    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(1) PINT_check_acls:"
-                        "returning access denied\n");
-                    return -PVFS_EACCES;
-                }
-                else
-                    goto check_perm;
-            default:
-                gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(2) PINT_check_acls: "
-                        "returning EIO\n");
-                return -PVFS_EIO;
-        }
-    }
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(3) PINT_check_acls: returning EIO\n");
-    return -PVFS_EIO;
-mask:
-    /* search the remaining entries */
-    i = i + 1;
-    for (; i < count; i++)
-    {
-        pvfs2_acl_entry me, *mask_obj = (pvfs2_acl_entry *) acl_buf + i;
-        
-        /* 
-          NOTE: Again, since pvfs2_acl_entry is in lebf, we need to
-          convert it to host endian format
-         */
-        me.p_tag  = bmitoh32(mask_obj->p_tag);
-        me.p_perm = bmitoh32(mask_obj->p_perm);
-        me.p_id   = bmitoh32(mask_obj->p_id);
-        mask_obj = &me;
-        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded (mask) ACL entry %d "
-            "(p_tag %d, p_perm %d, p_id %d)\n",
-            i, mask_obj->p_tag, mask_obj->p_perm, mask_obj->p_id);
-        if (mask_obj->p_tag == PVFS2_ACL_MASK) 
-        {
-            if ((pa->p_perm & mask_obj->p_perm & want) == want)
-                return 0;
-            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(4) PINT_check_acls:"
-                "returning access denied (mask)\n");
-            return -PVFS_EACCES;
-        }
-    }
-
-check_perm:
-    if ((pa->p_perm & want) == want)
-        return 0;
-    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(5) PINT_check_acls: returning"
-            "access denied\n");
-    return -PVFS_EACCES;
-}
-
Index: pvfs2_src/src/server/check.h
===================================================================
--- pvfs2_src/src/server/check.h	(revision 13267)
+++ pvfs2_src/src/server/check.h	(revision 13268)
@@ -1,25 +0,0 @@
-
-#ifndef __CHECK_H
-#define __CHECK_H
-
-#include "pvfs2-types.h"
-#include "pvfs2-attr.h"
-
-enum PINT_access_type
-{
-    PINT_ACCESS_EXECUTABLE = 1,
-    PINT_ACCESS_WRITABLE = 2,
-    PINT_ACCESS_READABLE = 4,
-};
-
-int PINT_check_mode(
-    PVFS_object_attr *attr,
-    PVFS_uid uid, PVFS_gid gid,
-    enum PINT_access_type access_type);
-
-int PINT_check_acls(void *acl_buf, size_t acl_size, 
-    PVFS_object_attr *attr,
-    PVFS_uid uid, PVFS_gid gid, int want);
-
-#endif  /* __CHECK_H */
-
Index: pvfs2_src/src/server/lookup.sm
===================================================================
--- pvfs2_src/src/server/lookup.sm	(revision 13267)
+++ pvfs2_src/src/server/lookup.sm	(revision 13268)
@@ -19,7 +19,6 @@
 #include "str-utils.h"
 #include "pint-util.h"
 #include "pvfs2-internal.h"
-#include "check.h"
 
 enum 
 {
Index: pvfs2_src/src/server/module.mk.in
===================================================================
--- pvfs2_src/src/server/module.mk.in	(revision 13267)
+++ pvfs2_src/src/server/module.mk.in	(revision 13268)
@@ -49,9 +49,6 @@
 	SERVERSRC += \
 		$(SERVER_SMCGEN)
 
-	# server only file
-	SERVERSRC += $(DIR)/check.c
-
 	# track generate .c files to remove during dist clean, etc. 
 		SMCGEN += $(SERVER_SMCGEN)
 
Index: pvfs2_src/src/server/prelude.sm
===================================================================
--- pvfs2_src/src/server/prelude.sm	(revision 13267)
+++ pvfs2_src/src/server/prelude.sm	(revision 13268)
@@ -15,7 +15,6 @@
 #include "pint-util.h"
 #include "pvfs2-internal.h"
 #include "pint-perf-counter.h"
-#include "check.h"
 
 /* prelude state machine:
  * This is a nested state machine that performs initial setup 
Index: pvfs2_src/src/common/misc/pint-util.c
===================================================================
--- pvfs2_src/src/common/misc/pint-util.c	(revision 13267)
+++ pvfs2_src/src/common/misc/pint-util.c	(revision 13268)
@@ -17,6 +17,10 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
+#include <grp.h>
+#include <pwd.h>
+#include <sys/types.h>
+
 #define __PINT_REQPROTO_ENCODE_FUNCS_C
 #include "gen-locks.h"
 #include "pint-util.h"
@@ -24,6 +28,17 @@
 #include "gossip.h"
 #include "pvfs2-req-proto.h"
 
+//#include "pvfs2-types.h"
+#include "pvfs2-debug.h"
+#include "bmi-byteswap.h"
+
+static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
+static int pw_buf_size = 1024;      // 1 KB
+static int gr_buf_size = 1024*1024; // 1 MB
+static char* check_group_pw_buffer = NULL;
+static char* check_group_gr_buffer = NULL;
+static int PINT_check_group(uid_t uid, gid_t gid);
+
 void PINT_time_mark(PINT_time_marker *out_marker)
 {
     struct rusage usage;
@@ -496,7 +511,407 @@
     return strdup(tmp_alias);
 }
 
+/* PINT_check_mode()
+ *
+ * checks to see if the type of access described by "access_type" is permitted 
+ * for user "uid" of group "gid" on the object with attributes "attr"
+ *
+ * returns 0 on success, -PVFS_EACCES if permission is not granted
+ */
+int PINT_check_mode(
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid,
+    enum PINT_access_type access_type)
+{
+    int in_group_flag = 0;
+    int ret = 0;
+
+    /* if we don't have masks for the permission information that we
+     * need, then the system is broken
+     */
+    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
+           attr->mask & PVFS_ATTR_COMMON_GID &&
+           attr->mask & PVFS_ATTR_COMMON_PERM);
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - check_mode called --- "
+                 "(uid=%d,gid=%d,access_type=%d)\n", uid, gid, access_type);
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - object attributes --- "
+                 "(uid=%d,gid=%d,mode=%d)\n", attr->owner, attr->group,
+                 attr->perms);
+
+    /* give root permission, no matter what */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG,
+                 " - checking if uid (%d) is root ...\n", uid);
+    if (uid == 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return 0;
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+    /* see if uid matches object owner */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if owner (%d) "
+        "matches uid (%d)...\n", attr->owner, uid);
+    if(attr->owner == uid)
+    {
+        /* see if object user permissions match access type */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+            "(%d) allows access type (%d) for user...\n", attr->perms, access_type);
+        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+            PVFS_U_READ))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+            PVFS_U_WRITE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+            PVFS_U_EXECUTE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+    else
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+
+    /* see if other bits allow access */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+        "(%d) allows access type (%d) by others...\n", attr->perms, access_type);
+    if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+        PVFS_O_READ))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+        PVFS_O_WRITE))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+        PVFS_O_EXECUTE))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+    /* see if gid matches object group */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if group (%d) "
+        "matches gid (%d)...\n", attr->group, gid);
+    if(attr->group == gid)
+    {
+        /* default group match */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        in_group_flag = 1;
+    }
+    else
+    {
+        /* no default group match, check supplementary groups */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking for"
+            " supplementary group match...\n");
+        ret = PINT_check_group(uid, attr->group);
+        if(ret == 0)
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            in_group_flag = 1;
+        }
+        else
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+            if(ret != -PVFS_ENOENT)
+            {
+                /* system error; not just failed match */
+                return(ret);
+            }
+        }
+    }
+
+    if(in_group_flag)
+    {
+        /* see if object group permissions match access type */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+            "(%d) allows access type (%d) for group...\n", attr->perms, access_type);
+        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+            PVFS_G_READ))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+            PVFS_G_WRITE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+            PVFS_G_EXECUTE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+  
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "******PINT_check_mode: denying access\n");
+    /* default case: access denied */
+    return -PVFS_EACCES;
+}
+
+/* PINT_check_group()
+ *
+ * checks to see if uid is a member of gid
+ * 
+ * returns 0 on success, -PVFS_ENOENT if not a member, other PVFS error codes
+ * on system failure
+ */
+static int PINT_check_group(uid_t uid, gid_t gid)
+{
+#ifdef HAVE_GETPWUID
+    struct passwd pwd;
+    struct passwd* pwd_p = NULL;
+    struct group grp;
+    struct group* grp_p = NULL;
+    int i = 0;
+    int ret = -1;
+
+    /* Explanation: 
+     *
+     * We use the _r variants of getpwuid and getgrgid in order to insure
+     * thread safety; particularly if this function ever gets called in a
+     * client side situation in which we can't prevent the application from
+     * making conflicting calls.
+     *
+     * These _r functions require that a buffer be supplied for the user and
+     * group information, however.  These buffers may be unconfortably large
+     * for the stack, so we malloc them on a static pointer and then mutex
+     * lock this function so that it can still be reentrant.
+     */
+
+    gen_mutex_lock(&check_group_mutex);
+
+    if(!check_group_pw_buffer)
+    {
+        check_group_pw_buffer = (char*)malloc(pw_buf_size);
+        check_group_gr_buffer = (char*)malloc(gr_buf_size);
+        if(!check_group_pw_buffer || !check_group_gr_buffer)
+        {
+            if(check_group_pw_buffer)
+            {
+                free(check_group_pw_buffer);
+                check_group_pw_buffer = NULL;
+            }
+            if(check_group_gr_buffer)
+            {
+                free(check_group_gr_buffer);
+                check_group_gr_buffer = NULL;
+            }
+            gen_mutex_unlock(&check_group_mutex);
+            return(-PVFS_ENOMEM);
+        }
+    }
+
+    /* get user information */
+    ret = getpwuid_r(uid, &pwd, check_group_pw_buffer, pw_buf_size, &pwd_p);
+    if(ret != 0 || pwd_p == NULL)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        gossip_err("Get user info for (uid=%d) failed."
+                   "errno [%d] error_msg [%s]\n",
+                   uid, ret, strerror(ret));
+        return(-PVFS_EINVAL);
+    }
+
+    /* check primary group */
+    if(pwd.pw_gid == gid)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        return 0;
+    }
+
+    /* get the members of the group */
+    ret = getgrgid_r(gid, &grp, check_group_gr_buffer, gr_buf_size, &grp_p);
+    if(ret != 0 || grp_p == NULL)
+    {
+      gen_mutex_unlock(&check_group_mutex);
+      gossip_err("Get members for group (gid=%d) failed."
+                 "errno [%d] error_msg [%s]\n",
+                 gid, ret, strerror(ret));
+      return(-PVFS_EINVAL);
+    }
+
+    for(i = 0; grp.gr_mem[i] != NULL; i++)
+    {
+        if(0 == strcmp(pwd.pw_name, grp.gr_mem[i]))
+        {
+            gen_mutex_unlock(&check_group_mutex);
+            return 0;
+        } 
+    }
+
+    gen_mutex_unlock(&check_group_mutex);
+    return(-PVFS_ENOENT);
+#else
+    return 0;
+#endif
+}
+
+/* Checks if a given user is part of any groups that matches the file gid */
+static int in_group_p(PVFS_uid uid, PVFS_gid gid, PVFS_gid attr_group)
+{
+    if (attr_group == gid)
+        return 1;
+    if (PINT_check_group(uid, attr_group) == 0)
+        return 1;
+    return 0;
+}
+
 /*
+ * Return 0 if requesting clients is granted want access to the object
+ * by the acl. Returns -PVFS_E... otherwise.
+ */
+int PINT_check_acls(void *acl_buf, size_t acl_size, 
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid, int want)
+{
+    pvfs2_acl_entry pe, *pa;
+    int i = 0, found = 0, count = 0;
+    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
+           attr->mask & PVFS_ATTR_COMMON_GID &&
+           attr->mask & PVFS_ATTR_COMMON_PERM);
+
+    if (acl_size == 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "no acl's present.. denying access\n");
+        return -PVFS_EACCES;
+    }
+
+    /* keyval for ACLs includes a \0. so subtract the thingie */
+    acl_size--;
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "PINT_check_acls: read keyval size "
+    " %d (%d acl entries)\n",
+        (int) acl_size, 
+        (int) (acl_size / sizeof(pvfs2_acl_entry)));
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "uid = %d, gid = %d, want = %d\n",
+        uid, gid, want);
+
+    assert(acl_buf);
+    /* if the acl format doesn't look valid, then return an error rather than
+     * asserting; we don't want the server to crash due to an invalid keyval
+     */
+    if((acl_size % sizeof(pvfs2_acl_entry)) != 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "invalid acls on object\n");
+        return(-PVFS_EACCES);
+    }
+    count = acl_size / sizeof(pvfs2_acl_entry);
+
+    for (i = 0; i < count; i++)
+    {
+        pa = (pvfs2_acl_entry *) acl_buf + i;
+        /* 
+           NOTE: Remember that keyval is encoded as lebf, so convert it 
+           to host representation 
+        */
+        pe.p_tag  = bmitoh32(pa->p_tag);
+        pe.p_perm = bmitoh32(pa->p_perm);
+        pe.p_id   = bmitoh32(pa->p_id);
+        pa = &pe;
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded ACL entry %d "
+            "(p_tag %d, p_perm %d, p_id %d)\n",
+            i, pa->p_tag, pa->p_perm, pa->p_id);
+        switch(pa->p_tag) 
+        {
+            case PVFS2_ACL_USER_OBJ:
+                /* (May have been checked already) */
+                if (attr->owner == uid)
+                    goto check_perm;
+                break;
+            case PVFS2_ACL_USER:
+                if (pa->p_id == uid)
+                    goto mask;
+                break;
+            case PVFS2_ACL_GROUP_OBJ:
+                if (in_group_p(uid, gid, attr->group)) 
+                {
+                    found = 1;
+                    if ((pa->p_perm & want) == want)
+                        goto mask;
+                }
+                break;
+            case PVFS2_ACL_GROUP:
+                if (in_group_p(uid, gid, pa->p_id)) {
+                    found = 1;
+                    if ((pa->p_perm & want) == want)
+                        goto mask;
+                }
+                break;
+            case PVFS2_ACL_MASK:
+                break;
+            case PVFS2_ACL_OTHER:
+                if (found)
+                {
+                    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(1) PINT_check_acls:"
+                        "returning access denied\n");
+                    return -PVFS_EACCES;
+                }
+                else
+                    goto check_perm;
+            default:
+                gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(2) PINT_check_acls: "
+                        "returning EIO\n");
+                return -PVFS_EIO;
+        }
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(3) PINT_check_acls: returning EIO\n");
+    return -PVFS_EIO;
+mask:
+    /* search the remaining entries */
+    i = i + 1;
+    for (; i < count; i++)
+    {
+        pvfs2_acl_entry me, *mask_obj = (pvfs2_acl_entry *) acl_buf + i;
+        
+        /* 
+          NOTE: Again, since pvfs2_acl_entry is in lebf, we need to
+          convert it to host endian format
+         */
+        me.p_tag  = bmitoh32(mask_obj->p_tag);
+        me.p_perm = bmitoh32(mask_obj->p_perm);
+        me.p_id   = bmitoh32(mask_obj->p_id);
+        mask_obj = &me;
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded (mask) ACL entry %d "
+            "(p_tag %d, p_perm %d, p_id %d)\n",
+            i, mask_obj->p_tag, mask_obj->p_perm, mask_obj->p_id);
+        if (mask_obj->p_tag == PVFS2_ACL_MASK) 
+        {
+            if ((pa->p_perm & mask_obj->p_perm & want) == want)
+                return 0;
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(4) PINT_check_acls:"
+                "returning access denied (mask)\n");
+            return -PVFS_EACCES;
+        }
+    }
+
+check_perm:
+    if ((pa->p_perm & want) == want)
+        return 0;
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(5) PINT_check_acls: returning"
+            "access denied\n");
+    return -PVFS_EACCES;
+}
+
+/*
  * Local variables:
  *  c-indent-level: 4
  *  c-basic-offset: 4
Index: pvfs2_src/src/common/misc/pint-util.h
===================================================================
--- pvfs2_src/src/common/misc/pint-util.h	(revision 13267)
+++ pvfs2_src/src/common/misc/pint-util.h	(revision 13268)
@@ -141,6 +141,22 @@
 void PINT_util_gen_credentials(
     PVFS_credentials *credentials);
 
+enum PINT_access_type
+{
+    PINT_ACCESS_EXECUTABLE = 1,
+    PINT_ACCESS_WRITABLE = 2,
+    PINT_ACCESS_READABLE = 4,
+};
+
+int PINT_check_mode(
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid,
+    enum PINT_access_type access_type);
+
+int PINT_check_acls(void *acl_buf, size_t acl_size, 
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid, int want);
+
 #endif /* __PINT_UTIL_H */
 
 /*
Index: pvfs2_src/src/client/sysint/sys-truncate.sm
===================================================================
--- pvfs2_src/src/client/sysint/sys-truncate.sm	(revision 13267)
+++ pvfs2_src/src/client/sysint/sys-truncate.sm	(revision 13268)
@@ -153,7 +153,7 @@
         sm_p->object_ref,
         PVFS_ATTR_META_ALL|PVFS_ATTR_COMMON_TYPE,
         PVFS_TYPE_METAFILE,
-        0);
+        PINT_SM_GETATTR_BYPASS_CACHE);
 
     return PINT_client_state_machine_post(
         smcb,  op_id, user_ptr);
@@ -314,6 +314,14 @@
 {
     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
 
+    //check for write access
+    js_p->error_code = PINT_check_mode(
+        &sm_p->getattr.attr, sm_p->cred_p->uid, sm_p->cred_p->gid, PINT_ACCESS_WRITABLE);
+    if(js_p->error_code)
+    {
+        return 1;
+    }
+
     /* determine if we need to unstuff or not to service this request */
     if(unstuff_needed(
         sm_p->u.truncate.size,
Index: pvfs2_src/src/common/misc/pint-util.c
===================================================================
--- pvfs2_src/src/common/misc/pint-util.c	(revision 13269)
+++ pvfs2_src/src/common/misc/pint-util.c	(revision 13270)
@@ -32,11 +32,13 @@
 #include "pvfs2-debug.h"
 #include "bmi-byteswap.h"
 
+#ifdef HAVE_GETPWUID
 static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
 static int pw_buf_size = 1024;      // 1 KB
 static int gr_buf_size = 1024*1024; // 1 MB
 static char* check_group_pw_buffer = NULL;
 static char* check_group_gr_buffer = NULL;
+#endif
 static int PINT_check_group(uid_t uid, gid_t gid);
 
 void PINT_time_mark(PINT_time_marker *out_marker)
Index: pvfs2_src/src/common/misc/pint-util.c
===================================================================
--- pvfs2_src/src/common/misc/pint-util.c	(revision 13286)
+++ pvfs2_src/src/common/misc/pint-util.c	(revision 13287)
@@ -28,7 +28,6 @@
 #include "gossip.h"
 #include "pvfs2-req-proto.h"
 
-//#include "pvfs2-types.h"
 #include "pvfs2-debug.h"
 #include "bmi-byteswap.h"
 
