Здравствуйте, SergH, Вы писали:
SH>Здравствуйте, x2003, Вы писали:
X>>У меня возникла проблемка
. Мне необходимо настройить для моего сервиса свойство RunAs, чтобы он крутился под аккаунтом конкретного пользователя. Причем сделать енто надо без использования dcomcnfg.exe
.
SH>Почитай статьи Alexa Fedotova про упавление системными службами. В Статьи\Базовые сервисы\..
Да. Я вроде как этими функциями и пользуюсь. Конкретно:
DWORD
SetAccountRights (
LPTSTR User,
LPTSTR Privilege
)
{
LSA_HANDLE policyHandle;
LSA_OBJECT_ATTRIBUTES objectAttributes;
PSID principalSID;
LSA_UNICODE_STRING lsaPrivilegeString;
WCHAR widePrivilege [256];
#ifdef _UNICODE
lstrcpy (widePrivilege, Privilege);
#else
STR2UNI (widePrivilege, Privilege);
#endif
memset (&objectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
if (LsaOpenPolicy (NULL,
&objectAttributes,
POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
&policyHandle) != ERROR_SUCCESS)
{
return GetLastError();
}
GetPrincipalSID (User, &principalSID);
lsaPrivilegeString.Length = (USHORT) (wcslen (widePrivilege) * sizeof (WCHAR));
lsaPrivilegeString.MaximumLength = (USHORT) (lsaPrivilegeString.Length + sizeof (WCHAR));
lsaPrivilegeString.Buffer = widePrivilege;
if (LsaAddAccountRights (policyHandle,
principalSID,
&lsaPrivilegeString,
1) != ERROR_SUCCESS)
{
free (principalSID);
LsaClose (policyHandle);
return GetLastError();
}
free (principalSID);
LsaClose (policyHandle);
return ERROR_SUCCESS;
}
Причем как привилегию беру SeBatchLogonRight.
Когда хочу пустить сервис мне говорят. Logon failure.
Здравствуйте, Alex Fedotov, Вы писали:
AF>Здравствуйте, SergH, Вы писали:
SH>>Здравствуйте, x2003, Вы писали:
X>>>У меня возникла проблемка
. Мне необходимо настройить для моего сервиса свойство RunAs, чтобы он крутился под аккаунтом конкретного пользователя. Причем сделать енто надо без использования dcomcnfg.exe
.
SH>>Почитай статьи Alexa Fedotova про упавление системными службами. В Статьи\Базовые сервисы\..
AF>Это если действительно сервис. Если это COM-сервер, не являющийся сервисом, то надо под его AppID прописать значение RunAs: http://msdn.microsoft.com/library/en-us/com/htm/reg_7nar.asp.
Это реальный ATL-ный сервис. В нем есть один COM объект.
Для установки прав на запуск я делаю следующее:
1) Вызов с APPID и Principal
DWORD
SetRunAsPrincipal
(
LPTSTR AppID,
LPTSTR Principal
)
{
DWORD returnValue;
HKEY registryKey;
TCHAR appid [256];
TCHAR keyName [256];
if (AppID[0] == '{')
wsprintf (appid, TEXT("%s"), AppID);
else
wsprintf (appid, TEXT("{%s}"), AppID);
wsprintf (keyName, TEXT("APPID\\%s"), appid);
returnValue = RegOpenKeyEx (HKEY_CLASSES_ROOT, keyName, 0, KEY_ALL_ACCESS, ®istryKey);
if (returnValue != ERROR_SUCCESS)
return returnValue;
//Error (TEXT("ERROR: Cannot open AppID registry key."), returnValue);
LPSTR s;
PDWORD a;
DWORD type;
returnValue = RegSetValueEx (registryKey, TEXT("RunAs"), 0, REG_SZ, (LPBYTE) Principal, _tcslen (Principal) * sizeof (TCHAR));
if (returnValue != ERROR_SUCCESS)
return returnValue;
RegCloseKey (registryKey);
return returnValue;
}
2) После вызова следующего я получаю, что dcomcnfg.exe показывает в меню
This User — имя Principal.
DWORD
SetRunAsPrincipalX
(
LPTSTR Service,
LPTSTR Principal
)
{
DWORD returnValue;
HKEY registryKey;
TCHAR appid [256];
TCHAR keyName [256];
wsprintf (appid, TEXT("%s"), Service);
wsprintf (keyName, TEXT("System\\CurrentControlSet\\Services\\%s"), appid);
returnValue = RegOpenKeyEx (HKEY_LOCAL_MACHINE, keyName, 0, KEY_ALL_ACCESS, ®istryKey);
if (returnValue != ERROR_SUCCESS)
return returnValue;
//Error (TEXT("ERROR: Cannot open AppID registry key."), returnValue);
LPSTR s;
PDWORD a;
DWORD type;
returnValue = RegSetValueEx (registryKey, TEXT("ObjectName"), 0, REG_SZ, (LPBYTE) Principal, _tcslen (Principal) * sizeof (TCHAR));
if (returnValue != ERROR_SUCCESS)
return returnValue;
// Error (TEXT("ERROR: Cannot set RunAs registry value."), returnValue);
RegCloseKey (registryKey);
return returnValue;
}
3) Даю этому Principal CeBatchLogonRight и юзерский пароль устанавливаю при помощи
DWORD SetRunAsPassword (
LPTSTR AppID,
LPTSTR Principal,
LPTSTR Password
)
{
LSA_OBJECT_ATTRIBUTES objectAttributes;
HANDLE policyHandle = NULL;
LSA_UNICODE_STRING lsaKeyString;
LSA_UNICODE_STRING lsaPasswordString;
WCHAR key [4 + GUIDSTR_MAX + 1];
WCHAR wideAppID [GUIDSTR_MAX + 1];
WCHAR widePassword [256];
DWORD returnValue;
#ifndef UNICODE
STR2UNI (wideAppID, AppID);
STR2UNI (widePassword, Password);
#else
wcscpy (wideAppID, AppID);
wcscpy (widePassword, Password);
#endif
wcscpy (key, L"SCM:");
wcscat (key, wideAppID);
lsaKeyString.Length = (USHORT) ((wcslen (key) + 1) * sizeof (WCHAR));
lsaKeyString.MaximumLength = (GUIDSTR_MAX + 5) * sizeof (WCHAR);
lsaKeyString.Buffer = key;
USES_CONVERSION;
MessageBox(0,"",OLE2A(key),0);
lsaPasswordString.Length = (USHORT) ((wcslen (widePassword) + 1) * sizeof (WCHAR));
lsaPasswordString.Buffer = widePassword;
lsaPasswordString.MaximumLength = lsaPasswordString.Length;
//
// Open the local security policy
//
memset (&objectAttributes, 0x00, sizeof (LSA_OBJECT_ATTRIBUTES));
objectAttributes.Length = sizeof (LSA_OBJECT_ATTRIBUTES);
returnValue = LsaOpenPolicy (NULL,
&objectAttributes,
POLICY_CREATE_SECRET,
&policyHandle);
if (returnValue != ERROR_SUCCESS)
return returnValue;
//
// Store the user's password
//
returnValue = LsaStorePrivateData (policyHandle,
&lsaKeyString,
&lsaPasswordString);
if (returnValue != ERROR_SUCCESS)
{
LsaClose (policyHandle);
return returnValue;
}
LsaClose (policyHandle);
returnValue = SetAccountRights (Principal, TEXT("SeBatchLogonRight"));
if (returnValue != ERROR_SUCCESS)
return returnValue;
return ERROR_SUCCESS;
}
В результате получаю Logon Failure.
Долго копался и в конце концов сделал следующее:
Сохранил реестр до регистрации сервиса (в файл).
Зарегистрировал сервис.
Запустил свою програмку.
Сохранил реестр в файл.
Отрегистрил сервис.
Опять зарегистрил.
Воспользовался dcomcnfg.exe
Сохранил реестр в файл.
Сравнил файлы и выявил, что моя программка не создает в реестре ключ
HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\_SC_<имя сервиса>
В этом ключе каких-то бинарных данных до черта. Похоже что это security.
Грохнул ключик и вот оно — Logon failure.
Что я делаю неправильно при регистрации.
Thanks.
Попробую SeServiceLogonRight