Ваш комментарий о LogonUser () побудил меня сделать некоторые исследования, чтобы подтвердить это. Я сталкивался с некоторыми вещами, которые его поддерживали, но у меня сложилось впечатление, что LogonUser () возвращает только ограниченный токен для интерактивных сессий. Я написал несколько тестов (см. Мой ответ) и обнаружил, что обычный тест IsInRole (), обычно выполняемый для проверки того, был ли evelavted или нет, всегда возвращал true при олицетворении созданного мной администратора домена независимо от того, был ли это сеанс с повышенными привилегиями. Однако, когда он не повышен, открыть подраздел для записи все равно не удалось. Я не совсем понимаю.

я есть библиотека классов, которая хранит общесистемные данные конфигурации в реестре (HKLM \ Software \ XXX). Эта библиотека используется в различных приложениях (сервисы, формы Windows, веб-приложения, консольные приложения) в различных версиях Windows (XP, 2003, 7, 2008 R2). Из-за этого идентификация приложения не согласована и может даже не входить в группу администраторов компьютера. Итак, я создал пользователя-администратора домена AD и выполняю олицетворение, чтобы получить доступ для записи в реестр. Это прекрасно работает в XP / 2003, но не в системах с поддержкой UAC (7 / 2008R2). Насколько я понимаю, только интерактивные учетные записи разделяют токены, что подразумевает, что неинтерактивные учетные записи (идентификаторы служб, идентификаторы пула приложений и т. Д.) Не разделяются. Я не могу найти ничего, чтобы это подтвердить, но исходя из этого предположения, подражание, которое я делаю, должно работать.

Я написал класс-оболочку для выполнения олицетворения с использованием собственного LogonUser (сетевой тип входа, поставщик по умолчанию) и DuplicateTokenEx (олицетворение, основной токен), а затем WindowsIdentity.Impersonate (). Я получаю ссылку на мой корневой ключ:

using (ECR.Impersonator imp = new ECR.Impersonator("XXX", "XXX", "XXX"))
{
    _root = Registry.LocalMachine.CreateSubKey("SOFTWARE\\XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);
}

Согласно сMSDNс помощью ReadWriteSubTree это должно быть ТОЛЬКО в тот момент, когда выполняется проверка безопасности. Я могу записывать значения в этот ключ, создавать вложенные ключи (также используя ReadWriteSubTree) и записывать значения в эти вложенные ключи без необходимости дополнительной проверки безопасности. Поэтому я подумал, что мне нужно будет только один раз выполнить дорогостоящее подражание - получить ссылку на мой корневой ключ.

Я могу записать значения в мой корневой ключ просто отлично:

_root.SetValue("cachedDate", value.ToBinary(), RegistryValueKind.QWord); }

но когда я создаю / открываю подключ с помощью ReadWriteSubTree:

RegistryKey key = _root.CreateSubKey("XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);

это бомбы сAccess to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\XXX\XXX' is denied.

Хотя мне любопытно, почему проверка безопасности выполняется, когда MSDN говорит, что этого не следует делать, у меня вопрос: как я могу получить повышенные разрешения с помощью олицетворения для приложений, которые могут не работать под интерактивным входом?

Ответы на вопрос(2)

Ваш ответ на вопрос