[Pvfs2-cvs] commit by pw in pvfs2/src/common/misc: pint-util.c
pint-util.h
CVS commit program
cvs at parl.clemson.edu
Fri Jul 20 15:37:05 EDT 2007
Update of /projects/cvsroot/pvfs2/src/common/misc
In directory parlweb1:/tmp/cvs-serv5287/src/common/misc
Modified Files:
pint-util.c pint-util.h
Log Message:
Move some server-only functions out of src/common/misc into src/server.
These functions happen not to compile on clients without getpwuid support.
Index: pint-util.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-util.c,v
diff -u -p -p -u -r1.20 -r1.21
--- pint-util.c 20 Mar 2007 18:32:30 -0000 1.20
+++ pint-util.c 20 Jul 2007 19:37:05 -0000 1.21
@@ -11,30 +11,12 @@
/* This file includes definitions of common internal utility functions */
#include <string.h>
+#include <assert.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include <unistd.h>
-#include <assert.h>
-#include <grp.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include "pvfs2-types.h"
-#include "pint-util.h"
#include "gen-locks.h"
-#include "gossip.h"
-#include "pvfs2-debug.h"
-#include "bmi-byteswap.h"
-
-static int current_tag = 1;
-static gen_mutex_t current_tag_lock = GEN_MUTEX_INITIALIZER;
-
-static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
-static char* check_group_pw_buffer = NULL;
-static long check_group_pw_buffer_size = 0;
-static char* check_group_gr_buffer = NULL;
-static long check_group_gr_buffer_size = 0;
-static int PINT_check_group(uid_t uid, gid_t gid);
+#include "pint-util.h"
void PINT_time_mark(PINT_time_marker *out_marker)
{
@@ -71,6 +53,9 @@ void PINT_time_diff(PINT_time_marker mar
(double)(mark1.utime.tv_usec) / 1000000);
}
+static int current_tag = 1;
+static gen_mutex_t current_tag_lock = GEN_MUTEX_INITIALIZER;
+
PVFS_msg_tag_t PINT_util_get_next_tag(void)
{
PVFS_msg_tag_t ret;
@@ -296,419 +281,6 @@ void PINT_free_object_attr(PVFS_object_a
}
}
}
-}
-
-/* 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)
-{
- 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)
- {
- /* need to create a buffer for pw and grp entries */
-#if defined(_SC_GETGR_R_SIZE_MAX) && defined(_SC_GETPW_R_SIZE_MAX)
- /* newish posix systems can tell us what the max buffer size is */
- check_group_gr_buffer_size = sysconf(_SC_GETGR_R_SIZE_MAX);
- check_group_pw_buffer_size = sysconf(_SC_GETPW_R_SIZE_MAX);
-#else
- /* fall back for older systems */
- check_group_pw_buffer_size = 1024;
- check_group_gr_buffer_size = 1024;
-#endif
- check_group_pw_buffer = (char*)malloc(check_group_pw_buffer_size);
- check_group_gr_buffer = (char*)malloc(check_group_gr_buffer_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,
- check_group_pw_buffer_size,
- &pwd_p);
- if(ret != 0 || pwd_p == NULL)
- {
- gen_mutex_unlock(&check_group_mutex);
- return(-PVFS_EINVAL);
- }
-
- /* check primary group */
- if(pwd.pw_gid == gid)
- {
- gen_mutex_unlock(&check_group_mutex);
- return 0;
- }
-
- /* get other group information */
- ret = getgrgid_r(gid, &grp, check_group_gr_buffer,
- check_group_gr_buffer_size,
- &grp_p);
- if(ret != 0)
- {
- gen_mutex_unlock(&check_group_mutex);
- return(-PVFS_EINVAL);
- }
-
- if(grp_p == NULL)
- {
- gen_mutex_unlock(&check_group_mutex);
- gossip_err("User (uid=%d) isn't in group %d on storage node.\n",
- uid, gid);
- return(-PVFS_EACCES);
- }
-
- 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);
-}
-
-/* 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;
}
char *PINT_util_get_object_type(int objtype)
Index: pint-util.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-util.h,v
diff -u -p -p -u -r1.12 -r1.13
--- pint-util.h 13 Sep 2006 19:09:35 -0000 1.12
+++ pint-util.h 20 Jul 2007 19:37:05 -0000 1.13
@@ -75,9 +75,6 @@ typedef struct PINT_time_marker_s PINT_t
PVFS_msg_tag_t PINT_util_get_next_tag(void);
-int PINT_check_acls(void *acl_buf, size_t acl_size,
- PVFS_object_attr *attr,
- PVFS_uid uid, PVFS_gid gid, int want);
int PINT_copy_object_attr(PVFS_object_attr *dest, PVFS_object_attr *src);
void PINT_free_object_attr(PVFS_object_attr *attr);
void PINT_time_mark(PINT_time_marker* out_marker);
@@ -86,18 +83,6 @@ void PINT_time_diff(PINT_time_marker mar
double* out_wtime_sec,
double* out_utime_sec,
double* out_stime_sec);
-
-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);
#ifdef HAVE_SYS_VFS_H
More information about the Pvfs2-cvs
mailing list