LTP GCOV extension - code coverage report
Current view: directory - main - safe_mode.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 93
Code covered: 0.0 % Executed lines: 0
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2007 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,v 1.62.2.1.2.8 2007/01/12 12:11:18 bjori Exp $ */
      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               0 : {
      50                 :         struct stat sb;
      51               0 :         int ret, nofile=0;
      52               0 :         long uid=0L, gid=0L, duid=0L, dgid=0L;
      53                 :         char path[MAXPATHLEN];
      54                 :         char *s, filenamecopy[MAXPATHLEN];
      55               0 :         php_stream_wrapper *wrapper = NULL;
      56                 :         TSRMLS_FETCH();
      57                 : 
      58               0 :         path[0] = '\0';
      59                 : 
      60               0 :         if (!filename) {
      61               0 :                 return 0; /* path must be provided */
      62                 :         }
      63                 : 
      64               0 :         if (strlcpy(filenamecopy, filename, MAXPATHLEN)>=MAXPATHLEN) {
      65               0 :                 return 0;
      66                 :         }
      67               0 :         filename=(char *)&filenamecopy;
      68                 : 
      69               0 :         if (fopen_mode) {
      70               0 :                 if (fopen_mode[0] == 'r') {
      71               0 :                         mode = CHECKUID_DISALLOW_FILE_NOT_EXISTS;
      72                 :                 } else {
      73               0 :                         mode = CHECKUID_CHECK_FILE_AND_DIR;
      74                 :                 }
      75                 :         }
      76                 : 
      77                 :         /* 
      78                 :          * If given filepath is a URL, allow - safe mode stuff
      79                 :          * related to URL's is checked in individual functions
      80                 :          */
      81               0 :         wrapper = php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC);
      82               0 :         if (wrapper != NULL)
      83               0 :                 return 1;
      84                 :                 
      85                 :         /* First we see if the file is owned by the same user...
      86                 :          * If that fails, passthrough and check directory...
      87                 :          */
      88               0 :         if (mode != CHECKUID_ALLOW_ONLY_DIR) {
      89               0 :                 expand_filepath(filename, path TSRMLS_CC);
      90               0 :                 ret = VCWD_STAT(path, &sb);
      91               0 :                 if (ret < 0) {
      92               0 :                         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               0 :                         } 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               0 :                         nofile = 1;
     104                 :                 } else {
     105               0 :                         uid = sb.st_uid;
     106               0 :                         gid = sb.st_gid;
     107               0 :                         if (uid == php_getuid()) {
     108               0 :                                 return 1;
     109               0 :                         } else if (PG(safe_mode_gid) && gid == php_getgid()) {
     110               0 :                                 return 1;
     111                 :                         }
     112                 :                 }
     113                 : 
     114                 :                 /* Trim off filename */
     115               0 :                 if ((s = strrchr(path, DEFAULT_SLASH))) {
     116               0 :                         if (s == path)
     117               0 :                                 path[1] = '\0';
     118                 :                         else
     119               0 :                                 *s = '\0';
     120                 :                 }
     121                 :         } else { /* CHECKUID_ALLOW_ONLY_DIR */
     122               0 :                 s = strrchr(filename, DEFAULT_SLASH);
     123                 : 
     124               0 :                 if (s == filename) {
     125                 :                         /* root dir */
     126               0 :                         path[0] = DEFAULT_SLASH;
     127               0 :                         path[1] = '\0';
     128               0 :                 } else if (s) {
     129               0 :                         *s = '\0';
     130               0 :                         VCWD_REALPATH(filename, path);
     131               0 :                         *s = DEFAULT_SLASH;
     132                 :                 } else {
     133                 :                         /* Under Solaris, getcwd() can fail if there are no
     134                 :                          * read permissions on a component of the path, even
     135                 :                          * though it has the required x permissions */
     136               0 :                         path[0] = '.';
     137               0 :                         path[1] = '\0';
     138               0 :                         VCWD_GETCWD(path, sizeof(path));
     139                 :                 }
     140                 :         } /* end CHECKUID_ALLOW_ONLY_DIR */
     141                 :         
     142               0 :         if (mode != CHECKUID_ALLOW_ONLY_FILE) {
     143                 :                 /* check directory */
     144               0 :                 ret = VCWD_STAT(path, &sb);
     145               0 :                 if (ret < 0) {
     146               0 :                         if ((flags & CHECKUID_NO_ERRORS) == 0) {
     147               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename);
     148                 :                         }
     149               0 :                         return 0;
     150                 :                 }
     151               0 :                 duid = sb.st_uid;
     152               0 :                 dgid = sb.st_gid;
     153               0 :                 if (duid == php_getuid()) {
     154               0 :                         return 1;
     155               0 :                 } else if (PG(safe_mode_gid) && dgid == php_getgid()) {
     156               0 :                         return 1;
     157                 :                 } else {
     158               0 :                         if (SG(rfc1867_uploaded_files)) {
     159               0 :                                 if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) {
     160               0 :                                         return 1;
     161                 :                                 }
     162                 :                         }
     163                 :                 }
     164                 :         }
     165                 : 
     166               0 :         if (mode == CHECKUID_ALLOW_ONLY_DIR) {
     167               0 :                 uid = duid;
     168               0 :                 gid = dgid;
     169               0 :                 if (s) {
     170               0 :                         *s = 0;
     171                 :                 }
     172                 :         }
     173                 :         
     174               0 :         if (nofile) {
     175               0 :                 uid = duid;
     176               0 :                 gid = dgid;
     177               0 :                 filename = path;
     178                 :         }
     179                 : 
     180               0 :         if ((flags & CHECKUID_NO_ERRORS) == 0) {
     181               0 :                 if (PG(safe_mode_gid)) {
     182               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);
     183                 :                 } else {
     184               0 :                         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);
     185                 :                 }                       
     186                 :         }
     187                 : 
     188               0 :         return 0;
     189                 : }
     190                 : 
     191               0 : PHPAPI int php_checkuid(const char *filename, const char *fopen_mode, int mode) {
     192                 : #ifdef NETWARE
     193                 : /* NetWare don't have uid*/
     194                 :         return 1;
     195                 : #else
     196               0 :         return php_checkuid_ex(filename, fopen_mode, mode, 0);
     197                 : #endif
     198                 : }
     199                 : 
     200                 : PHPAPI char *php_get_current_user()
     201               0 : {
     202                 :         struct stat *pstat;
     203                 :         TSRMLS_FETCH();
     204                 : 
     205               0 :         if (SG(request_info).current_user) {
     206               0 :                 return SG(request_info).current_user;
     207                 :         }
     208                 : 
     209                 :         /* FIXME: I need to have this somehow handled if
     210                 :         USE_SAPI is defined, because cgi will also be
     211                 :         interfaced in USE_SAPI */
     212                 : 
     213               0 :         pstat = sapi_get_stat(TSRMLS_C);
     214                 : 
     215               0 :         if (!pstat) {
     216               0 :                 return "";
     217                 :         } else {
     218                 : #ifdef PHP_WIN32
     219                 :                 char name[256];
     220                 :                 DWORD len = sizeof(name)-1;
     221                 : 
     222                 :                 if (!GetUserName(name, &len)) {
     223                 :                         return "";
     224                 :                 }
     225                 :                 name[len] = '\0';
     226                 :                 SG(request_info).current_user_length = len;
     227                 :                 SG(request_info).current_user = estrndup(name, len);
     228                 :                 return SG(request_info).current_user;           
     229                 : #else
     230                 :                 struct passwd *pwd;
     231                 : #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
     232                 :                 struct passwd _pw;
     233                 :                 struct passwd *retpwptr = NULL;
     234                 :                 int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
     235                 :                 char *pwbuf;
     236                 : 
     237                 :                 if (pwbuflen < 1) {
     238                 :                         return "";
     239                 :                 }
     240                 :                 pwbuf = emalloc(pwbuflen);
     241                 :                 if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
     242                 :                         efree(pwbuf);
     243                 :                         return "";
     244                 :                 }
     245                 :                 pwd = &_pw;
     246                 : #else
     247               0 :                 if ((pwd=getpwuid(pstat->st_uid))==NULL) {
     248               0 :                         return "";
     249                 :                 }
     250                 : #endif
     251               0 :                 SG(request_info).current_user_length = strlen(pwd->pw_name);
     252               0 :                 SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length);
     253                 : #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
     254                 :                 efree(pwbuf);
     255                 : #endif
     256               0 :                 return SG(request_info).current_user;           
     257                 : #endif
     258                 :         }       
     259                 : }       
     260                 : 
     261                 : /*
     262                 :  * Local variables:
     263                 :  * tab-width: 4
     264                 :  * c-basic-offset: 4
     265                 :  * End:
     266                 :  * vim600: sw=4 ts=4 fdm=marker
     267                 :  * vim<600: sw=4 ts=4
     268                 :  */

Generated by: LTP GCOV extension version 1.5