Solved

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

Posted on 2004-07-30
5
201 Views
Last Modified: 2010-04-13
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.
0
Comment
Question by:azfronz
  • 3
  • 2
5 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 11679907
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);
}
0
 

Author Comment

by:azfronz
ID: 11680470
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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 11680519
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
0
 

Author Comment

by:azfronz
ID: 11680617
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?
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 11680901
Hmm, in this case, you'd better check the desktop you're running on - if it is different from 'WinSta0', you are running as a non-interactive service, e.g.

STARTUPINFO si;

GetStartupInfo ( &si);

if ( strcmp(si.lpDesktop, "WinSta0")) {

    // service
}
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

NTFS file system has been developed by Microsoft that is widely used by Windows NT operating system and its advanced versions. It is the mostly used over FAT file system as it provides superior features like reliability, security, storage, efficienc…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now