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"
@@ -1062,6 +1063,7 @@ int pipe(int filedes[2])
1062
1063
return 0 ;
1063
1064
}
1064
1065
1066
+ #ifndef __MINGW64__
1065
1067
struct tm * gmtime_r (const time_t * timep , struct tm * result )
1066
1068
{
1067
1069
if (gmtime_s (result , timep ) == 0 )
@@ -1075,6 +1077,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
1075
1077
return result ;
1076
1078
return NULL ;
1077
1079
}
1080
+ #endif
1078
1081
1079
1082
char * mingw_getcwd (char * pointer , int len )
1080
1083
{
@@ -2601,6 +2604,92 @@ static void setup_windows_environment(void)
2601
2604
}
2602
2605
}
2603
2606
2607
+ static PSID get_current_user_sid (void )
2608
+ {
2609
+ HANDLE token ;
2610
+ DWORD len = 0 ;
2611
+ PSID result = NULL ;
2612
+
2613
+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & token ))
2614
+ return NULL ;
2615
+
2616
+ if (!GetTokenInformation (token , TokenUser , NULL , 0 , & len )) {
2617
+ TOKEN_USER * info = xmalloc ((size_t )len );
2618
+ if (GetTokenInformation (token , TokenUser , info , len , & len )) {
2619
+ len = GetLengthSid (info -> User .Sid );
2620
+ result = xmalloc (len );
2621
+ if (!CopySid (len , result , info -> User .Sid )) {
2622
+ error (_ ("failed to copy SID (%ld)" ),
2623
+ GetLastError ());
2624
+ FREE_AND_NULL (result );
2625
+ }
2626
+ }
2627
+ FREE_AND_NULL (info );
2628
+ }
2629
+ CloseHandle (token );
2630
+
2631
+ return result ;
2632
+ }
2633
+
2634
+ int is_path_owned_by_current_sid (const char * path )
2635
+ {
2636
+ WCHAR wpath [MAX_PATH ];
2637
+ PSID sid = NULL ;
2638
+ PSECURITY_DESCRIPTOR descriptor = NULL ;
2639
+ DWORD err ;
2640
+
2641
+ static wchar_t home [MAX_PATH ];
2642
+
2643
+ int result = 0 ;
2644
+
2645
+ if (xutftowcs_path (wpath , path ) < 0 )
2646
+ return 0 ;
2647
+
2648
+ /*
2649
+ * On Windows, the home directory is owned by the administrator, but for
2650
+ * all practical purposes, it belongs to the user. Do pretend that it is
2651
+ * owned by the user.
2652
+ */
2653
+ if (!* home ) {
2654
+ DWORD size = ARRAY_SIZE (home );
2655
+ DWORD len = GetEnvironmentVariableW (L"HOME" , home , size );
2656
+ if (!len || len > size )
2657
+ wcscpy (home , L"::N/A::" );
2658
+ }
2659
+ if (!wcsicmp (wpath , home ))
2660
+ return 1 ;
2661
+
2662
+ /* Get the owner SID */
2663
+ err = GetNamedSecurityInfoW (wpath , SE_FILE_OBJECT ,
2664
+ OWNER_SECURITY_INFORMATION |
2665
+ DACL_SECURITY_INFORMATION ,
2666
+ & sid , NULL , NULL , NULL , & descriptor );
2667
+
2668
+ if (err != ERROR_SUCCESS )
2669
+ error (_ ("failed to get owner for '%s' (%ld)" ), path , err );
2670
+ else if (sid && IsValidSid (sid )) {
2671
+ /* Now, verify that the SID matches the current user's */
2672
+ static PSID current_user_sid ;
2673
+
2674
+ if (!current_user_sid )
2675
+ current_user_sid = get_current_user_sid ();
2676
+
2677
+ if (current_user_sid &&
2678
+ IsValidSid (current_user_sid ) &&
2679
+ EqualSid (sid , current_user_sid ))
2680
+ result = 1 ;
2681
+ }
2682
+
2683
+ /*
2684
+ * We can release the security descriptor struct only now because `sid`
2685
+ * actually points into this struct.
2686
+ */
2687
+ if (descriptor )
2688
+ LocalFree (descriptor );
2689
+
2690
+ return result ;
2691
+ }
2692
+
2604
2693
int is_valid_win32_path (const char * path , int allow_literal_nul )
2605
2694
{
2606
2695
const char * p = path ;
0 commit comments