~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to main/safe_mode.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

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