Wednesday, November 29, 2017

Relinquish rights on Windows

Leave a Comment

I have a C++ application that runs as administrator (it is compiled with a manifest with requestedExecutionLevel set to requireAdministrator.

At some point, once all the tasks requiring administration rights are done, I would like to relinquish those rights and perform the remaining tasks as the user that launched the application.

Windows provides the ImpersonateLoggedOnUser function, but I can't find any way to obtain a token for the user that called the application.

Are there any other ways to do what I have described here?

2 Answers

Answers 1

Perhaps a better approach would be to request highestAvailable instead of requireAdministrator in your manifest. Then, if you find that you are running elevated, just do everything you need to do. If you find that you are not running elevated:

  1. Launch your program again, using ShellExecute with the runAs verb to run it elevated.
  2. Have your unelevated process wait for the elevated process to do whatever it needs to do. (How to know when the elevated process is done is left as an exercise for the implementer. You also need to worry about what happens if the user does not allow your elevated process to start.)
  3. Once the elevated process completes, do the rest of your unelevated work.

If you want to continue with your original plan, this Raymond Chen blog post explains how to start an unelevated process from an elevated process. (The fact that your manifest requests requireAdministrator may complicate this process.)

Answers 2

msdn:

Enabling a privilege in an access token allows the process to perform system-level actions that it could not previously. Your application should thoroughly verify that the privilege is appropriate to the type of account.

You can check: https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx

And here is their c++ sample:

#include <windows.h> #include <stdio.h> #pragma comment(lib, "cmcfg32.lib")  BOOL SetPrivilege(     HANDLE hToken,          // access token handle     LPCTSTR lpszPrivilege,  // name of privilege to enable/disable     BOOL bEnablePrivilege   // to enable or disable privilege     )  {     TOKEN_PRIVILEGES tp;     LUID luid;      if ( !LookupPrivilegeValue(              NULL,            // lookup privilege on local system             lpszPrivilege,   // privilege to lookup              &luid ) )        // receives LUID of privilege     {         printf("LookupPrivilegeValue error: %u\n", GetLastError() );          return FALSE;      }      tp.PrivilegeCount = 1;     tp.Privileges[0].Luid = luid;     if (bEnablePrivilege)         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;     else         tp.Privileges[0].Attributes = 0;      // Enable the privilege or disable all privileges.      if ( !AdjustTokenPrivileges(            hToken,             FALSE,             &tp,             sizeof(TOKEN_PRIVILEGES),             (PTOKEN_PRIVILEGES) NULL,             (PDWORD) NULL) )     {            printf("AdjustTokenPrivileges error: %u\n", GetLastError() );            return FALSE;      }       if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)      {           printf("The token does not have the specified privilege. \n");           return FALSE;     }       return TRUE; } 

And also look at: https://msdn.microsoft.com/en-us/library/windows/desktop/ms717797(v=vs.85).aspx

Hope it helps.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment