1
#include "../git-compat-util.h"
2
#include "win32.h"
3
+#include <aclapi.h>
4
#include <conio.h>
5
#include <wchar.h>
6
#include "../strbuf.h"
2602
}
2603
}
2604
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
+
2691
int is_valid_win32_path(const char *path, int allow_literal_nul)
2692
{
2693
const char *p = path;