PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_3/main - safe_mode.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 93
Code covered: 68.8 % Executed lines: 64
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: safe_mode.c 272370 2008-12-31 11:15:49Z sebastian $ */
      20                 : 
      21                 : #include "php.h"
      22                 : 
      23                 : #include <stdio.h>
      24                 : #include <stdlib.h>
      25                 : 
      26                 : #if HAVE_UNISTD_H
      27                 : #include <unistd.h>
      28                 : #endif
      29                 : #include <sys/stat.h>
      30                 : #include "ext/standard/pageinfo.h"
      31                 : #include "safe_mode.h"
      32                 : #include "SAPI.h"
      33                 : #include "php_globals.h"
      34                 : 
      35                 : /*
      36                 :  * php_checkuid
      37                 :  *
      38                 :  * This function has six modes:
      39                 :  * 
      40                 :  * 0 - return invalid (0) if file does not exist
      41                 :  * 1 - return valid (1)  if file does not exist
      42                 :  * 2 - if file does not exist, check directory
      43                 :  * 3 - only check directory (needed for mkdir)
      44                 :  * 4 - check mode and param
      45                 :  * 5 - only check file
      46                 :  */
      47                 : 
      48                 : PHPAPI int php_checkuid_ex(const char *filename, const char *fopen_mode, int mode, int flags)
      49              22 : {
      50                 :         struct stat sb;
      51              22 :         int ret, nofile=0;
      52              22 :         long uid=0L, gid=0L, duid=0L, dgid=0L;
      53                 :         char path[MAXPATHLEN];
      54                 :         char *s, filenamecopy[MAXPATHLEN];
      55                 :         TSRMLS_FETCH();
      56                 : 
      57              22 :         path[0] = '\0';
      58                 : 
      59              22 :         if (!filename) {
      60               0 :                 return 0; /* path must be provided */
      61                 :         }
      62                 : 
      63              22 :         if (strlcpy(filenamecopy, filename, MAXPATHLEN)>=MAXPATHLEN) {
      64               0 :                 return 0;
      65                 :         }
      66              22 :         filename=(char *)&filenamecopy;
      67                 : 
      68              22 :         if (fopen_mode) {
      69               2 :                 if (fopen_mode[0] == 'r') {
      70               0 :                         mode = CHECKUID_DISALLOW_FILE_NOT_EXISTS;
      71                 :                 } else {
      72               2 :                         mode = CHECKUID_CHECK_FILE_AND_DIR;
      73                 :                 }
      74                 :         }
      75                 :                 
      76                 :         /* First we see if the file is owned by the same user...
      77                 :          * If that fails, passthrough and check directory...
      78                 :          */
      79              22 :         if (mode != CHECKUID_ALLOW_ONLY_DIR) {
      80                 : #if HAVE_BROKEN_GETCWD
      81                 :                 char ftest[MAXPATHLEN];
      82                 : 
      83                 :                 strcpy(ftest, filename);
      84                 :                 if (VCWD_GETCWD(ftest, sizeof(ftest)) == NULL) {
      85                 :                         strcpy(path, filename);
      86                 :                 } else
      87                 : #endif
      88              20 :                 expand_filepath(filename, path TSRMLS_CC);
      89                 : 
      90              20 :                 ret = VCWD_STAT(path, &sb);
      91              20 :                 if (ret < 0) {
      92               5 :                         if (mode == CHECKUID_DISALLOW_FILE_NOT_EXISTS) {
      93               0 :                                 if ((flags & CHECKUID_NO_ERRORS) == 0) {
      94               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename);
      95                 :                                 }
      96               0 :                                 return 0;
      97               5 :                         } else if (mode == CHECKUID_ALLOW_FILE_NOT_EXISTS) {
      98               0 :                                 if ((flags & CHECKUID_NO_ERRORS) == 0) {
      99               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename);
     100                 :                                 }
     101               0 :                                 return 1;
     102                 :                         } 
     103               5 :                         nofile = 1;
     104                 :                 } else {
     105              15 :                         uid = sb.st_uid;
     106              15 :                         gid = sb.st_gid;
     107              15 :                         if (uid == php_getuid()) {
     108              14 :                                 return 1;
     109               1 :                         } else if (PG(safe_mode_gid) && gid == php_getgid()) {
     110               0 :                                 return 1;
     111                 :                         }
     112                 :                 }
     113                 : 
     114                 :                 /* Trim off filename */
     115               6 :                 if ((s = strrchr(path, DEFAULT_SLASH))) {
     116               6 :                         if (*(s + 1) == '\0' && s != path) { /* make sure that the / is not the last character */
     117               0 :                                 *s = '\0';
     118               0 :                                 s = strrchr(path, DEFAULT_SLASH);
     119                 :                         }
     120               6 :                         if (s) {
     121               6 :                                 if (s == path) {
     122               1 :                                         path[1] = '\0';
     123                 :                                 } else {
     124               5 :                                         *s = '\0';
     125                 :                                 }
     126                 :                         }
     127                 :                 }
     128                 :         } else { /* CHECKUID_ALLOW_ONLY_DIR */
     129               2 :                 s = strrchr(filename, DEFAULT_SLASH);
     130                 : 
     131               2 :                 if (s == filename) {
     132                 :                         /* root dir */
     133               0 :                         path[0] = DEFAULT_SLASH;
     134               0 :                         path[1] = '\0';
     135               4 :                 } else if (s && *(s + 1) != '\0') { /* make sure that the / is not the last character */
     136               2 :                         *s = '\0';
     137               2 :                         VCWD_REALPATH(filename, path);
     138               2 :                         *s = DEFAULT_SLASH;
     139                 :                 } else {
     140                 :                         /* Under Solaris, getcwd() can fail if there are no
     141                 :                          * read permissions on a component of the path, even
     142                 :                          * though it has the required x permissions */
     143               0 :                         path[0] = '.';
     144               0 :                         path[1] = '\0';
     145               0 :                         VCWD_GETCWD(path, sizeof(path));
     146                 :                 }
     147                 :         } /* end CHECKUID_ALLOW_ONLY_DIR */
     148                 :         
     149               8 :         if (mode != CHECKUID_ALLOW_ONLY_FILE) {
     150                 :                 /* check directory */
     151               8 :                 ret = VCWD_STAT(path, &sb);
     152               8 :                 if (ret < 0) {
     153               0 :                         if ((flags & CHECKUID_NO_ERRORS) == 0) {
     154               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename);
     155                 :                         }
     156               0 :                         return 0;
     157                 :                 }
     158               8 :                 duid = sb.st_uid;
     159               8 :                 dgid = sb.st_gid;
     160               8 :                 if (duid == php_getuid()) {
     161               6 :                         return 1;
     162               2 :                 } else if (PG(safe_mode_gid) && dgid == php_getgid()) {
     163               0 :                         return 1;
     164                 :                 } else {
     165               2 :                         if (SG(rfc1867_uploaded_files)) {
     166               0 :                                 if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) {
     167               0 :                                         return 1;
     168                 :                                 }
     169                 :                         }
     170                 :                 }
     171                 :         }
     172                 : 
     173               2 :         if (mode == CHECKUID_ALLOW_ONLY_DIR) {
     174               1 :                 uid = duid;
     175               1 :                 gid = dgid;
     176               1 :                 if (s) {
     177               1 :                         *s = 0;
     178                 :                 }
     179                 :         }
     180                 :         
     181               2 :         if (nofile) {
     182               0 :                 uid = duid;
     183               0 :                 gid = dgid;
     184               0 :                 filename = path;
     185                 :         }
     186                 : 
     187               2 :         if ((flags & CHECKUID_NO_ERRORS) == 0) {
     188               1 :                 if (PG(safe_mode_gid)) {
     189               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect.  The script whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld", php_getuid(), php_getgid(), filename, uid, gid);
     190                 :                 } else {
     191               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect.  The script whose uid is %ld is not allowed to access %s owned by uid %ld", php_getuid(), filename, uid);
     192                 :                 }                       
     193                 :         }
     194                 : 
     195               2 :         return 0;
     196                 : }
     197                 : 
     198                 : PHPAPI int php_checkuid(const char *filename, const char *fopen_mode, int mode)
     199              10 : {
     200                 : #ifdef NETWARE
     201                 : /* NetWare don't have uid*/
     202                 :         return 1;
     203                 : #else
     204              10 :         return php_checkuid_ex(filename, fopen_mode, mode, 0);
     205                 : #endif
     206                 : }
     207                 : 
     208                 : PHPAPI char *php_get_current_user(void)
     209              29 : {
     210                 :         struct stat *pstat;
     211                 :         TSRMLS_FETCH();
     212                 : 
     213              29 :         if (SG(request_info).current_user) {
     214              10 :                 return SG(request_info).current_user;
     215                 :         }
     216                 : 
     217                 :         /* FIXME: I need to have this somehow handled if
     218                 :         USE_SAPI is defined, because cgi will also be
     219                 :         interfaced in USE_SAPI */
     220                 : 
     221              19 :         pstat = sapi_get_stat(TSRMLS_C);
     222                 : 
     223              19 :         if (!pstat) {
     224               0 :                 return "";
     225                 :         } else {
     226                 : #ifdef PHP_WIN32
     227                 :                 char name[256];
     228                 :                 DWORD len = sizeof(name)-1;
     229                 : 
     230                 :                 if (!GetUserName(name, &len)) {
     231                 :                         return "";
     232                 :                 }
     233                 :                 name[len] = '\0';
     234                 :                 SG(request_info).current_user_length = len;
     235                 :                 SG(request_info).current_user = estrndup(name, len);
     236                 :                 return SG(request_info).current_user;           
     237                 : #else
     238                 :                 struct passwd *pwd;
     239                 : #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
     240                 :                 struct passwd _pw;
     241                 :                 struct passwd *retpwptr = NULL;
     242                 :                 int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
     243                 :                 char *pwbuf;
     244                 : 
     245                 :                 if (pwbuflen < 1) {
     246                 :                         return "";
     247                 :                 }
     248                 :                 pwbuf = emalloc(pwbuflen);
     249                 :                 if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
     250                 :                         efree(pwbuf);
     251                 :                         return "";
     252                 :                 }
     253                 :                 pwd = &_pw;
     254                 : #else
     255              19 :                 if ((pwd=getpwuid(pstat->st_uid))==NULL) {
     256               0 :                         return "";
     257                 :                 }
     258                 : #endif
     259              19 :                 SG(request_info).current_user_length = strlen(pwd->pw_name);
     260              19 :                 SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length);
     261                 : #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
     262                 :                 efree(pwbuf);
     263                 : #endif
     264              19 :                 return SG(request_info).current_user;           
     265                 : #endif
     266                 :         }       
     267                 : }       
     268                 : 
     269                 : /*
     270                 :  * Local variables:
     271                 :  * tab-width: 4
     272                 :  * c-basic-offset: 4
     273                 :  * End:
     274                 :  * vim600: sw=4 ts=4 fdm=marker
     275                 :  * vim<600: sw=4 ts=4
     276                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:16 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.