Click here to Skip to main content
15,883,901 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi
i have a Local System service that is running currently which launches an application as it should do for each of their users logged and works as expected however the problem i have now is that i am trying to prevent it from running as 'Administrators' / 'Domain Admins'

It has to run as 'Local Service' as it requires the SE_TCB_NAME privilege.

Everything works as it should other than the WindowsIdentity/WindowsPrincipal Calls all return false for each of the principal's/

Ses.SecureToken is the users token, the following section returns the correct username of the of the session so i know that the WindowsIdentity is correct and has identified it correct:
VB
Dim EventLogText As String = wi.User.Translate(GetType(NTAccount)).ToString



Here is a code snippet from what i am trying to do and below is the event log output:
VB
For Each Ses As clsGetLoggedInSessions.LoggedInInfo In liSessions.Sessions
    'Is the State in Active State
    If (Ses.ConnectionState = WTS_CONNECTSTATE_CLASS.WTSActive) Then
        Dim wi As WindowsIdentity = New WindowsIdentity(Ses.SecurityToken)
        Dim wp As WindowsPrincipal

        wp = New WindowsPrincipal(wi)

        Dim EventLogText As String = wi.User.Translate(GetType(NTAccount)).ToString & vbCrLf

        EventLogText &= "Admin Role: " & wp.IsInRole(WindowsBuiltInRole.Administrator) & vbCrLf
        EventLogText &= "Power Role: " & wp.IsInRole(WindowsBuiltInRole.PowerUser) & vbCrLf
        EventLogText &= "operator Role: " & wp.IsInRole(WindowsBuiltInRole.AccountOperator) & vbCrLf
        EventLogText &= "Backup Role: " & wp.IsInRole(WindowsBuiltInRole.BackupOperator) & vbCrLf
        EventLogText &= "System Role: " & wp.IsInRole(WindowsBuiltInRole.SystemOperator) & vbCrLf
        EventLogText &= "Domain Admin Role: " & wp.IsInRole("DOMAIN\Domain Admins") & vbCrLf

        EventLog1.WriteEntry(EventLogText)

    End If
Next

My.Username
Admin Role: False
Power Role: False
operator Role: False
Backup Role: False
System Role: False
Domain Admin Role: False


Would appreciate any help you guys can offer. Thanks again guys/gals :)

Thanks Dave
Posted

1 solution

Hi
Resolved this issue, changed the token name from Ses.SecureToken to the following:

VB
Dim wi As WindowsIdentity = New WindowsIdentity(String.Concat(Ses.WindowsUsername & "@" & Ses.WindowsDomain))


And now instead of using 'IsInRole'

I loop through the WindowsIdentity.Groups, Translate the SID to a name and and do a case select to match the required groups, its as broad as it is long but it works.

VB
        For Each Ses As clsGetLoggedInSessions.LoggedInInfo In liSessions.Sessions
            'Is the State in Active State - If Not, Move On
            If Not (Ses.ConnectionState = WTS_CONNECTSTATE_CLASS.WTSActive) Then Continue For

            'Windows Identity Based on User Account.
            Dim WI As New WindowsIdentity(Ses.WindowsUsername & "@" & Ses.WindowsDomain)

            'SID List, GroupName List
            Dim tmpGrpName As String = ""

            'Loop Through WI Groups and Store to String (For Group Checking Later)
            For Each Pip As IdentityReference In WI.Groups
                Try : tmpGrpName &= Pip.Translate(GetType(NTAccount)).ToString & ","
                Catch ex As Exception : Continue For : End Try
            Next
            'Drop Process Info into Data Table for each user
            Dim tmpDat As DataTable = WMIQueryDataset(String.Format("SELECT * FROM Win32_Process WHERE SessionId='{0}' And Name='{1}'", CUInt(Ses.SessionId).ToString, "calc.exe"))

            'Check if Rows Have been returned
            If (tmpDat.Rows.Count = 0) Then
                'Ensure user is not member of admin roles
                If (GroupPermissionCheck(tmpGrpName) = False) Then Call StartAppAsUser(Ses.SecurityToken, "C:\Windows\System32\calc.exe")
            Else

            End If
        Next
End Sub


    Private Function GroupPermissionCheck(ByVal Grps As String) As Boolean
        Dim GroupsToCheck() As String = {"BUILTIN\ADMINISTRATORS", "BUILTIN\POWER USERS", "AKINIKA\DOMAIN ADMINS", "BUILTIN\BACKUP OPERATORS"}
        Dim Returnval As Boolean = False
        Array.ForEach(GroupsToCheck, Sub(val) If (Grps.IndexOf(val) > -1) Then Returnval = True)
        Return True
    End Function

    Private Sub StartAppAsUser(ByVal SecureToken As IntPtr, CommandPath As String)
        Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
        Dim StartInfo As New WindowsApi.STARTUPINFOW
        StartInfo.cb = CUInt(Runtime.InteropServices.Marshal.SizeOf(StartInfo))
        WindowsApi.CreateProcessAsUser(SecureToken, CommandPath, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
        If Not SecureToken = IntPtr.Zero Then
            WindowsApi.CloseHandle(SecureToken)
        End If
    End Sub
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900