11#include "../git-compat-util.h"
22#include "win32.h"
3+ #include <aclapi.h>
34#include <conio.h>
45#include <wchar.h>
56#include "../strbuf.h"
@@ -1060,6 +1061,7 @@ int pipe(int filedes[2])
10601061 return 0 ;
10611062}
10621063
1064+ #ifndef __MINGW64__
10631065struct tm * gmtime_r (const time_t * timep , struct tm * result )
10641066{
10651067 if (gmtime_s (result , timep ) == 0 )
@@ -1073,6 +1075,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
10731075 return result ;
10741076 return NULL ;
10751077}
1078+ #endif
10761079
10771080char * mingw_getcwd (char * pointer , int len )
10781081{
@@ -2599,6 +2602,92 @@ static void setup_windows_environment(void)
25992602 }
26002603}
26012604
2605+ static PSID get_current_user_sid (void )
2606+ {
2607+ HANDLE token ;
2608+ DWORD len = 0 ;
2609+ PSID result = NULL ;
2610+
2611+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & token ))
2612+ return NULL ;
2613+
2614+ if (!GetTokenInformation (token , TokenUser , NULL , 0 , & len )) {
2615+ TOKEN_USER * info = xmalloc ((size_t )len );
2616+ if (GetTokenInformation (token , TokenUser , info , len , & len )) {
2617+ len = GetLengthSid (info -> User .Sid );
2618+ result = xmalloc (len );
2619+ if (!CopySid (len , result , info -> User .Sid )) {
2620+ error (_ ("failed to copy SID (%ld)" ),
2621+ GetLastError ());
2622+ FREE_AND_NULL (result );
2623+ }
2624+ }
2625+ FREE_AND_NULL (info );
2626+ }
2627+ CloseHandle (token );
2628+
2629+ return result ;
2630+ }
2631+
2632+ int is_path_owned_by_current_sid (const char * path )
2633+ {
2634+ WCHAR wpath [MAX_PATH ];
2635+ PSID sid = NULL ;
2636+ PSECURITY_DESCRIPTOR descriptor = NULL ;
2637+ DWORD err ;
2638+
2639+ static wchar_t home [MAX_PATH ];
2640+
2641+ int result = 0 ;
2642+
2643+ if (xutftowcs_path (wpath , path ) < 0 )
2644+ return 0 ;
2645+
2646+ /*
2647+ * On Windows, the home directory is owned by the administrator, but for
2648+ * all practical purposes, it belongs to the user. Do pretend that it is
2649+ * owned by the user.
2650+ */
2651+ if (!* home ) {
2652+ DWORD size = ARRAY_SIZE (home );
2653+ DWORD len = GetEnvironmentVariableW (L"HOME" , home , size );
2654+ if (!len || len > size )
2655+ wcscpy (home , L"::N/A::" );
2656+ }
2657+ if (!wcsicmp (wpath , home ))
2658+ return 1 ;
2659+
2660+ /* Get the owner SID */
2661+ err = GetNamedSecurityInfoW (wpath , SE_FILE_OBJECT ,
2662+ OWNER_SECURITY_INFORMATION |
2663+ DACL_SECURITY_INFORMATION ,
2664+ & sid , NULL , NULL , NULL , & descriptor );
2665+
2666+ if (err != ERROR_SUCCESS )
2667+ error (_ ("failed to get owner for '%s' (%ld)" ), path , err );
2668+ else if (sid && IsValidSid (sid )) {
2669+ /* Now, verify that the SID matches the current user's */
2670+ static PSID current_user_sid ;
2671+
2672+ if (!current_user_sid )
2673+ current_user_sid = get_current_user_sid ();
2674+
2675+ if (current_user_sid &&
2676+ IsValidSid (current_user_sid ) &&
2677+ EqualSid (sid , current_user_sid ))
2678+ result = 1 ;
2679+ }
2680+
2681+ /*
2682+ * We can release the security descriptor struct only now because `sid`
2683+ * actually points into this struct.
2684+ */
2685+ if (descriptor )
2686+ LocalFree (descriptor );
2687+
2688+ return result ;
2689+ }
2690+
26022691int is_valid_win32_path (const char * path , int allow_literal_nul )
26032692{
26042693 const char * p = path ;
0 commit comments