View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005040 | JEDI Code Library | JclSysInfo | public | 2009-12-02 17:12 | 2009-12-17 10:18 |
Reporter | HeikoAdams | Assigned To | outchy | ||
Priority | normal | Severity | feature | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Desktop Workstation | OS | Windows 7 | OS Version | 6.1 Build 7600 |
Product Version | Version 2.1 | ||||
Target Version | Fixed in Version | Version 2.2 | |||
Summary | 0005040: New Function: IsPowerUser | ||||
Description | The following function is copy of IsAdministrator but modified to check if the logged-in user is member of the powerusers group. function IsPowerUser: Boolean; var psidAdmin: Pointer; Token: THandle; Count: DWORD; TokenInfo: PTokenGroups; HaveToken: Boolean; I: Integer; const SE_GROUP_USE_FOR_DENY_ONLY = $00000010; begin Result := (IsWinVista or IsWin7); if Result then Exit; psidAdmin := nil; TokenInfo := nil; HaveToken := False; try Token := 0; HaveToken := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token); if (not HaveToken) and (GetLastError = ERROR_NO_TOKEN) then HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token); if HaveToken then begin {$IFDEF FPC} Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, psidAdmin)); if GetTokenInformation(Token, TokenGroups, nil, 0, @Count) or (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then RaiseLastOSError; TokenInfo := PTokenGroups(AllocMem(Count)); Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, @Count)); {$ELSE FPC} Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, psidAdmin)); if GetTokenInformation(Token, TokenGroups, nil, 0, Count) or (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then RaiseLastOSError; TokenInfo := PTokenGroups(AllocMem(Count)); Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, Count)); {$ENDIF FPC} for I := 0 to TokenInfo^.GroupCount - 1 do begin {$RANGECHECKS OFF} // Groups is an array [0..0] of TSIDAndAttributes, ignore ERangeError Result := EqualSid(psidAdmin, TokenInfo^.Groups[I].Sid); if Result then begin //consider denied ACE with Administrator SID Result := TokenInfo^.Groups[I].Attributes and SE_GROUP_USE_FOR_DENY_ONLY <> SE_GROUP_USE_FOR_DENY_ONLY; Break; end; {$IFDEF RANGECHECKS_ON} {$RANGECHECKS ON} {$ENDIF RANGECHECKS_ON} end; end; finally if TokenInfo <> nil then FreeMem(TokenInfo); if HaveToken then CloseHandle(Token); if psidAdmin <> nil then FreeSid(psidAdmin); end; end; | ||||
Tags | IsPowerUser, JclSysInfo | ||||
Fixed in GIT commit | |||||
Fixed in SVN revision | 3091 | ||||
IDE version | BDS 2006 | ||||
|
Update: Return true if logged in user is admin function IsPowerUser: Boolean; var psidAdmin: Pointer; Token: THandle; Count: DWORD; TokenInfo: PTokenGroups; HaveToken: Boolean; I: Integer; const SE_GROUP_USE_FOR_DENY_ONLY = $00000010; begin Result := (IsWinVista or IsWin7) or IsAdministrator; if Result then Exit; psidAdmin := nil; TokenInfo := nil; HaveToken := False; try Token := 0; HaveToken := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token); if (not HaveToken) and (GetLastError = ERROR_NO_TOKEN) then HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token); if HaveToken then begin {$IFDEF FPC} Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, psidAdmin)); if GetTokenInformation(Token, TokenGroups, nil, 0, @Count) or (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then RaiseLastOSError; TokenInfo := PTokenGroups(AllocMem(Count)); Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, @Count)); {$ELSE FPC} Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, psidAdmin)); if GetTokenInformation(Token, TokenGroups, nil, 0, Count) or (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then RaiseLastOSError; TokenInfo := PTokenGroups(AllocMem(Count)); Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, Count)); {$ENDIF FPC} for I := 0 to TokenInfo^.GroupCount - 1 do begin {$RANGECHECKS OFF} // Groups is an array [0..0] of TSIDAndAttributes, ignore ERangeError Result := EqualSid(psidAdmin, TokenInfo^.Groups[I].Sid); if Result then begin //consider denied ACE with Administrator SID Result := TokenInfo^.Groups[I].Attributes and SE_GROUP_USE_FOR_DENY_ONLY <> SE_GROUP_USE_FOR_DENY_ONLY; Break; end; {$IFDEF RANGECHECKS_ON} {$RANGECHECKS ON} {$ENDIF RANGECHECKS_ON} end; end; finally if TokenInfo <> nil then FreeMem(TokenInfo); if HaveToken then CloseHandle(Token); if psidAdmin <> nil then FreeSid(psidAdmin); end; end; |
|
I don't think this function should return true when the user is an administrator. |
|
IMHO it should return true because a admin is higher than a poweruser. Maybe the description should be modified to "checks if the logged-in user is member of the powerusers- or admintrators-group." I can't see any practical reaseon why it should return false if the logged-in user is administrator. |
|
You're mixing user groups and group rights. A user can be a member of the administrator group, while it is not a member of the poweruser group, while the security strategy gives him all the rights superusers have. the function should return whether the user is a member of the poweruser group or not, it should not make hypotheses on whether the administrator rights are a superset of the superuser rights. Anyway we can introduce a new function IsPowerUserOrAdministrator that will behave like the one you proposed. |
|
Okay, you're right. So just forget the update and let's use the function from the first post ;-) |
|
committed in revision 3091. I refactored the code to avoid duplicates and generalized to all group aliases. All the new available functions are: function IsGroupMember(RelativeGroupID: DWORD): Boolean; function IsUser: Boolean; function IsGuest: Boolean; function IsPowerUser: Boolean; function IsAccountOperator: Boolean; function IsSystemOperator: Boolean; function IsPrintOperator: Boolean; function IsBackupOperator: Boolean; function IsReplicator: Boolean; function IsRASServer: Boolean; function IsPreWin2000CompAccess: Boolean; function IsRemoteDesktopUser: Boolean; function IsNetworkConfigurationOperator: Boolean; function IsIncomingForestTrustBuilder: Boolean; function IsMonitoringUser: Boolean; function IsLoggingUser: Boolean; function IsAuthorizationAccess: Boolean; function IsTSLicenseServer: Boolean; |
Date Modified | Username | Field | Change |
---|---|---|---|
2009-12-02 17:12 | HeikoAdams | New Issue | |
2009-12-02 17:12 | HeikoAdams | IDE version | => BDS 2006 |
2009-12-03 08:13 | HeikoAdams | Note Added: 0016922 | |
2009-12-03 08:13 | HeikoAdams | Tag Attached: JclSysInfo | |
2009-12-03 08:13 | HeikoAdams | Tag Attached: IsPowerUser | |
2009-12-03 08:27 | HeikoAdams | Note Edited: 0016922 | |
2009-12-03 21:31 | outchy | Note Added: 0016925 | |
2009-12-07 17:15 | HeikoAdams | Note Added: 0016976 | |
2009-12-07 20:00 | outchy | Note Added: 0016977 | |
2009-12-08 13:33 | HeikoAdams | Note Added: 0016980 | |
2009-12-08 22:23 | outchy | Note Added: 0016985 | |
2009-12-08 22:23 | outchy | Assigned To | => outchy |
2009-12-08 22:23 | outchy | Status | new => feedback |
2009-12-17 10:18 | outchy | Fixed in revision | => 3091 |
2009-12-17 10:18 | outchy | Status | feedback => resolved |
2009-12-17 10:18 | outchy | Fixed in Version | => Version 2.2 (Subversion repository/Daily zips) |
2009-12-17 10:18 | outchy | Resolution | open => fixed |