http://bugs.winehq.org/show_bug.cgi?id=18980
Summary: Canon's CONSOLE Image Control & Storage Software fails on administrator privs check Product: Wine Version: 1.1.23 Platform: PC URL: http://www.usa.canon.com/consumer/controller?act=Model InfoAct&tabact=DownloadDetailTabAct&fcategoryid=326&mo delid=10350 OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: advapi32 AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net
Hello,
a user in #winehq came up with this problem, so I looked into it knowing the app won't work at all due to low level hardware driver dependency.
Anyway it revealed at least a valid bug ;-)
--- snip --- ... 0028:Call advapi32.OpenProcessToken(ffffffff,00000018,0032fce4) ret=0046fa9e 0028:Ret advapi32.OpenProcessToken() retval=00000001 ret=0046fa9e 0028:Call advapi32.GetTokenInformation(000000a8,00000002,00000000,00000000,0032fce0) ret=0046fac3 0028:trace:advapi:GetTokenInformation (0xa8, TokenGroups, (nil), 0, 0x32fce0): 0028:Ret advapi32.GetTokenInformation() retval=00000000 ret=0046fac3 0028:Call msvcrt.malloc(000000a0) ret=5f8038d6 0028:Call ntdll.RtlAllocateHeap(00110000,00000000,000000a0) ret=7ed2d867 0028:Ret ntdll.RtlAllocateHeap() retval=00159260 ret=7ed2d867 0028:Ret msvcrt.malloc() retval=00159260 ret=5f8038d6 0028:Call advapi32.GetTokenInformation(000000a8,00000002,00159260,000000a0,0032fce0) ret=0046faef 0028:trace:advapi:GetTokenInformation (0xa8, TokenGroups, 0x159260, 160, 0x32fce0): 0028:Ret advapi32.GetTokenInformation() retval=00000001 ret=0046faef 0028:Call advapi32.GetSidSubAuthorityCount(0015929c) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=0015929d ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592a8) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592a9 ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592b4) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592b5 ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592c0) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592c1 ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592cc) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592cd ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592dc) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592dd ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call advapi32.GetSidSubAuthorityCount(001592ec) ret=0046fb10 0028:Ret advapi32.GetSidSubAuthorityCount() retval=001592ed ret=0046fb10 0028:Call KERNEL32.GetLastError() ret=0046fb20 0028:Ret KERNEL32.GetLastError() retval=0000007a ret=0046fb20 0028:Call msvcrt.free(00159260) ret=5f8048cf 0028:Call ntdll.RtlFreeHeap(00110000,00000000,00159260) ret=7ed2da36 0028:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7ed2da36 0028:Ret msvcrt.free() retval=00000001 ret=5f8048cf ... 0028:Call user32.MessageBoxW(00000000,00159560 L"This program requires administrator privileges.",00157d48 L"CONSOLE",00000040) ret=5f86881e --- snip ---
With the first call to GetTokenInformation( ... TokenGroups ... ) the app queries the buffer size to hold result data -> lasterror = ERROR_INSUFFICIENT_BUFFER. The app allocates the required buffer and then calls GetTokenInformation() to actually fetch the data.
Next, the app loops through sub authorities using GetSidSubAuthorityCount(). Normally it would look for DOMAIN_ALIAS_RID_ADMINS but the problem is the GetLastError() call _before_ the actual comparison. If last error is != 0, the app won't look at data returned by GetSidSubAuthorityCount().
The last successful call to GetTokenInformation() didn't reset last error at all - it's still at ERROR_INSUFFICIENT_BUFFER:
--- snip dlls/advapi32/security.c --- BOOL WINAPI GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass, LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen ) { ... return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength, retlen)); } --- snip dlls/advapi32/security.c ---
--- snip dlls/advapi32/security.c --- /* set last error code from NT status and get the proper boolean return value */ /* used for functions that are a simple wrapper around the corresponding ntdll API */ static inline BOOL set_ntstatus( NTSTATUS status ) { if (status) SetLastError( RtlNtStatusToDosError( status )); return !status; } --- snip dlls/advapi32/security.c ---
This is probably an oversight. I don't know what Windows does but the app seems to expect the last error being reset to zero (NTSTATUS success). A conformance test should reveal this.
Regards