How am I able to shutdown the system when I don't have SeShutdownPrivilege
Solution 1:
You have the permission, but it is disabled. That's what PowerShell is telling you.
To shutdown system you use the Win32API function called InitiateSystemShutdown
or ExitWindowsEx
:
ExitWindowsEx(EWX_POWEROFF, 0);
These functions note:
To shut down the local computer, the calling thread must have the SE_SHUTDOWN_NAME privilege. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.
As you can see, Windows checks thread privileges (any thread has token with privileges). If you call ExitWindowsEx
without the SE_SHUTDOWN_NAME privilege, the function will fail with the error:
Error code: 1314
A required privilege is not held by the client
Threads that you create by default inherit your privileges; but a program can enable a disabled privilege that it has been granted using AdjustTokenPrivileges
:
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = LookupPrivilegeValue(NULL, "SeShutdownPrivilege");
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
HANDLE processToken = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES);
AdjustTokenPrivileges(processToken, FALSE, &tp, 0, NULL, NULL);
CloseHandle(processToken);
Changing Privileges in a Token says:
AdjustTokenPrivileges
cannot add or remove privileges from the token. It can only enable existing privileges that are currently disabled or disable existing privileges that are currently enabled
So, why is this privilege disabled by default? To make sure that no program can shut down Windows by accident. Applications should ask for this explicitly.
There is an ancient but very good book: https://www.amazon.com/Programming-Windows-Security-Keith-Brown/dp/0201604426/ about all that stuff.
Solution 2:
It's because your user belongs to a group that has that privilege enabled.
To see for yourself which group(s):
- Open a PowerShell (or Command) prompt as Admin.
- Run
secedit /export /areas USER_RIGHTS /cfg OUTFILE.CFG
. - View the contents of OutFile.cfg in Notepad or alike, and look for the
SeShutdownPrivilege
entry. You will (should) see a couple/few SIDs for users and/or groups that have that privilege enabled.
So I have three short SIDs listed. Short SIDs are usually computer-level accounts/groups. For example, one of them is S-1-5-32-545
.
Using PowerShell we can determine which account/group that SID represents:
$objSID = New-Object System.Security.Principal.SecurityIdentifier ("S-1-5-32-545")
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$objUser.Value
This returns BUILTIN\Users
.
Since you're a user on that computer, you're automatically a member of that group, meaning you can shut down the computer.
The other two I have are S-1-5-32-544
, and S-1-5-32-551
. These are the standard BUILTIN\Administrators
group, and the BUILTIN\Backup Operators
group. Which line up with the groups you're seeing in the secpol.msc
dialog.