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"
@@ -1083,6 +1084,7 @@ int pipe(int filedes[2])
10831084 return 0 ;
10841085}
10851086
1087+ #ifndef __MINGW64__
10861088struct tm * gmtime_r (const time_t * timep , struct tm * result )
10871089{
10881090 if (gmtime_s (result , timep ) == 0 )
@@ -1096,6 +1098,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
10961098 return result ;
10971099 return NULL ;
10981100}
1101+ #endif
10991102
11001103char * mingw_getcwd (char * pointer , int len )
11011104{
@@ -2622,6 +2625,92 @@ static void setup_windows_environment(void)
26222625 }
26232626}
26242627
2628+ static PSID get_current_user_sid (void )
2629+ {
2630+ HANDLE token ;
2631+ DWORD len = 0 ;
2632+ PSID result = NULL ;
2633+
2634+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & token ))
2635+ return NULL ;
2636+
2637+ if (!GetTokenInformation (token , TokenUser , NULL , 0 , & len )) {
2638+ TOKEN_USER * info = xmalloc ((size_t )len );
2639+ if (GetTokenInformation (token , TokenUser , info , len , & len )) {
2640+ len = GetLengthSid (info -> User .Sid );
2641+ result = xmalloc (len );
2642+ if (!CopySid (len , result , info -> User .Sid )) {
2643+ error (_ ("failed to copy SID (%ld)" ),
2644+ GetLastError ());
2645+ FREE_AND_NULL (result );
2646+ }
2647+ }
2648+ FREE_AND_NULL (info );
2649+ }
2650+ CloseHandle (token );
2651+
2652+ return result ;
2653+ }
2654+
2655+ int is_path_owned_by_current_sid (const char * path )
2656+ {
2657+ WCHAR wpath [MAX_PATH ];
2658+ PSID sid = NULL ;
2659+ PSECURITY_DESCRIPTOR descriptor = NULL ;
2660+ DWORD err ;
2661+
2662+ static wchar_t home [MAX_PATH ];
2663+
2664+ int result = 0 ;
2665+
2666+ if (xutftowcs_path (wpath , path ) < 0 )
2667+ return 0 ;
2668+
2669+ /*
2670+ * On Windows, the home directory is owned by the administrator, but for
2671+ * all practical purposes, it belongs to the user. Do pretend that it is
2672+ * owned by the user.
2673+ */
2674+ if (!* home ) {
2675+ DWORD size = ARRAY_SIZE (home );
2676+ DWORD len = GetEnvironmentVariableW (L"HOME" , home , size );
2677+ if (!len || len > size )
2678+ wcscpy (home , L"::N/A::" );
2679+ }
2680+ if (!wcsicmp (wpath , home ))
2681+ return 1 ;
2682+
2683+ /* Get the owner SID */
2684+ err = GetNamedSecurityInfoW (wpath , SE_FILE_OBJECT ,
2685+ OWNER_SECURITY_INFORMATION |
2686+ DACL_SECURITY_INFORMATION ,
2687+ & sid , NULL , NULL , NULL , & descriptor );
2688+
2689+ if (err != ERROR_SUCCESS )
2690+ error (_ ("failed to get owner for '%s' (%ld)" ), path , err );
2691+ else if (sid && IsValidSid (sid )) {
2692+ /* Now, verify that the SID matches the current user's */
2693+ static PSID current_user_sid ;
2694+
2695+ if (!current_user_sid )
2696+ current_user_sid = get_current_user_sid ();
2697+
2698+ if (current_user_sid &&
2699+ IsValidSid (current_user_sid ) &&
2700+ EqualSid (sid , current_user_sid ))
2701+ result = 1 ;
2702+ }
2703+
2704+ /*
2705+ * We can release the security descriptor struct only now because `sid`
2706+ * actually points into this struct.
2707+ */
2708+ if (descriptor )
2709+ LocalFree (descriptor );
2710+
2711+ return result ;
2712+ }
2713+
26252714int is_valid_win32_path (const char * path , int allow_literal_nul )
26262715{
26272716 const char * p = path ;
0 commit comments