PHP 4.0 Bug #3753 Updated: is_readable() broken
| From: | Bug Database | Date: | Wed, 08 Mar 2000 01:25:45 +0000 |
| Subject: | PHP 4.0 Bug #3753 Updated: is_readable() broken | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-16523@lists.php.net to get a copy of this message | ||
ID: 3753
Updated by: hholzgra
Reported By: ajung@suxers.de
Status: Analyzed
Bug Type: Misbehaving function
Assigned To:
Comments:
the following patch to ext/standard/filestat.c
should do most of the job
it checks for all groups a user belongs to
and it knows that root can do anything
it does not yet check for effective id's
( geteuid(), getegid() ) and i am quite
shure that the getgroups() funktion is
not available on all systems
can especially someone check this on a win32
system please ?
(won't do a cvs commit until i know better)
--- filestat.c 2000/03/06 20:37:11 1.26
+++ filestat.c 2000/03/08 01:19:47
@@ -402,6 +402,7 @@
static void php_stat(const char *filename, int type, pval *return_value)
{
struct stat *stat_sb;
+ int rmask=S_IROTH,wmask=S_IWOTH,xmask=S_IXOTH; /* access rights defaults to other */
BLS_FETCH();
stat_sb = &BG(sb);
@@ -444,6 +445,35 @@
}
#endif
+
+ if(BG(sb).st_uid==getuid()) {
+ rmask=S_IRUSR;
+ wmask=S_IWUSR;
+ xmask=S_IXUSR;
+ } else if(BG(sb).st_gid==getgid()) {
+ rmask=S_IRGRP;
+ wmask=S_IWGRP;
+ xmask=S_IXGRP;
+ } else {
+ int groups,n,i;
+ gid_t *gids;
+
+ groups = getgroups(0,NULL);
+ if(groups) {
+ gids=(gid_t *)emalloc(groups*sizeof(gid_t));
+ n=getgroups(groups,gids);
+ for(i=0;i<n;i++){
+ if(BG(sb).st_gid==gids[i]) {
+ rmask=S_IRGRP;
+ wmask=S_IWGRP;
+ xmask=S_IXGRP;
+ break;
+ }
+ }
+ efree(gids);
+ }
+ }
+
switch(type) {
case 0: /* fileperms */
RETURN_LONG((long)BG(sb).st_mode);
@@ -477,11 +507,14 @@
php_error(E_WARNING,"Unknown file type (%d)",BG(sb).st_mode&S_IFMT);
RETURN_STRING("unknown",1);
case 9: /*is writable*/
- RETURN_LONG((BG(sb).st_mode&S_IWRITE)!=0);
+ if(getuid()==0) RETURN_LONG(1); /* root */
+ RETURN_LONG((BG(sb).st_mode&wmask)!=0);
case 10: /*is readable*/
- RETURN_LONG((BG(sb).st_mode&S_IREAD)!=0);
+ if(getuid()==0) RETURN_LONG(1); /* root */
+ RETURN_LONG((BG(sb).st_mode&rmask)!=0);
case 11: /*is executable*/
- RETURN_LONG((BG(sb).st_mode&S_IEXEC)!=0 && !S_ISDIR(BG(sb).st_mode));
+ if(getuid()==0) RETURN_LONG(1); /* root */
+ RETURN_LONG((BG(sb).st_mode&xmask)!=0 && !S_ISDIR(BG(sb).st_mode));
case 12: /*is file*/
RETURN_LONG(S_ISREG(BG(sb).st_mode));
case 13: /*is dir*/
Full Bug description available at: http://bugs.php.net/?id=3753