Dropping privileges in C++ on Windows
Yes, you can use AdjustTokenPrivileges to remove unneeded and dangerous privileges from your token. You can either disable if not immediately needed (the privilege can be enabled later) or remove a privilege from your token altogether.
You can also create a restricted token via CreateRestrictedToken and relaunch your application running with that restricted token. CreateRestrictedToken can be used to disable privileges and remove groups (like Administrators Group) from a token.
You may be able to use AdjustTokenGroups to remove the administrator group from the token of your running process, but I've never tried this on an already running process.
Note that write-access to the Windows directory is not covered by a privilege. Resources in the system have ACL's which govern who has access. System and administrators have write-access to the Windows directory.
Dropping process rights under windows
Take a look at Mark Russinovich's description of stripping privileges under Windows using CreateRestrictedToken
and CreateProcessAsUser
. As he explains, this isn't bulletproof since the account under which the process is running still retains its privileges.
And of course, his PsExec sysinternals utility helps you strip away at least Administrator
privileges, without requiring coding.
For an existing process, it seems AdjustToken
and AdjustTokenGroup
permit manipulation (the former apparently requires XPSP2 or higher), but require privileges themselves... it might be possible to commit privilege seppuku this way, but I haven't tried them: they might barf on manipulating privileges of the current process.
How to properly drop (remove or disable) privileges in Windows?
My understanding was indeed wrong. Despite what the documentation claims, you can "easily" remove privileges using AdjustTokenPrivileges()
by setting the attribute SE_PRIVILEGE_REMOVED
to the appropriate privilege in the NewState
field.
c++ drop administrator privileges
I end up with this to make owner of new object to current user.
if(GetTokenInformation(hToken,TokenUser,tu,buff.size(),&rw)){
if(!SetTokenInformation(hToken,TokenOwner,tu,buff.size())){
}
}
c# starting process with lowered privileges from UAC admin level process
You'd better avoid starting a non-elevated process from an elevated one. It's tricky part and error-prone.
This approach is better:
- Your updater initially starts as non-elevated application, and its manifest has
asInvoker
level. - When it starts, it restarts itself with elevated privileges using
runas
verb, and passes a command-line parameter to indicate it. This instance performs the update and returns. - Here comes the non-elevated updater again, and starts your application with the same non-elevated user token that started the first instance of updater in step 1.
Pretty simple and robust.
Requesting administrator privileges at run time
Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.
Batch file: Drop elevated privileges (run a command as original user)
You can run a command with restricted privileges with:
runas /trustlevel:0x20000 "YourCommandHere"
You should provide the absolute path to your command including any arguments in double quotes as an argument to runas
.
If you would like to run more than one command with restricted privileges, you can put them in a separate batch file and run it with:
runas /trustlevel:0x20000 "cmd /C PathToYourBatchFile"
Anyway, this will open a new console with restricted privileges. You also have to use this syntax whenever you wish to run with restricted privileges an internal command (like copy
, del
, etc.) as these are provided by the command line interpreter and do not have an associated path.
Note that 0x20000
is the trust level of standard users. You can list other available trust levels by running
runas /showtrustlevels
Related Topics
Qthread Emits Finished() Signal But Isrunning() Returns True and Isfinished() Returns False
Understanding Boost::Disjoint_Sets
Avoid Exponential Grow of Const References and Rvalue References in Constructor
How to Determine Programmatically If an Expression Is Rvalue or Lvalue in C++
Why Does Visual Studio Not Perform Return Value Optimization (Rvo) in This Case
Is There a Reason Declval Returns Add_Rvalue_Reference Instead of Add_Lvalue_Reference
Is There Any G++ Option to Dump Class Layout and Vtables
Is the Std::Set Iteration Order Always Ascending According to the C++ Specification
C++11 Scope Exit Guard, a Good Idea
What Is Void* and to What Variables/Objects It Can Point To
Load Shared Library by Path at Runtime
Why Vector Access Operators Are Not Specified as Noexcept
C++ Unified Assignment Operator Move-Semantics
Real-Time Pitch Detection Using Fft
Is There a Null Std::Ostream Implementation in C++ or Libraries
Eigen How to Concatenate Matrix Along a Specific Dimension
How to Make the for Each Loop Function in C++ Work with a Custom Class