Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if user is an Administrator, even if non-elevated

In my C# application, I need to check if the current user is a member of the Administrators group. It needs to be compatible with both Windows XP and Windows 7.

Currently, I am using the following code:

bool IsAdministrator
{
    get
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);

        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

The problem is that this method returns false if the application is run on Windows 7 with UAC turned on as a non-elevated Administrator. How can I determine if the user is an Administrator even if the application is run as a non-elevated Administrator?

like image 479
markyd13 Avatar asked Apr 06 '12 14:04

markyd13


2 Answers

There is a Win32 API GetTokenInformation that can be used to check the current token. If the returned token is a split token, it probably is an administrator user that is running i non elevated mode.

GetTokenInformation has an output parameter tokenInformation which takes one of three values:

  • TokenElevationTypeDefault = 1
  • TokenElevationTypeFull = 2
  • TokenElevationTypeLimited = 3

A value of TokenElevantionTypeLimited indicates that the user is running with a split token with limited privileges. When elevated the TokenElevationTypeFull value is returned. Non-admin user has a value of TokenElevationTypeDefault.

There is a complete code example for C# at http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/

like image 180
Anders Abel Avatar answered Jan 03 '23 16:01

Anders Abel


For any VB.NET people (I know you're out there ...), here's a version that I concocted from various sources and is, I think, optimized to determine whether the current user (including elevated) is in a defined Administrators group, machine or domain, with or without UAC enabled. (Lots of credit to other posts here and elsewhere for this one!)

Firstly, it uses a static null-able Boolean to retain the Administrator status because, although the basic check is quick, the full test can take tens of seconds, so you only want to do it once - if at all if you can help it.

Secondly, it errs on the side of the basic test being incorrect/false, which is usually the case if the user is AD-administered or if the local machine has UAC enabled. So if it can decide a user is an Administrator, it will.

Thirdly, you can add or remove criteria from the AuthorizationGroups as you see fit but the ones included cover most situations.

Lastly, if anything goes wrong, you'll get False; if you want an error, you can have one, but personally I don't see the point.

Function IsAdministrator() As Boolean

    Static bResult As Boolean? = Nothing
    Try
        If bResult Is Nothing Then
            bResult = New WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)
            If Not bResult Then
                Dim oContext As PrincipalContext = Nothing
                Try 'to get a domain context first ...
                    Domain.GetComputerDomain()
                    oContext = New PrincipalContext(ContextType.Domain)
                Catch
                    '... if it fails, fall through to a machine context
                End Try
                If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
                Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name)
                If oPrincipal IsNot Nothing Then
                    bResult = oPrincipal.GetAuthorizationGroups().Any(Function(p) _
                        p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse
                        p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse
                        p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse
                        p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))
                End If
            End If
        End If
    Catch
        bResult = False
    End Try
    Return bResult.GetValueOrDefault(False)
End Function
like image 44
SteveCinq Avatar answered Jan 03 '23 17:01

SteveCinq