locked
ImpersonateLoggedOnUser Not Working in Win 7? RRS feed

  • Question

  • One of my applications needs to access a CompactFlash card as a raw device. I can do this using CreateFile with the first parameter set to "\\.\PhysicalDriveX" where 'X' is the number of the drive where the CompactFlash card is located. The security descriptor in the CreateFile call is set to NULL. There is a caveat that this only works with users that have administrator access. So I created a class that elevates the user to an administrator using a fixed administrator account on the computer. The code snippet looks like this:

       if( LogonUser( "AdminUser", ".", Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_AdminToken ) )
       {
          TRACE_MSG0( "Logged in as user AdminUser\n" );
    
          if( ImpersonateLoggedOnUser(m_AdminToken) )
          {
             TRACE_MSG0( "Impersonating user AdminUser\n" );
    
             m_LoggedIn = true;
          }
          else
          {
             TRACE_MSG1( "Could not impersonate user AdminUser (error = 0x%08X)\n", GetLastError() );
          }
       }
       else
       {
          TRACE_MSG1( "Could not login as user AdminUser (error = 0x%08X)\n", GetLastError() );
       }
    

    This code works perfectly on Win XP. However, when I try it on Win 7, it does not seem to work. In fact, it's weird because the trace message after the "LogonUser" call indicates that it was successful, but neither of the trace messages after the "ImpersonateLoggedOnUser" are displayed (success path or failure path). The m_LoggedIn variable seems to be set to "true" because I use this to determine whether I need to call RevertToSelf() when I no longer need access to the CompactFlash card.

    If somebody can tell me what I'm doing wrong or why this doesn't work in Win 7, I would appreciate it. Thanks!

    Tuesday, March 13, 2012 7:50 PM

Answers

  • You can always have a windows service as a part of your solution which is responsible for performing operations which need admin privileges. Then your interactive portion of your application can connect to your service through any IPC mechanism  (i.e. named pipe, local RPC, ...) to request the service. If you go with this scenario, you will not need to prompt the user for the privilege escalation either.

    ----
    Nima Sharifimehr.
    sbucsc at yahoo dot com

    • Proposed as answer by Nima Sharifimehr Friday, March 16, 2012 2:08 PM
    • Marked as answer by SrqDan Thursday, March 22, 2012 4:19 PM
    Friday, March 16, 2012 1:58 PM
  • Well, UAC is per process. It affects the user token that is attached to the process.

    As I said, the UAC friendly way is to have a seperate executable that does what you want then run it with ShellExecute with the runas verb. This doesn't modify the current process' security token but instead starts up the child with administrative privileges. You can communicate with it using IPC to this child process.

    But anyway, the hint that I was trying to give is that the whole UAC restriction only affects LogonUser when using the LOGON32_LOGON_INTERACTIVE. LogonUser with LOGON32_LOGON_BATCH and  both of the LOGON32_LOGON_NETWORK will give an administrator token back, but these tokens have some differences in the token to stop you from being able to use these tokens to access the desktop properly.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    • Marked as answer by SrqDan Thursday, March 22, 2012 4:19 PM
    Friday, March 16, 2012 8:36 PM

All replies

  • I believe that you have your UAC (User Access Control) turned on for your Win7 machine and you must be trying to run above code from within an interactive process. UAC elevation is per process. So, you will need to run this code from within a windows service or you could start an escalated process. Then you can use that process as a host for any functionality that you need to run with admin privileges.

    ----
    Nima Sharifimehr.
    sbucsc at yahoo dot com

    Tuesday, March 13, 2012 8:20 PM
  • When you call LogonUser with the LOGON32_LOGON_INTERACTIVE logon type, the token you get back will be restricted. The interactive logon type is meant to be used for processes that will interact with a user and as such it will go through the same UAC restriction that your main user token goes through when you log on.

    The UAC friendly way recommends that you start up a child process with ShellExecute with the runas verb so that it prompts the user. There are some other ways around this with some restrictions and stuff, but if you are planning on rolling this out to customers I really suggest you prompt the users to let them know that what they are doing is an administrative action.

    If this is just for you then just play around with LogonUser a bit more.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.


    • Edited by Darran Rowe Tuesday, March 13, 2012 8:37 PM
    Tuesday, March 13, 2012 8:30 PM
  • Crescens2k - I have tried many different variations of the LogonUser call, but none of them grant me the access that I need. Even though LogonUser and ImpersonateLoggedOnUser return successfully, the application doesn't seem to have been granted administrator access. I'm guessing that Windows 7 UAC is getting in the way.

    Nima - I believe you're correct that UAC elevation is per process. Unfortunately, I can't give administrator access for the entire application since that would allow non-administrators access to places where they shouldn't be going.

    I only need a temporary administrator access for when I try to access the physical drive using the CreateFile function call. If anybody has ideas on how to do this in Windows 7 with UAC turned on, I'd sure appreciate it. If this is not possible, I'll have to tell my users that this will only work on Windows XP.

    Thanks for your thoughts.

    Thursday, March 15, 2012 5:46 PM
  • You can always have a windows service as a part of your solution which is responsible for performing operations which need admin privileges. Then your interactive portion of your application can connect to your service through any IPC mechanism  (i.e. named pipe, local RPC, ...) to request the service. If you go with this scenario, you will not need to prompt the user for the privilege escalation either.

    ----
    Nima Sharifimehr.
    sbucsc at yahoo dot com

    • Proposed as answer by Nima Sharifimehr Friday, March 16, 2012 2:08 PM
    • Marked as answer by SrqDan Thursday, March 22, 2012 4:19 PM
    Friday, March 16, 2012 1:58 PM
  • Well, UAC is per process. It affects the user token that is attached to the process.

    As I said, the UAC friendly way is to have a seperate executable that does what you want then run it with ShellExecute with the runas verb. This doesn't modify the current process' security token but instead starts up the child with administrative privileges. You can communicate with it using IPC to this child process.

    But anyway, the hint that I was trying to give is that the whole UAC restriction only affects LogonUser when using the LOGON32_LOGON_INTERACTIVE. LogonUser with LOGON32_LOGON_BATCH and  both of the LOGON32_LOGON_NETWORK will give an administrator token back, but these tokens have some differences in the token to stop you from being able to use these tokens to access the desktop properly.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    • Marked as answer by SrqDan Thursday, March 22, 2012 4:19 PM
    Friday, March 16, 2012 8:36 PM
  • I tried LogonUser with LOGON32_LOGON_BATCH and LOGON32_LOGON_NETWORK, but that by itself did not work. Are you saying that I can use LOGON32_LOGON_BATCH or LOGON32_LOGON_NETWORK and then change the token permissions to get me the access that I need? If so, what token privilege would this be? I looked at the token privilege constants, but none of them stand out as one I would need to access a physical drive.
    Monday, March 19, 2012 12:02 PM
  • I believe that both of you are right. With UAC getting in the way, the way to do this is to have something else that is running at administrator level do your work for you. Whether this is a service or another process started with "runas" doesn't seem to matter.
    Thursday, March 22, 2012 4:19 PM
  • Well, I was looking around a bit more and UAC elevation really is the only way to get this to work easily.

    It seems I forgot one important thing. Because of security, you cannot impersonate a user with a higher set of privileges unless you have the SE_IMPERSONATE_NAME privilege set. By default regular users don't have this. I completely forgot about this.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    Thursday, March 22, 2012 10:10 PM