Link to home
Start Free TrialLog in
Avatar of azfronz
azfronzFlag for United States of America

asked on

I wrote an ODBC Driver .DLL; programmacly how can I tell if I am being called by a process running as a system service

I wrote an ODBC Driver .DLL; programmacly how can I tell if I am being called by a process running as a system service? I need to know this for two reasons, one I do not want to pop up a message box when running as a system service, but log to the event log, and second I would like to charge more for users running in this mode as they are probably running scheduled DTS jobs or web servers.
Avatar of jkr
jkr
Flag of Germany image

The simple answer: 'GetUserName()' will return 'SYSTEM' when running under the local system account...

The more complex one:

BOOL RunningAsSystem ( void)
{
    BOOL                        fSystem;
    HANDLE                      hThread;
    TOKEN_USER*                 ptu;
    DWORD                       cbToken;
    PSID                        psid;

    SID_IDENTIFIER_AUTHORITY    SystemSidAuthority  =   SECURITY_NT_AUTHORITY;

    // First we must open a handle to the access token for this thread.

    if  (   !OpenThreadToken    (   GetCurrentThread(),
                                    TOKEN_QUERY,
                                    FALSE,
                                    &hThread
                                )
        )
        {
            if  ( GetLastError() == ERROR_NO_TOKEN)
                {
                    // If the thread does not have an access token, we'll examine the
                    // access token associated with the process.

                    if  (   !OpenProcessToken   (   GetCurrentProcess   (),
                                                    TOKEN_QUERY,
                                                    &hThread
                                                )
                        )   return ( FALSE);
                }
             else   return ( FALSE);
        }

    // Then we must query the size of the group information associated with
    // the token. Note that we expect a FALSE result from GetTokenInformation
    // because we've given it a NULL buffer. On exit cbTokenGroups will tell
    // the size of the group information.

    if  (   GetTokenInformation (   hThread,    TokenGroups,    NULL,   0,  &cbToken))
        return ( FALSE);

    // Here we verify that GetTokenInformation failed for lack of a large
    // enough buffer.

    if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        return ( FALSE);

    // Now we allocate a buffer for the group information.
    // Since _alloca allocates on the stack, we don't have
    // to explicitly deallocate it. That happens automatically
    // when we exit this function.

    if ( ! ( ptu= ( TOKEN_USER*) _alloca ( cbToken)))
        return ( FALSE);

    // Now we ask for the group information again.
    // This may fail if an administrator has added this account
    // to an additional group between our first call to
    // GetTokenInformation and this one.

    if ( !GetTokenInformation ( hThread, TokenUser, ptu, cbToken,
                                       &cbToken) )
    {
        return ( FALSE);
    }

    // Now we must create a System Identifier for the SYSTEM account

    if ( ! AllocateAndInitializeSid ( &SystemSidAuthority, 1,
                                               SECURITY_LOCAL_SYSTEM_RID,
                                               0,
                                               0, 0, 0, 0, 0, 0, &psid) )
        return ( FALSE);

    fSystem= FALSE;

        if ( EqualSid ( ptu->User.Sid, psid))
        {
            fSystem = TRUE;
        }

    FreeSid ( psid);

    return ( fSystem);
}
Avatar of azfronz

ASKER

What is this exactly checking for? That the thread/process requires the SYSTEM_LOCAL_SYSTEM_RID or that the user that is running this has rights to run as a SYSTEM service? If it is the second case, wouldn't it return true for the Administrator account no matter what side it is running on? I guess a little more info on what exactly this is doing what make me more comfortable.
The above is checking whether the security identifier of the current thread is the one of the 'LocalSystem' account by querying the TokenUser information. BTW, the above is tested: http:Q_10108122.html
Avatar of azfronz

ASKER

That does not help me completely. If a user is running say a scheduled DTS job wouldn't it be running under whatever account DTS scheduler is setup to run as? Also wouldn’t  that be the same as the Anonymous user under IIS? Both of those processes would be running as a system service but not necessarily running as account SYSTEM? Or do all users used in these situations require having LOCALSYSTEM rights?
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial