WMI: редактирование реестра удаленно - PullRequest
3 голосов
/ 02 апреля 2010

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

Все методы "get" в StdRegProv работают нормально (http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx), но методы "set" или "create", а также проверка доступа ко всем возвращают "5", которое равно "Error_Access_Denied" согласно winerror.h. Так что вот в чем проблема: почему я получаю отказ в доступе при попытке изменить реестр? Если кто-нибудь может помочь мне разобраться в этом, я буду вам очень признателен!

Я почти забыл, когда я запускаю Visual Studio в режиме администратора на своем локальном компьютере и запускаю код на локальном компьютере, он работает безупречно. Если я не запускаюсь в режиме администратора на локальном компьютере, код завершается ошибкой, поэтому я подозреваю, что, возможно, проблема с UAC? ​​

ОБНОВЛЕНИЕ: Используя regedit и подключаясь к удаленному компьютеру, я МОГУ изменить ключ реестра, что наводит меня на мысль, что это не проблема UAC, но она выполняется с локальным соединением WMI при запуске в повышенный режим на моей собственной машине, так что, возможно, это UAC. Кроме того, машины winXP возвращают тот же код ошибки (5, ERROR_ACCESS_DENIED), что приводит меня к мысли, что это не UAC ... это отстой.

решено: объект ManagementClass использует неправильное переопределение; он должен быть параметризован с помощью ManagementScope, в противном случае вы просто выполняете функции локально.

ManagementClass mc = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);

Да, я эпический провал: / 9K строк кода, и эта строка подняла меня до самого длинного из них.

using System;
using System.Management;


public class EditRemoteRegistry
{
    public static void Main(string[] args)
    {
        ConnectionOptions options = new ConnectionOptions();
        options.EnablePrivileges = true;
        options.Impersonation = ImpersonationLevel.Impersonate;
        options.Password = "password goes here";
        //options.Authority = "my company's domain";
        //options.Username = "Admin username";

        ManagementScope scope = new ManagementScope("\\\\arbitraryhost\\root\\default", options);
        scope.Connect();

        ManagementClass mc = new ManagementClass("StdRegProv");

        ManagementBaseObject inParams = mc.GetMethodParameters("CreateKey");
        inParams["hDefKey"] = (UInt32)2147483650;
        inParams["sSubKeyName"] = "Software\\Test";
        ManagementBaseObject outParams = mc.InvokeMethod("CreateKey", inParams, null);
        //Should return a 0, but returns a 5, "Error_Access_Denied"
        Console.WriteLine("CreateKey Method returned " + outParams["returnValue"]);

        //This chunk works fine
        ManagementBaseObject inParams5 = mc.GetMethodParameters("GetDWORDValue");
        inParams5["hDefKey"] = 2147483650;
        inParams5["sSubKeyName"] = "Software\\Test";
        inParams5["sValueName"] = "testDWORDvalue";
        ManagementBaseObject outParams5 = mc.InvokeMethod("GetDWORDValue", inParams5, null);
        Console.WriteLine("GetDWORDValue returned " + (UInt32)outParams5["returnValue"] + " ");
        Console.WriteLine((UInt32)outParams5["uValue"]);


        ManagementBaseObject inParams6 = mc.GetMethodParameters("SetStringValue");
        inParams6["hDefKey"] = 2147483650;
        inParams6["sSubKeyName"] = "Software\\Test";
        inParams6["sValueName"] = "TestStringValue";
        inParams6["sValue"] = "Hello World!";
        ManagementBaseObject outParams6 = mc.InvokeMethod("SetStringValue", inParams6, null);
        //Should return a 0, but returns a 5, "Error_Access_Denied"
        Console.WriteLine("SetStringValue returned " + outParams6["returnValue"]);

        Console.ReadKey();
    }
}

Ответы [ 2 ]

2 голосов
/ 02 апреля 2010

Вы также можете отключить удаленную фильтрацию UAC.

Отключение удаленного контроля учетных записей путем изменения записи реестра, которая управляет удаленным контролем учетных записей, не рекомендуется, но может быть необходимо в рабочей группе.Запись реестра: HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ system \ LocalAccountTokenFilterPolicy.Когда значение этой записи равно нулю (0), фильтрация маркеров удаленного доступа UAC включена.Когда значение равно 1, удаленный контроль учетных записей отключен.

http://msdn.microsoft.com/en-us/library/aa826699(VS.85).aspx

0 голосов
/ 02 апреля 2010

Кажется, что есть проблемы с запуском сеттеров WMI на машинах с включенным UAC.

цитата

Из отчетов, которые мы получаем с мест, кажется, что для работы удаленных запросов WMI необходимо отключить UAC. При работающем UAC учетная запись администратора фактически имеет два токена безопасности, токен обычного пользователя и токен администратора (который активируется только при передаче запроса UAC). К сожалению, удаленные запросы, поступающие по сети, получают обычный пользовательский токен для администратора, и, поскольку нет способа удаленной обработки запроса UAC, токен не может быть повышен до токена безопасности истинного администратора.

Источник: http://www.poweradmin.com/help/enableWMI.aspx

Попробуйте отредактировать раздел реестра на удаленном компьютере:

HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ System \ LocalAccountTokenFilterPolicy.

0 - построить отфильтрованный токен (Remote UAC включен) 1 - построить повышенный токен (удаленный контроль учетных записей отключен)

...