From 75acdeb6454429d6a1704a10f3bfe649a074b227 Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Wed, 13 Nov 2019 18:43:50 +0100 Subject: [PATCH] [Windows] Fix certbot renew task failure under NT AUTHORITY\SYSTEM account (#7536) Turned out that the scheduled task that runs `certbot renew` twice a day, is failing. Without any kind of log of course, otherwise it would not be fun. It can be revealed by opening a powershell under the `NT AUTHORITY\SYSTEM` account, under which the scheduled task is run. Under theses circumstances, the bug is revealed: Certbot breaks when trying to invoke `certbot.compat.filesystem._get_current_user()`. Indeed the logic there implied to call `win32api.GetUserNameEx(win32api.NameSamCompatible)` and this function does not return always a useful value. For normal account, it will be typically `DOMAIN_OR_MACHINE_NAME\YOUR_USER_NAME` (e.g. `My Machine\Adrien Ferrand`). But for the account `NT AUTHORITY\SYSTEM`, it will return `MACHINE_NAME\DOMAIN$`, which is a nonsense and makes fail the resolution of the actual SID of the account at the end of `_get_current_user()`. This PR fixes this behavior by using an explicit construction of the account name that works both for normal users and `SYSTEM`. * Use a different way to resolve current user account, that works both for normal users and SYSTEM. * Add a comment to run Certbot under NT AUTHORITY\SYSTEM --- certbot/compat/filesystem.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/certbot/compat/filesystem.py b/certbot/compat/filesystem.py index 69a3a63c5..5fba440cc 100644 --- a/certbot/compat/filesystem.py +++ b/certbot/compat/filesystem.py @@ -588,7 +588,11 @@ def _get_current_user(): """ Return the pySID corresponding to the current user. """ - account_name = win32api.GetUserNameEx(win32api.NameSamCompatible) + # We craft the account_name ourselves instead of calling for instance win32api.GetUserNameEx, + # because this function returns nonsense values when Certbot is run under NT AUTHORITY\SYSTEM. + # To run Certbot under NT AUTHORITY\SYSTEM, you can open a shell using the instructions here: + # https://blogs.technet.microsoft.com/ben_parker/2010/10/27/how-do-i-run-powershell-execommand-prompt-as-the-localsystem-account-on-windows-7/ + account_name = r"{0}\{1}".format(win32api.GetDomainName(), win32api.GetUserName()) # LookupAccountName() expects the system name as first parameter. By passing None to it, # we instruct Windows to first search the matching account in the machine local accounts, # then into the primary domain accounts, if the machine has joined a domain, then finally