Как установить ACL для службы Windows в.net?
У меня есть сервис, который я должен иметь возможность запускать и останавливать с помощью кнопки. Я использую ServiceController в отдельной программе, и все работает, как задумано, когда я запускаю эту отдельную программу от имени администратора. Тем не менее, я должен иметь возможность контролировать этот сервис, как и любой другой. Как я могу установить разрешения для своего сервиса, чтобы все имели полный контроль над ним? Это должно быть сделано программно или как часть службы, или как установка. Это локальный сервис, написанный на vb.net.
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
Обновить
Я изменил текст и добавил вариант 4, основываясь на комментарии Гарри. Похоже, есть способы подправить разрешения. Для этого изначально требуются права администратора, но если вы связываете что-то вроде swsc (третья ссылка) с вашей установкой, вы можете использовать это для установки прав для вас. Я не уверен, есть ли какие-либо последствия для лицензии для этого. Кроме того, вы можете использовать вариант кода, который он вставил.
Код, который у меня есть, написан на 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;
}