Как я могу получить повышенные разрешения (UAC) с помощью олицетворения при неинтерактивном входе в систему?

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

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

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);

он бомбит с помощью Доступ к разделу реестра 'HKEY_LOCAL_MACHINE \ SOFTWARE \ XXX \ XXX' запрещен .

Хотя мне любопытно, почему проверка безопасности выполняется, когда MSDN сообщает не должно, {попробуйте {DoSomething (); } catch (Exception e) {// делаем что-то с e} } public int FooReturnInt (...

Нам всегда нужно попробовать catch в нашем коде, и он становится уродливым, как

public void foo()
{
  try
  {
    DoSomething();
  }
  catch(Exception e)
  {
     //do whatever with e
  }
}

public int FooReturnInt()
{
  try
  {
     return IntAfterSomeCalculation();
  }
  catch(Exception e)
  {
    //do exactly whatever with e as foo()
  }
}

Представьте, что у нас есть огромный класс со многими общедоступными функциями, подобными этой, и мы должны применять один и тот же try catch в каждом single function.

В идеале, поскольку часть try catch идентична, и мы можем передать Func в качестве параметра вспомогательной функции, которая выполняет что-то вроде

public void TryCatch(Func theFunction)
{
  try
  {
    theFunction();
  }
  catch(Exception e)
  {
    //processthe common exception        
  }
}

Тогда я бы предположил, что это значительно упорядочит мой код, теперь проблема в том, как правильно написать эту функцию? Тип возвращаемого значения этой функции зависит от типа возвращаемого значения этой функции.

10
задан Yuan 23 February 2011 в 22:38
поделиться