[Libsysio-commit] HEAD: libsysio/src access.c init.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2006-05-03 15:57:32
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24736/src Modified Files: access.c init.c Log Message: Speed up group ID checks a little by keeping memory allocated instead of reallocating every time. Index: access.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/access.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -w -b -B -p -r1.10 -r1.11 --- access.c 21 Sep 2004 16:18:30 -0000 1.10 +++ access.c 3 May 2006 15:57:28 -0000 1.11 @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2003 Sandia Corporation. + * Cplant(TM) Copyright 1998-2006 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -50,9 +50,14 @@ #include <sys/queue.h> #include "sysio.h" +#include "mount.h" +#include "fs.h" #include "inode.h" #include "sysio-symbols.h" +static gid_t *gids = NULL; /* space for gids */ +static unsigned ngids = 0; /* max # gids */ + /* * Check given access type on given inode. */ @@ -82,6 +87,13 @@ _sysio_check_permission(struct inode *in if (amode & X_OK) mask |= S_IXUSR; + /* + * Check for RO access to the file due to mount + * options. + */ + if (amode & W_OK && IS_RDONLY(NULL, ino)) + return -EROFS; + stat = &ino->i_stbuf; if (stat->st_uid == uid && (stat->st_mode & mask) == mask) return 0; @@ -110,22 +122,33 @@ int _sysio_permitted(struct inode *ino, int amode) { int err; - gid_t *gids; int n; void *p; err = 0; - gids = NULL; for (;;) { + /* + * This is far more expensive than I would like. Each time + * called it has to go to some length to acquire the + * current uid and groups membership. We can't just cache + * the result, either. The caller could have altered something + * asynchronously. Wish we had easy access to this info. + */ n = getgroups(0, NULL); - if (!n) + if (n < 0) { + err = -errno; break; + } + if ((unsigned )n > ngids) { p = realloc(gids, n * sizeof(gid_t)); if (!p && gids) { err = -ENOMEM; break; } + ngids = n; gids = p; + } + if (n) { err = getgroups(n, gids); if (err < 0) { if (errno == EINVAL) @@ -133,6 +156,7 @@ _sysio_permitted(struct inode *ino, int err = -errno; break; } + } err = _sysio_check_permission(ino, geteuid(), getegid(), @@ -142,10 +166,24 @@ _sysio_permitted(struct inode *ino, int } if (!gids) return err; - free(gids); return err; } +#ifdef ZERO_SUM_MEMORY +/* + * Clean up persistent resource on shutdown. + */ +void +_sysio_access_shutdown() +{ + + if (gids) + free(gids); + gids = NULL; + ngids = 0; +} +#endif + int SYSIO_INTERFACE_NAME(access)(const char *path, int amode) { Index: init.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/init.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -w -b -B -p -r1.26 -r1.27 --- init.c 27 Feb 2006 17:26:55 -0000 1.26 +++ init.c 3 May 2006 15:57:28 -0000 1.27 @@ -210,6 +210,7 @@ _sysio_shutdown() _sysio_fd_shutdown(); _sysio_i_shutdown(); _sysio_fssw_shutdown(); + _sysio_access_shutdown(); #if SYSIO_TRACING { struct trace_callback *tcb; |