1
1
#include "../git-compat-util.h"
2
2
#include "win32.h"
3
+ #include <aclapi.h>
3
4
#include <conio.h>
4
5
#include <wchar.h>
5
6
#include "../strbuf.h"
@@ -1083,6 +1084,7 @@ int pipe(int filedes[2])
1083
1084
return 0 ;
1084
1085
}
1085
1086
1087
+ #ifndef __MINGW64__
1086
1088
struct tm * gmtime_r (const time_t * timep , struct tm * result )
1087
1089
{
1088
1090
if (gmtime_s (result , timep ) == 0 )
@@ -1096,6 +1098,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
1096
1098
return result ;
1097
1099
return NULL ;
1098
1100
}
1101
+ #endif
1099
1102
1100
1103
char * mingw_getcwd (char * pointer , int len )
1101
1104
{
@@ -2622,6 +2625,92 @@ static void setup_windows_environment(void)
2622
2625
}
2623
2626
}
2624
2627
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
+
2625
2714
int is_valid_win32_path (const char * path , int allow_literal_nul )
2626
2715
{
2627
2716
const char * p = path ;
0 commit comments