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

LCOV - code coverage report
Current view: top level - main - safe_mode.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 64 93 68.8 %
Date: 2014-04-18 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 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$ */
      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          22 : PHPAPI int php_checkuid_ex(const char *filename, const char *fopen_mode, int mode, int flags)
      49             : {
      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          10 : PHPAPI int php_checkuid(const char *filename, const char *fopen_mode, int mode)
     199             : {
     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          11 : PHPAPI char *php_get_current_user(void)
     209             : {
     210             :         struct stat *pstat;
     211             :         TSRMLS_FETCH();
     212             : 
     213          11 :         if (SG(request_info).current_user) {
     214           2 :                 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           9 :         pstat = sapi_get_stat(TSRMLS_C);
     222             : 
     223           9 :         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           9 :                 if ((pwd=getpwuid(pstat->st_uid))==NULL) {
     256           0 :                         return "";
     257             :                 }
     258             : #endif
     259           9 :                 SG(request_info).current_user_length = strlen(pwd->pw_name);
     260           9 :                 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           9 :                 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: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:41 +0000 (6 days ago)

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