Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Windows time zone specs request SeTimeZonePrivilege properly #14297

Merged
merged 3 commits into from
Feb 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions spec/support/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ end

TokenPrivileges = 3

SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001_u32
SE_PRIVILEGE_ENABLED = 0x00000002_u32
SE_PRIVILEGE_ENABLED = 0x00000002_u32

fun OpenProcessToken(processHandle : HANDLE, desiredAccess : DWORD, tokenHandle : HANDLE*) : BOOL
fun GetTokenInformation(tokenHandle : HANDLE, tokenInformationClass : Int, tokenInformation : Void*, tokenInformationLength : DWORD, returnLength : DWORD*) : BOOL
Expand All @@ -78,19 +77,25 @@ end
raise RuntimeError.from_winerror("LookupPrivilegeValueW")
end

# if the process token already has the privilege, and the privilege is already enabled,
# we don't need to do anything else
if LibC.OpenProcessToken(LibC.GetCurrentProcess, LibC::TOKEN_QUERY, out token) != 0
begin
LibC.GetTokenInformation(token, LibC::TokenPrivileges, nil, 0, out len)
buf = Pointer(UInt8).malloc(len).as(LibC::TOKEN_PRIVILEGES*)
LibC.GetTokenInformation(token, LibC::TokenPrivileges, buf, len, out _)
privileges = Slice.new(pointerof(buf.value.@privileges).as(LibC::LUID_AND_ATTRIBUTES*), buf.value.privilegeCount)
return true if privileges.any? { |pr| pr.luid == time_zone_luid && pr.attributes & (LibC::SE_PRIVILEGE_ENABLED_BY_DEFAULT | LibC::SE_PRIVILEGE_ENABLED) != 0 }
# if the process token doesn't have the privilege, there is no way
# `AdjustTokenPrivileges` could grant or enable it
privilege = privileges.find(&.luid.== time_zone_luid)
return false unless privilege
return true if privilege.attributes.bits_set?(LibC::SE_PRIVILEGE_ENABLED)
ensure
LibC.CloseHandle(token)
end
end

if LibC.OpenProcessToken(LibC.GetCurrentProcess, LibC::TOKEN_ADJUST_PRIVILEGES | LibC::TOKEN_QUERY, out adjust_token) != 0
if LibC.OpenProcessToken(LibC.GetCurrentProcess, LibC::TOKEN_ADJUST_PRIVILEGES, out adjust_token) != 0
new_privileges = LibC::TOKEN_PRIVILEGES.new(
privilegeCount: 1,
privileges: StaticArray[
Expand All @@ -101,7 +106,7 @@ end
],
)
if LibC.AdjustTokenPrivileges(adjust_token, 0, pointerof(new_privileges), 0, nil, nil) != 0
return true
return true if WinError.value.error_success?
end
end

Expand Down
Loading