Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 721 lines (606 sloc) 19.033 kb
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
1 /*
2 +----------------------------------------------------------------------+
dbeb415 @andigutmans - A belated happy holidays and PHP 5
andigutmans authored
3 | PHP Version 5 |
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
4 +----------------------------------------------------------------------+
8775a37 @felipensp - Year++
felipensp authored
5 | Copyright (c) 1997-2012 The PHP Group |
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
6 +----------------------------------------------------------------------+
5bd9322 bump year and license version
foobar authored
7 | This source file is subject to version 3.01 of the PHP license, |
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
8 | that is bundled with this package in the file LICENSE, and is |
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
9 | available through the world-wide-web at the following url: |
5bd9322 bump year and license version
foobar authored
10 | http://www.php.net/license/3_01.txt |
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
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 | Authors: Daniel Beulshausen <daniel@php4win.de> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <io.h>
24 #include <process.h>
95d3092 implement shm* similar functions
Daniel Beulshausen authored
25 #include <time.h>
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
26 #include <errno.h>
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
27
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
28 #define TSRM_INCLUDE_FULL_WINDOWS_HEADERS
64934cf @pierrejoye - missing include
pierrejoye authored
29 #include "SAPI.h"
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
30 #include "TSRM.h"
31
32 #ifdef TSRM_WIN32
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
33 #include <Sddl.h>
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
34 #include "tsrm_win32.h"
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
35 #include "tsrm_virtual_cwd.h"
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
36
37 #ifdef ZTS
38 static ts_rsrc_id win32_globals_id;
39 #else
40 static tsrm_win32_globals win32_globals;
41 #endif
42
736b4ae @zsuraski - Prepare for optimization - use a single fetch for multiple resources
zsuraski authored
43 static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
44 {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
45 globals->process = NULL;
95d3092 implement shm* similar functions
Daniel Beulshausen authored
46 globals->shm = NULL;
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
47 globals->process_size = 0;
95d3092 implement shm* similar functions
Daniel Beulshausen authored
48 globals->shm_size = 0;
8934c1e fix some popen trouble
Daniel Beulshausen authored
49 globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
60223d6 @pierrejoye - #48535, file_exists returns false when impersonate is used
pierrejoye authored
50
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
51 /* Set it to INVALID_HANDLE_VALUE
52 * It will be initialized correctly in tsrm_win32_access or set to
53 * NULL if no impersonation has been done.
54 * the impersonated token can't be set here as the impersonation
55 * will happen later, in fcgi_accept_request (or whatever is the
56 * SAPI being used).
57 */
58 globals->impersonation_token = INVALID_HANDLE_VALUE;
59 globals->impersonation_token_sid = NULL;
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
60 }
61
736b4ae @zsuraski - Prepare for optimization - use a single fetch for multiple resources
zsuraski authored
62 static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
63 {
95d3092 implement shm* similar functions
Daniel Beulshausen authored
64 shm_pair *ptr;
65
66 if (globals->process) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
67 free(globals->process);
68 }
95d3092 implement shm* similar functions
Daniel Beulshausen authored
69
70 if (globals->shm) {
71 for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
72 UnmapViewOfFile(ptr->addr);
73 CloseHandle(ptr->segment);
74 UnmapViewOfFile(ptr->descriptor);
75 CloseHandle(ptr->info);
76 }
77 free(globals->shm);
78 }
79
8934c1e fix some popen trouble
Daniel Beulshausen authored
80 free(globals->comspec);
aedaf1a @pierrejoye - close manually the impersonation token
pierrejoye authored
81
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
82 if (globals->impersonation_token && globals->impersonation_token != INVALID_HANDLE_VALUE ) {
aedaf1a @pierrejoye - close manually the impersonation token
pierrejoye authored
83 CloseHandle(globals->impersonation_token);
84 }
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
85 if (globals->impersonation_token_sid) {
86 free(globals->impersonation_token_sid);
87 }
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
88 }
89
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
90 TSRM_API void tsrm_win32_startup(void)
91 {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
92 #ifdef ZTS
736b4ae @zsuraski - Prepare for optimization - use a single fetch for multiple resources
zsuraski authored
93 ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
94 #else
736b4ae @zsuraski - Prepare for optimization - use a single fetch for multiple resources
zsuraski authored
95 tsrm_win32_ctor(&win32_globals TSRMLS_CC);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
96 #endif
97 }
98
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
99 TSRM_API void tsrm_win32_shutdown(void)
100 {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
101 #ifndef ZTS
736b4ae @zsuraski - Prepare for optimization - use a single fetch for multiple resources
zsuraski authored
102 tsrm_win32_dtor(&win32_globals TSRMLS_CC);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
103 #endif
104 }
105
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
106 char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC)
107 {
108 PSID pSid = TWG(impersonation_token_sid);
109 DWORD sid_len = pSid ? GetLengthSid(pSid) : 0;
110 TCHAR *ptcSid = NULL;
111 char *bucket_key = NULL;
112
113 if (!pSid) {
26e3082 @pierrejoye - fix lenght for alloc and cpy (Kanwal)
pierrejoye authored
114 bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + 1);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
115 if (!bucket_key) {
116 return NULL;
117 }
118 memcpy(bucket_key, pathname, strlen(pathname));
119 return bucket_key;
120 }
121
122 if (!ConvertSidToStringSid(pSid, &ptcSid)) {
123 return NULL;
124 }
125
26e3082 @pierrejoye - fix lenght for alloc and cpy (Kanwal)
pierrejoye authored
126 bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + strlen(ptcSid) + 1);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
127 if (!bucket_key) {
128 LocalFree(ptcSid);
129 return NULL;
130 }
131
132 memcpy(bucket_key, ptcSid, strlen(ptcSid));
26e3082 @pierrejoye - fix lenght for alloc and cpy (Kanwal)
pierrejoye authored
133 memcpy(bucket_key + strlen(ptcSid), pathname, strlen(pathname) + 1);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
134
135 LocalFree(ptcSid);
136 return bucket_key;
137 }
138
139
140 PSID tsrm_win32_get_token_sid(HANDLE hToken)
141 {
142 BOOL bSuccess = FALSE;
143 DWORD dwLength = 0;
144 PTOKEN_USER pTokenUser = NULL;
145 PSID sid;
146 PSID *ppsid = &sid;
147 DWORD sid_len;
148 PSID pResultSid = NULL;
3111aa2 @pierrejoye - ws
pierrejoye authored
149
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
150 /* Get the actual size of the TokenUser structure */
151 if (!GetTokenInformation(
152 hToken, TokenUser, (LPVOID) pTokenUser, 0, &dwLength)) {
153 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
154 goto Finished;
155 }
156
157 pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
158 if (pTokenUser == NULL) {
159 goto Finished;
160 }
161 }
162
163 /* and fetch it now */
164 if (!GetTokenInformation(
165 hToken, TokenUser, (LPVOID) pTokenUser, dwLength, &dwLength)) {
166 goto Finished;
167 }
168
169 sid_len = GetLengthSid(pTokenUser->User.Sid);
170
171 /* ConvertSidToStringSid(pTokenUser->User.Sid, &ptcSidOwner); */
172 pResultSid = malloc(sid_len);
173 if (!pResultSid) {
174 goto Finished;
175 }
176 if (!CopySid(sid_len, pResultSid, pTokenUser->User.Sid)) {
177 goto Finished;
178 }
5d360fa @pierrejoye - fix leak
pierrejoye authored
179 HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
180 return pResultSid;
181
182 Finished:
183 if (pResultSid) {
184 free(pResultSid);
185 }
186 /* Free the buffer for the token groups. */
187 if (pTokenUser != NULL) {
188 HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser);
189 }
190 return NULL;
191 }
192
83527d1 @pierrejoye - drop tsrmls_fetch in tsrm_win32_access
pierrejoye authored
193 TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC)
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
194 {
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
195 time_t t;
196 HANDLE thread_token;
197 PSID token_sid;
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
198 SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
199 GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
200 DWORD priv_set_length = sizeof(PRIVILEGE_SET);
201
202 PRIVILEGE_SET privilege_set = {0};
203 DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0;
204 BYTE * psec_desc = NULL;
205 BOOL fAccess = FALSE;
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
206
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
207 BOOL bucket_key_alloc = FALSE;
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
208 realpath_cache_bucket * bucket = NULL;
209 char * real_path = NULL;
210
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
211 if (mode == 1 /*X_OK*/) {
91dc80b Removed dependency from SHELL32.DLL
Dmitry Stogov authored
212 DWORD type;
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
213 return GetBinaryType(pathname, &type) ? 0 : -1;
214 } else {
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
215 if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
216 real_path = (char *)malloc(MAX_PATH);
217 if(tsrm_realpath(pathname, real_path TSRMLS_CC) == NULL) {
218 goto Finished;
219 }
220 pathname = real_path;
221 }
222
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
223 if(access(pathname, mode)) {
565af74 @pierrejoye - fix leak
pierrejoye authored
224 free(real_path);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
225 return errno;
226 }
227
228 /* If only existence check is made, return now */
229 if (mode == 0) {
565af74 @pierrejoye - fix leak
pierrejoye authored
230 free(real_path);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
231 return 0;
232 }
233
234 /* Only in NTS when impersonate==1 (aka FastCGI) */
235
236 /*
237 AccessCheck() requires an impersonation token. We first get a primary
238 token and then create a duplicate impersonation token. The
239 impersonation token is not actually assigned to the thread, but is
240 used in the call to AccessCheck. Thus, this function itself never
241 impersonates, but does use the identity of the thread. If the thread
242 was impersonating already, this function uses that impersonation context.
243 */
244 if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
245 DWORD err = GetLastError();
246 if (GetLastError() == ERROR_NO_TOKEN) {
247 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
248 TWG(impersonation_token) = NULL;
249 goto Finished;
250 }
251 }
252 }
253
254 /* token_sid will be freed in tsrmwin32_dtor */
255 token_sid = tsrm_win32_get_token_sid(thread_token);
256 if (!token_sid) {
257 if (TWG(impersonation_token_sid)) {
258 free(TWG(impersonation_token_sid));
259 }
260 TWG(impersonation_token_sid) = NULL;
261 goto Finished;
262 }
263
264 /* Different identity, we need a new impersontated token as well */
265 if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
266 if (TWG(impersonation_token_sid)) {
267 free(TWG(impersonation_token_sid));
268 }
269 TWG(impersonation_token_sid) = token_sid;
270
271 /* Duplicate the token as impersonated token */
272 if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
273 goto Finished;
274 }
79aa615 @pierrejoye - fix leak when the SID is already used and duplicated
pierrejoye authored
275 } else {
276 /* we already have it, free it then */
277 free(token_sid);
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
278 }
279
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
280 if (CWDG(realpath_cache_size_limit)) {
281 t = time(0);
282 bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
283 if(bucket == NULL && real_path == NULL) {
284 /* We used the pathname directly. Call tsrm_realpath */
285 /* so that entry is created in realpath cache */
286 real_path = (char *)malloc(MAX_PATH);
287 if(tsrm_realpath(pathname, real_path TSRMLS_CC) != NULL) {
288 pathname = real_path;
289 bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
290 }
291 }
292 }
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
293
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
294 /* Do a full access check because access() will only check read-only attribute */
295 if(mode == 0 || mode > 6) {
296 if(bucket != NULL && bucket->is_rvalid) {
297 fAccess = bucket->is_readable;
298 goto Finished;
299 }
300 desired_access = FILE_GENERIC_READ;
301 } else if(mode <= 2) {
302 if(bucket != NULL && bucket->is_wvalid) {
303 fAccess = bucket->is_writable;
304 goto Finished;
305 }
1bbc4f1 @pierrejoye - fix write access check when write mode only is requested (not RW)
pierrejoye authored
306 desired_access = FILE_GENERIC_WRITE;
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
307 } else if(mode <= 4) {
308 if(bucket != NULL && bucket->is_rvalid) {
309 fAccess = bucket->is_readable;
310 goto Finished;
311 }
056f0ae @pierrejoye - fix #49047, touch may fail on directory
pierrejoye authored
312 desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
313 } else { // if(mode <= 6)
314 if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
315 fAccess = bucket->is_readable & bucket->is_writable;
316 goto Finished;
317 }
318 desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
319 }
320
60223d6 @pierrejoye - #48535, file_exists returns false when impersonate is used
pierrejoye authored
321 if(TWG(impersonation_token) == NULL) {
322 goto Finished;
323 }
324
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
325 /* Get size of security buffer. Call is expected to fail */
326 if(GetFileSecurity(pathname, sec_info, NULL, 0, &sec_desc_length)) {
327 goto Finished;
328 }
329
330 psec_desc = (BYTE *)malloc(sec_desc_length);
331 if(psec_desc == NULL ||
332 !GetFileSecurity(pathname, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
333 goto Finished;
334 }
335
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
336 MapGenericMask(&desired_access, &gen_map);
337
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
338 if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
339 goto Finished_Impersonate;
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
340 }
341
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
342 /* Keep the result in realpath_cache */
343 if(bucket != NULL) {
6711276 @pierrejoye - fix ACL cache for read check
pierrejoye authored
344 if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
345 bucket->is_rvalid = 1;
346 bucket->is_readable = fAccess;
347 }
348 else if(desired_access == FILE_GENERIC_WRITE) {
349 bucket->is_wvalid = 1;
350 bucket->is_writable = fAccess;
3a239b1 @pierrejoye - silent warning
pierrejoye authored
351 } else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
1bbc4f1 @pierrejoye - fix write access check when write mode only is requested (not RW)
pierrejoye authored
352 bucket->is_rvalid = 1;
353 bucket->is_readable = fAccess;
354 bucket->is_wvalid = 1;
355 bucket->is_writable = fAccess;
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
356 }
357 }
358
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
359 Finished_Impersonate:
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
360 if(psec_desc != NULL) {
361 free(psec_desc);
362 psec_desc = NULL;
363 }
364
0304ec7 @pierrejoye - Fix ACL support and add support for ACL for TS SAPI. Be sure to get th...
pierrejoye authored
365 Finished:
18d5751 @pierrejoye - Windows ACL cache support, update existing tests and add a new one
pierrejoye authored
366 if(real_path != NULL) {
367 free(real_path);
368 real_path = NULL;
369 }
370
10ace3f @pierrejoye - #44859, fixed support for windows ACL, drop win9x code
pierrejoye authored
371 if(fAccess == FALSE) {
372 errno = EACCES;
373 return errno;
374 } else {
375 return 0;
376 }
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
377 }
378 }
379
380
95d3092 implement shm* similar functions
Daniel Beulshausen authored
381 static process_pair *process_get(FILE *stream TSRMLS_DC)
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
382 {
95d3092 implement shm* similar functions
Daniel Beulshausen authored
383 process_pair *ptr;
384 process_pair *newptr;
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
385
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
386 for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
112b906 adopt shane's popen patch
Daniel Beulshausen authored
387 if (ptr->stream == stream) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
388 break;
389 }
390 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
391
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
392 if (ptr < (TWG(process) + TWG(process_size))) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
393 return ptr;
394 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
395
95d3092 implement shm* similar functions
Daniel Beulshausen authored
396 newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
397 if (newptr == NULL) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
398 return NULL;
399 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
400
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
401 TWG(process) = newptr;
402 ptr = newptr + TWG(process_size);
403 TWG(process_size)++;
404 return ptr;
405 }
406
95d3092 implement shm* similar functions
Daniel Beulshausen authored
407 static shm_pair *shm_get(int key, void *addr)
408 {
409 shm_pair *ptr;
410 shm_pair *newptr;
411 TSRMLS_FETCH();
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
412
95d3092 implement shm* similar functions
Daniel Beulshausen authored
413 for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
414 if (!ptr->descriptor) {
415 continue;
416 }
417 if (!addr && ptr->descriptor->shm_perm.key == key) {
418 break;
419 } else if (ptr->addr == addr) {
420 break;
421 }
422 }
423
424 if (ptr < (TWG(shm) + TWG(shm_size))) {
425 return ptr;
426 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
427
95d3092 implement shm* similar functions
Daniel Beulshausen authored
428 newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
429 if (newptr == NULL) {
430 return NULL;
431 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
432
95d3092 implement shm* similar functions
Daniel Beulshausen authored
433 TWG(shm) = newptr;
434 ptr = newptr + TWG(shm_size);
435 TWG(shm_size)++;
436 return ptr;
437 }
438
112b906 adopt shane's popen patch
Daniel Beulshausen authored
439 static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
440 HANDLE copy, self = GetCurrentProcess();
441 if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
442 return NULL;
443 }
444 return copy;
445 }
446
1f3faae @zsuraski Nukre most TSRMLS_FETCH()'s in TSRM
zsuraski authored
447 TSRM_API FILE *popen(const char *command, const char *type)
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
448 {
b154864 @pierrejoye - drop tsrmls_fetch in popen_ex
pierrejoye authored
449 TSRMLS_FETCH();
450
451 return popen_ex(command, type, NULL, NULL TSRMLS_CC);
1f0523c windows is smart enough to provide a way to set cwd for new processes.
Shane Caraveo authored
452 }
453
b154864 @pierrejoye - drop tsrmls_fetch in popen_ex
pierrejoye authored
454 TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC)
1f0523c windows is smart enough to provide a way to set cwd for new processes.
Shane Caraveo authored
455 {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
456 FILE *stream = NULL;
bae3df7 @pierrejoye - fix #44683, popen crashes when an invalid mode is passed (works on 2k8...
pierrejoye authored
457 int fno, type_len = strlen(type), read, mode;
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
458 STARTUPINFO startup;
459 PROCESS_INFORMATION process;
460 SECURITY_ATTRIBUTES security;
461 HANDLE in, out;
49666ee @pierrejoye #41874, separate STDOUT and STDERR in exec functions
pierrejoye authored
462 DWORD dwCreateFlags = 0;
ddab8be @pierrejoye - #27051, create process as impersonated user
pierrejoye authored
463 BOOL res;
95d3092 implement shm* similar functions
Daniel Beulshausen authored
464 process_pair *proc;
05f86b6 @pierrejoye - revert fix for #43327, it breaks system&co functions
pierrejoye authored
465 char *cmd;
bae3df7 @pierrejoye - fix #44683, popen crashes when an invalid mode is passed (works on 2k8...
pierrejoye authored
466 int i;
467 char *ptype = (char *)type;
da9aee9 @pierrejoye - #27051, we need the thread token here, not the process
pierrejoye authored
468 HANDLE thread_token = NULL;
469 HANDLE token_user = NULL;
542c087 @pierrejoye - be sure that we use the user token by default (Christian Wenz)
pierrejoye authored
470 BOOL asuser = TRUE;
511c923 @pierrejoye - #27051, improve fix on xp/2k3
pierrejoye authored
471
bae3df7 @pierrejoye - fix #44683, popen crashes when an invalid mode is passed (works on 2k8...
pierrejoye authored
472 if (!type) {
473 return NULL;
474 }
475
476 /*The following two checks can be removed once we drop XP support */
477 type_len = strlen(type);
478 if (type_len <1 || type_len > 2) {
479 return NULL;
480 }
481
482 for (i=0; i < type_len; i++) {
483 if (!(*ptype == 'r' || *ptype == 'w' || *ptype == 'b' || *ptype == 't')) {
484 return NULL;
485 }
486 ptype++;
487 }
488
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
489 security.nLength = sizeof(SECURITY_ATTRIBUTES);
490 security.bInheritHandle = TRUE;
491 security.lpSecurityDescriptor = NULL;
492
bae3df7 @pierrejoye - fix #44683, popen crashes when an invalid mode is passed (works on 2k8...
pierrejoye authored
493 if (!type_len || !CreatePipe(&in, &out, &security, 2048L)) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
494 return NULL;
495 }
19322fc MFH: Fix bug when command is quoted and parameters are quoted during cal...
Scott MacVicar authored
496
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
497 memset(&startup, 0, sizeof(STARTUPINFO));
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
498 memset(&process, 0, sizeof(PROCESS_INFORMATION));
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
499
500 startup.cb = sizeof(STARTUPINFO);
501 startup.dwFlags = STARTF_USESTDHANDLES;
502 startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
503
504 read = (type[0] == 'r') ? TRUE : FALSE;
bae3df7 @pierrejoye - fix #44683, popen crashes when an invalid mode is passed (works on 2k8...
pierrejoye authored
505 mode = ((type_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
506
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
507 if (read) {
223c0a2 fix handle dup.
Daniel Beulshausen authored
508 in = dupHandle(in, FALSE);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
509 startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
510 startup.hStdOutput = out;
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
511 } else {
223c0a2 fix handle dup.
Daniel Beulshausen authored
512 out = dupHandle(out, FALSE);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
513 startup.hStdInput = in;
514 startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
515 }
516
49666ee @pierrejoye #41874, separate STDOUT and STDERR in exec functions
pierrejoye authored
517 dwCreateFlags = NORMAL_PRIORITY_CLASS;
518 if (strcmp(sapi_module.name, "cli") != 0) {
519 dwCreateFlags |= CREATE_NO_WINDOW;
520 }
521
da9aee9 @pierrejoye - #27051, we need the thread token here, not the process
pierrejoye authored
522 /* Get a token with the impersonated user. */
523 if(OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
524 DuplicateTokenEx(thread_token, MAXIMUM_ALLOWED, &security, SecurityImpersonation, TokenPrimary, &token_user);
511c923 @pierrejoye - #27051, improve fix on xp/2k3
pierrejoye authored
525 } else {
526 DWORD err = GetLastError();
527 if (err == ERROR_NO_TOKEN) {
528 asuser = FALSE;
529 }
da9aee9 @pierrejoye - #27051, we need the thread token here, not the process
pierrejoye authored
530 }
531
05f86b6 @pierrejoye - revert fix for #43327, it breaks system&co functions
pierrejoye authored
532 cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
b2e3d0a @pierrejoye - Fix #55295, check if malloc failed
pierrejoye authored
533 if (!cmd) {
534 return NULL;
535 }
536
05f86b6 @pierrejoye - revert fix for #43327, it breaks system&co functions
pierrejoye authored
537 sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
511c923 @pierrejoye - #27051, improve fix on xp/2k3
pierrejoye authored
538 if (asuser) {
539 res = CreateProcessAsUser(token_user, NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
540 CloseHandle(token_user);
541 } else {
542 res = CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
543 }
05f86b6 @pierrejoye - revert fix for #43327, it breaks system&co functions
pierrejoye authored
544 free(cmd);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
545
ddab8be @pierrejoye - #27051, create process as impersonated user
pierrejoye authored
546 if (!res) {
547 return NULL;
548 }
549
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
550 CloseHandle(process.hThread);
1f3faae @zsuraski Nukre most TSRMLS_FETCH()'s in TSRM
zsuraski authored
551 proc = process_get(NULL TSRMLS_CC);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
552
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
553 if (read) {
e1814f0 WIN64 support
Dmitry Stogov authored
554 fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
555 CloseHandle(out);
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
556 } else {
e1814f0 WIN64 support
Dmitry Stogov authored
557 fno = _open_osfhandle((tsrm_intptr_t)out, _O_WRONLY | mode);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
558 CloseHandle(in);
559 }
560
561 stream = _fdopen(fno, type);
562 proc->prochnd = process.hProcess;
563 proc->stream = stream;
564 return stream;
565 }
566
1f3faae @zsuraski Nukre most TSRMLS_FETCH()'s in TSRM
zsuraski authored
567 TSRM_API int pclose(FILE *stream)
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
568 {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
569 DWORD termstat = 0;
95d3092 implement shm* similar functions
Daniel Beulshausen authored
570 process_pair *process;
1f3faae @zsuraski Nukre most TSRMLS_FETCH()'s in TSRM
zsuraski authored
571 TSRMLS_FETCH();
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
572
1f3faae @zsuraski Nukre most TSRMLS_FETCH()'s in TSRM
zsuraski authored
573 if ((process = process_get(stream TSRMLS_CC)) == NULL) {
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
574 return 0;
575 }
576
577 fflush(process->stream);
59a6d8d @pierrejoye - WS
pierrejoye authored
578 fclose(process->stream);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
579
112b906 adopt shane's popen patch
Daniel Beulshausen authored
580 WaitForSingleObject(process->prochnd, INFINITE);
1b279d3 get rid of MS's _popen/_pclose
Daniel Beulshausen authored
581 GetExitCodeProcess(process->prochnd, &termstat);
582 process->stream = NULL;
583 CloseHandle(process->prochnd);
584
585 return termstat;
586 }
a2dbc5b @andigutmans - Fix some ws to be like the rest of TSRM
andigutmans authored
587
95d3092 implement shm* similar functions
Daniel Beulshausen authored
588 TSRM_API int shmget(int key, int size, int flags)
589 {
590 shm_pair *shm;
591 char shm_segment[26], shm_info[29];
592 HANDLE shm_handle, info_handle;
593 BOOL created = FALSE;
594
595 if (size < 0) {
596 return -1;
597 }
598
b415e3d @smalyshev Unfortunately, VC does not have snprintf, and sprintf_s supported only i...
smalyshev authored
599 sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
600 sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
95d3092 implement shm* similar functions
Daniel Beulshausen authored
601
602 shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
603 info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
604
605 if ((!shm_handle && !info_handle)) {
606 if (flags & IPC_CREAT) {
607 shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
608 info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
609 created = TRUE;
610 }
611 if ((!shm_handle || !info_handle)) {
612 return -1;
613 }
17d8912 @tony2001 MFH: fix shmop_open() with IPC_CREAT|IPC_EXCL flags on win32
tony2001 authored
614 } else {
615 if (flags & IPC_EXCL) {
616 return -1;
617 }
95d3092 implement shm* similar functions
Daniel Beulshausen authored
618 }
619
620 shm = shm_get(key, NULL);
621 shm->segment = shm_handle;
622 shm->info = info_handle;
623 shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
624
625 if (created) {
626 shm->descriptor->shm_perm.key = key;
627 shm->descriptor->shm_segsz = size;
628 shm->descriptor->shm_ctime = time(NULL);
629 shm->descriptor->shm_cpid = getpid();
630 shm->descriptor->shm_perm.mode = flags;
631
632 shm->descriptor->shm_perm.cuid = shm->descriptor->shm_perm.cgid= 0;
633 shm->descriptor->shm_perm.gid = shm->descriptor->shm_perm.uid = 0;
634 shm->descriptor->shm_atime = shm->descriptor->shm_dtime = 0;
635 shm->descriptor->shm_lpid = shm->descriptor->shm_nattch = 0;
636 shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
637 }
638
639 if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
640 CloseHandle(shm->segment);
641 UnmapViewOfFile(shm->descriptor);
642 CloseHandle(shm->info);
643 return -1;
644 }
645
646 return key;
647 }
648
649 TSRM_API void *shmat(int key, const void *shmaddr, int flags)
650 {
651 shm_pair *shm = shm_get(key, NULL);
652
653 if (!shm->segment) {
654 return (void*)-1;
655 }
656
657 shm->descriptor->shm_atime = time(NULL);
658 shm->descriptor->shm_lpid = getpid();
659 shm->descriptor->shm_nattch++;
660
661 shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
662
663 return shm->addr;
664 }
665
666 TSRM_API int shmdt(const void *shmaddr)
667 {
668 shm_pair *shm = shm_get(0, (void*)shmaddr);
669
670 if (!shm->segment) {
671 return -1;
672 }
673
674 shm->descriptor->shm_dtime = time(NULL);
675 shm->descriptor->shm_lpid = getpid();
676 shm->descriptor->shm_nattch--;
677
678 return UnmapViewOfFile(shm->addr) ? 0 : -1;
679 }
680
681 TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
682 shm_pair *shm = shm_get(key, NULL);
683
684 if (!shm->segment) {
685 return -1;
686 }
687
688 switch (cmd) {
689 case IPC_STAT:
a118a1e fix buffer size
Daniel Beulshausen authored
690 memcpy(buf, shm->descriptor, sizeof(struct shmid_ds));
95d3092 implement shm* similar functions
Daniel Beulshausen authored
691 return 0;
692
693 case IPC_SET:
694 shm->descriptor->shm_ctime = time(NULL);
695 shm->descriptor->shm_perm.uid = buf->shm_perm.uid;
696 shm->descriptor->shm_perm.gid = buf->shm_perm.gid;
697 shm->descriptor->shm_perm.mode = buf->shm_perm.mode;
698 return 0;
699
700 case IPC_RMID:
701 if (shm->descriptor->shm_nattch < 1) {
702 shm->descriptor->shm_perm.key = -1;
703 }
704 return 0;
705
706 default:
707 return -1;
708 }
709 }
1a773f1 @smalyshev MF4: add realpath function for win32
smalyshev authored
710
711 TSRM_API char *realpath(char *orig_path, char *buffer)
712 {
1600253 @andigutmans - Fix indentation
andigutmans authored
713 int ret = GetFullPathName(orig_path, _MAX_PATH, buffer, NULL);
714 if(!ret || ret > _MAX_PATH) {
715 return NULL;
716 }
717 return buffer;
1a773f1 @smalyshev MF4: add realpath function for win32
smalyshev authored
718 }
1600253 @andigutmans - Fix indentation
andigutmans authored
719
60ffd0e Restore HEAD of TSRM to what it was two days ago.
Sebastian Bergmann authored
720 #endif
Something went wrong with that request. Please try again.