|
14 | 14 | #include "win32/w32_buffer.h" |
15 | 15 | #include "win32/w32_util.h" |
16 | 16 | #include "win32/version.h" |
| 17 | +#include <AclAPI.h> |
17 | 18 | #else |
18 | 19 | #include <dirent.h> |
19 | 20 | #endif |
@@ -1946,3 +1947,79 @@ bool git_path_supports_symlinks(const char *dir) |
1946 | 1947 | git_buf_dispose(&path); |
1947 | 1948 | return supported; |
1948 | 1949 | } |
| 1950 | + |
| 1951 | +int git_path_validate_system_file_ownership(const char *path) |
| 1952 | +{ |
| 1953 | +#ifndef GIT_WIN32 |
| 1954 | + GIT_UNUSED(path); |
| 1955 | + return GIT_OK; |
| 1956 | +#else |
| 1957 | + git_win32_path buf; |
| 1958 | + PSID owner_sid; |
| 1959 | + PSECURITY_DESCRIPTOR descriptor = NULL; |
| 1960 | + HANDLE token; |
| 1961 | + TOKEN_USER *info = NULL; |
| 1962 | + DWORD err, len; |
| 1963 | + int ret; |
| 1964 | + |
| 1965 | + if (git_win32_path_from_utf8(buf, path) < 0) |
| 1966 | + return -1; |
| 1967 | + |
| 1968 | + err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT, |
| 1969 | + OWNER_SECURITY_INFORMATION | |
| 1970 | + DACL_SECURITY_INFORMATION, |
| 1971 | + &owner_sid, NULL, NULL, NULL, &descriptor); |
| 1972 | + |
| 1973 | + if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { |
| 1974 | + ret = GIT_ENOTFOUND; |
| 1975 | + goto cleanup; |
| 1976 | + } |
| 1977 | + |
| 1978 | + if (err != ERROR_SUCCESS) { |
| 1979 | + git_error_set(GIT_ERROR_OS, "failed to get security information"); |
| 1980 | + ret = GIT_ERROR; |
| 1981 | + goto cleanup; |
| 1982 | + } |
| 1983 | + |
| 1984 | + if (!IsValidSid(owner_sid)) { |
| 1985 | + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown"); |
| 1986 | + ret = GIT_ERROR; |
| 1987 | + goto cleanup; |
| 1988 | + } |
| 1989 | + |
| 1990 | + if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) || |
| 1991 | + IsWellKnownSid(owner_sid, WinLocalSystemSid)) { |
| 1992 | + ret = GIT_OK; |
| 1993 | + goto cleanup; |
| 1994 | + } |
| 1995 | + |
| 1996 | + /* Obtain current user's SID */ |
| 1997 | + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) && |
| 1998 | + !GetTokenInformation(token, TokenUser, NULL, 0, &len)) { |
| 1999 | + info = git__malloc(len); |
| 2000 | + GIT_ERROR_CHECK_ALLOC(info); |
| 2001 | + if (!GetTokenInformation(token, TokenUser, info, len, &len)) { |
| 2002 | + git__free(info); |
| 2003 | + info = NULL; |
| 2004 | + } |
| 2005 | + } |
| 2006 | + |
| 2007 | + /* |
| 2008 | + * If the file is owned by the same account that is running the current |
| 2009 | + * process, it's okay to read from that file. |
| 2010 | + */ |
| 2011 | + if (info && EqualSid(owner_sid, info->User.Sid)) |
| 2012 | + ret = GIT_OK; |
| 2013 | + else { |
| 2014 | + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid"); |
| 2015 | + ret = GIT_ERROR; |
| 2016 | + } |
| 2017 | + free(info); |
| 2018 | + |
| 2019 | +cleanup: |
| 2020 | + if (descriptor) |
| 2021 | + LocalFree(descriptor); |
| 2022 | + |
| 2023 | + return ret; |
| 2024 | +#endif |
| 2025 | +} |
0 commit comments