Вопрос по service, acl, windows, vb.net, .net – Как установить ACL для службы Windows в .net?

3

У меня есть сервис, который я должен иметь возможность запускать и останавливать с помощью кнопки. Я использую ServiceController в отдельной программе, и все работает, как задумано, когда я запускаю эту отдельную программу от имени администратора. Тем не менее, я должен иметь возможность контролировать этот сервис, как и любой другой. Как я могу установить разрешения для своего сервиса, чтобы все имели полный контроль над ним? Это должно быть сделано программно или как часть службы, или как установка. Это локальный сервис, написанный на vb.net.

Ваш Ответ

2   ответа
2

У вас есть несколько вариантов:

1) Вы можете требовать, чтобы ваше приложение запускалось от имени администратора. Каждый раз, когда ваше приложение запускается, вам будет предложено UAC (в Windows 7 и Vista), и ваше приложение будет повышено до необходимого уровня.

Запустите приложение .NET от имени администратора

2) Ваше приложение может запросить повышение прав, когда требуется действие, чтобы остановить и запустить службу. Это будет сделано путем запуска другого приложения на более высоком уровне, и это другое приложение будет выполнять фактический запуск и остановку.

Как повысить привилегии только при необходимости?

3) Предпочтительный вариант, ИМХО - вы должны создать свой сервис для постоянной работы, но не делать ничего, кроме прослушивания запросов через TCP / IP, именованные каналы или какой-либо другой механизм связи. Ваш сервис может затем запустить или остановить поток, который выполняет реальную работу.

4) Вы можете изменить права на обслуживание. Вот некоторые сообщения, которые дают некоторую информацию об этом (я все еще предпочел бы вариант 3):

Запуск / остановка службы Windows из учетной записи пользователя без прав администратора

http://msmvps.com/blogs/erikr/archive/2007/09/26/set-permissions-on-a-specific-service-windows.aspx

http://fstaal01.home.xs4all.nl/swsc-us.html

Update

Я изменил текст и добавил вариант 4 на основе комментария Гарри. Похоже, есть способы подправить разрешения. Для этого изначально требуются права администратора, но если вы связываете что-то вроде swsc (третья ссылка) с вашей установкой, вы можете использовать это для установки прав для вас. Я не уверен, есть ли какие-либо последствия для лицензии для этого. Кроме того, вы можете использовать вариант кода, который он вставил.

Спасибо, я обновил свой пост и проголосовал за ваш.
Это не верно. Вы можете изменить ACL службы, это даже не особенно сложно.
Проблема в том, что это сильно зависит от контекста. Хотя службы действительно потребляют ресурсы, существует значительный риск, связанный с предоставлением всем пользователям разрешения останавливать или запускать службу по желанию. Например, приложение, которое запускает или останавливает службу, может исходить из предположения, что служба работает, хотя на самом деле она была остановлена с помощью других средств. Служба также работает с повышенным разрешением, что может привести к дополнительному риску.
Я не согласен с вашим предположением, что предпочтительно, чтобы служба работала постоянно. Чтобы быть справедливым, это зависит от контекста, который OP не предоставил, но, как правило, лучше запускать службы только тогда, когда это необходимо. Даже в режиме ожидания они все еще используют системные ресурсы.
1

Код, который у меня есть, написан на C, но его не должно быть слишком сложно адаптировать к VB - или вы можете поместить его в DLL. Кроме того, вы можете запустить командную оболочку и использоватьsc sdset команда.

wchar_t sddl[] = L"D:"
  L"(A;;CCLCSWRPWPDTLOCRRC;;;SY)"           
      // default permissions for local system
  L"(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)"   
      // default permissions for administrators
  L"(A;;CCLCSWLOCRRC;;;AU)"                 
      // default permissions for authenticated users
  L"(A;;CCLCSWRPWPDTLOCRRC;;;PU)"           
      // default permissions for power users
  L"(A;;RP;;;IU)"                           
      // added permission: start service for interactive users
  ;

DWORD InstallService() 
{
  SC_HANDLE manager, service;
  PSECURITY_DESCRIPTOR sd;
  DWORD err;

  wchar_t apppath[MAX_PATH + 2];

  // Note: because this is only called from main() which exits
  // immediately afterwards, no attempt is made to close the
  // handles generated.

  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, 
      SDDL_REVISION_1, &sd, NULL))
  {
    err = GetLastError();
    printf("Error %u creating security descriptor.\n", err);
    return err;
  }

  if (!GetModuleFileName(0, apppath, MAX_PATH + 1)) 
  {
    err = GetLastError();
    printf("Error %u fetching module name.\n", err);
    return err;
  }

  if (_wcsicmp(apppath + wcslen(apppath) - wcslen(exename), exename) != 0) 
  {
    printf("Application name mismatch: %ls\n", 
      apppath + wcslen(apppath) - wcslen(exename));
    return ERROR_INVALID_FUNCTION;
  }

  manager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);

  if (!manager) 
  {
    err = GetLastError();
    printf("Error %u connecting to service manager.\n", err);
    return err;
  }

  service = CreateService(manager,
    servicename,
    displayname,
    WRITE_DAC,
    SERVICE_WIN32_OWN_PROCESS,
    SERVICE_DEMAND_START,
    SERVICE_ERROR_NORMAL,
    apppath,
    0,
    0,
    NULL,
    NULL,
    NULL);

  if (!service) 
  {
    err = GetLastError();
    printf("Error %u installing service.\n", err);
    return err;
  }

  if (!SetServiceObjectSecurity(service, DACL_SECURITY_INFORMATION, sd))
  {
    err = GetLastError();
    printf("Error %u setting service security.\n", err);
    return err;
  }

  printf("Service successfully installed.\n");
  return 0;
}

Похожие вопросы