diff --git a/src/util/fs_path.c b/src/util/fs_path.c index ff0836ff8..5be2da35b 100644 --- a/src/util/fs_path.c +++ b/src/util/fs_path.c @@ -1853,12 +1853,16 @@ static PSID *sid_dup(PSID sid) return dup; } -static int current_user_sid(PSID *out) +static int current_user_sid(PSID *sid, HANDLE *linked_token) { TOKEN_USER *info = NULL; HANDLE token = NULL; DWORD len = 0; int error = -1; + TOKEN_ELEVATION_TYPE elevation_type; + DWORD size; + + *linked_token = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { git_error_set(GIT_ERROR_OS, "could not lookup process information"); @@ -1879,9 +1883,19 @@ static int current_user_sid(PSID *out) goto done; } - if ((*out = sid_dup(info->User.Sid))) + if ((*sid = sid_dup(info->User.Sid))) error = 0; + if (GetTokenInformation(token, TokenElevationType, &elevation_type, sizeof(elevation_type), &size) && + elevation_type == TokenElevationTypeLimited) { + /* + * The current process is run by a member of the Administrators group + * but is not running elevated. + */ + if (!GetTokenInformation(token, TokenLinkedToken, linked_token, sizeof(HANDLE), &size)) { + linked_token = NULL; + } + } done: if (token) CloseHandle(token); @@ -1926,6 +1940,7 @@ int git_fs_path_owner_is( git_fs_path_owner_t owner_type) { PSID owner_sid = NULL, user_sid = NULL; + static HANDLE linked_token; BOOL is_admin, admin_owned; int error; @@ -1938,7 +1953,7 @@ int git_fs_path_owner_is( goto done; if ((owner_type & GIT_FS_PATH_OWNER_CURRENT_USER) != 0) { - if ((error = current_user_sid(&user_sid)) < 0) + if ((error = current_user_sid(&user_sid, &linked_token)) < 0) goto done; if (EqualSid(owner_sid, user_sid)) { @@ -1959,7 +1974,8 @@ int git_fs_path_owner_is( if (admin_owned && (owner_type & GIT_FS_PATH_USER_IS_ADMINISTRATOR) != 0 && - CheckTokenMembership(NULL, owner_sid, &is_admin) && + (CheckTokenMembership(NULL, owner_sid, &is_admin) && + CheckTokenMembership(linked_token, owner_sid, &is_admin)) && is_admin) { *out = true; goto done;