locked
Retrieving session ID fails after impersonation RRS feed

  • Question

  • Hi,

    I want to retrieve a user's session ID in Vista from within an application (a printer driver) that runs as LOCAL SERVICE. For this I call GetCurrentProcessId and ProcessIdToSessionId.
    If, however, I call these functions normally, I get the session ID of LOCAL SERVICE, which is 0; therefore I first call ImpersonateLoggedOnUser with a security token of the user I want to know the session ID of.

    In theory, this should return the session ID I'm after. However, the call to ProcessIdToSessionId fails with error 5, E_ACCESSDENIED.
    Am I (or the LOCAL SERVICE user account) lacking some privileges here?

    Note that both the normal user and LOCAL SERVICE allow a call to
    ProcessIdToSessionId, only the situation where LOCAL SERVICE impersonates the normal user causes a problem.

    Regards,
    Bert Vingerhoets
    Monday, November 17, 2008 11:44 AM

Answers

  •  

    Impersonation is per thread, so ProcessIdToSessionId won't know which users the threads of the process are impersonating, even if all access checks pass.

    You wrote you call ImpersonateLoggedOnUser with the user's token.  As you have the token, you could call GetTokenInformation with TokenSessionId.

    Wednesday, November 19, 2008 4:52 PM

All replies

  • I did some digging through MSDN until I had some grasp (I think) of access rights in Windows. Enough at least to be able to determine the access rights defined on the process in which my printer driver runs.

    Using calls to GetKernelObjectSecurity with current process handle, GetSecurityDescriptorSacl, GetSecurityDescriptorDacl, and GetExplicitEntriesFromAcl, I was able to retrieve DACL and SACL set on my process. However, I could not access explicit entries from the SACL (it contains 1 ACE).
    Entries in the process' DACL:
    • grant 'NT AUTHORITY\LOCAL SERVICE' noninheritable PROCESS_ALL_ACCESS rights.
    • grant some SID without a username ('S-1-5-5-0-136552') noninheritable SYNCHRONIZE and PROCESS_TERMINATE rights
    • grant 'NT AUTHORITY\SYSTEM' noninheritable SYNCHRONIZE and PROCESS_TERMINATE rights

    This explains why I can perform a ProcessIdToSessionId call without impersonation: LOCAL SERVICE has the PROCESS_QUERY_INFORMATION right; and not with impersonation: the user is not listed in the process' DACL (and I guess not in the SACL either) and thus has no rights at all.

    I attempted to grant rights to the user using AddAccessAllowedAce on the DACL for the query rights, SetSecurityDescriptorDacl to add the DACL to the security descriptor and SetKernelObjectSecurity to set the modified security descriptor as security descriptor of the process.
    All these API calls return successful, but the descriptor doesn't get set and the user reamins unable to retrieve the session ID.

    Is this the correct way to modify a process' access rights? If not, then what is?

    Does anyone have any other ideas to get a process' session ID?
    Wednesday, November 19, 2008 3:26 PM
  •  

    Impersonation is per thread, so ProcessIdToSessionId won't know which users the threads of the process are impersonating, even if all access checks pass.

    You wrote you call ImpersonateLoggedOnUser with the user's token.  As you have the token, you could call GetTokenInformation with TokenSessionId.

    Wednesday, November 19, 2008 4:52 PM
  • Thank you; that solved my problem.

    Note that the impersonation trick does work on XP where the driver runs under the SYSTEM user account. It also works for retrieving the username of the logged-in user; both on XP and Vista. The latter operation I can now replace with an info call on the token as well, so no impersonation is needed anymore.
    • Proposed as answer by aslamkhan24 Thursday, March 5, 2009 11:53 AM
    Thursday, November 20, 2008 9:47 AM
  • Bert Vingerhoets said:

    Thank you; that solved my problem.

    Note that the impersonation trick does work on XP where the driver runs under the SYSTEM user account. It also works for retrieving the username of the logged-in user; both on XP and Vista. The latter operation I can now replace with an info call on the token as well, so no impersonation is needed anymore.



    Hi,
     I have same issue with port monitor printer driver. Actually, i want to run an application in the users session, but my application works fine in XP, win2003,etc but with vista i am not able to do it. You have written that you have solved this problem. will you please help me somehow.
        I want to use "GetTokenInformation" which needs usertoken and you have mentioned that you have already that. Will you please let me know how i can get that.
      Thank you in advance.
    aslam
    Thursday, March 5, 2009 11:57 AM
  • Which current user's session?
    Thursday, March 5, 2009 5:36 PM
  • hi,

      yah actually i want to know the session ID of the user, who executed the print command, so that i can launch the application in his session. As i mentioned i have this issue in vista only.
    thank you

    aslam
    Friday, March 6, 2009 3:52 AM
  • Did you find a solution about to know the session ID of the user who executed the print command? I have the same need.

    Thx
    Diego
    Monday, July 6, 2009 10:28 AM
  • Hi Guys,

    Did you find a solution to get the user session ID in this case? I have the same problem, spooler process in Vista is running under session 0, so as you know the actual user would run as console session (usually session=1) or RDP session. I can enumerate sessions using WTSEnumerateSessions, but as you have the same problem I can not tell the SessionID of the user who initially send something to printer.

    Thanks,
    Farid

    Wednesday, September 30, 2009 8:04 PM