Это происходит потому, что у нас G = 80 банков, T = 83 наблюдения на банк и K = 5 параметров на банк, что дает 83-5 = 78 степеней свободы на уравнение, что является проблемой, поскольку SUR оценивает остатки GxG ковариационная матрица. Между тем, OLS не будет выдавать никаких ошибок и будет давать те же оценки, но не будет вычислять ковариационную матрицу, и, следовательно, стандартные ошибки будут другими.
Примечание: Это не обращается к услугам по перечислению как к другому пользователю, но, учитывая более широкое описание того, что Вы делаете, я думаю, что это - хороший ответ.
Я думаю, что можно упростить это много и возможно избежать части проблемы безопасности, если Вы переходите непосредственно к службе интереса. Вместо того, чтобы назвать GetServices, попробуйте это:
string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
string serviceName = ConfigurationManager.AppSettings["ServiceName"];
ServiceController service = new ServiceController( serviceName, machineName );
return service.Status;
Это соединяется непосредственно с сервисом интереса и обходит шаг перечисления/поиска. Поэтому это не требует, чтобы вызывающая сторона имела SC_MANAGER_ENUMERATE_SERVICE
прямо на Диспетчере управления службами (SCM), который удаленные пользователи не имеют по умолчанию. Это действительно все еще требует SC_MANAGER_CONNECT
, но согласно MSDN, которого нужно предоставить удаленным аутентифицируемым пользователям.
После того как Вы нашли сервис интересным, необходимо будет все еще смочь остановить и запустить его, который удаленные пользователи, вероятно, не имеют прав сделать. Однако возможно изменить дескриптор безопасности (DACL) на отдельных сервисах, которые позволили бы Вам предоставить свой доступ удаленных пользователей, чтобы остановить и запустить сервис, не требуя, чтобы они были локальными администраторами. Это сделано через API-функцию SetNamedSecurityInfo. Права доступа, которые необходимо предоставить, SERVICE_START
и SERVICE_STOP
. В зависимости от точно, который группирует этих пользователей, принадлежат, Вы, возможно, также должны были бы предоставить им GENERIC_READ
. Все эти права описаны в MSDN.
Вот некоторый код C++, который выполнил бы эту установку, предположив, что пользователи интереса находятся в "Удаленной Сервисной группе" Контроллеров (который Вы создали бы), и сервисное название является "my-service-name". Обратите внимание, что, если Вы хотели предоставить доступ известной группе, такой как Пользователи (не обязательно хорошая идея), а не группе, Вы создали, необходимо измениться TRUSTEE_IS_GROUP
кому: TRUSTEE_IS_WELL_KNOWN_GROUP
.
Код не имеет никакой проверки ошибок, которую Вы хотели бы добавить. Все три функции, которые могут перестать работать (Get/SetNamedSecurityInfo и SetEntriesInAcl) возвращаются 0 для указания на успех.
Другое Примечание: можно также установить дескриптор безопасности сервиса с помощью инструмента SC, который может быть найден под %WINDIR %\System32, но это не включает программирования.
#include "windows.h"
#include "accctrl.h"
#include "aclapi.h"
int main()
{
char serviceName[] = "my-service-name";
char userGroup[] = "Remote Service Controllers";
// retrieve the security info
PACL pDacl = NULL;
PSECURITY_DESCRIPTOR pDescriptor = NULL;
GetNamedSecurityInfo( serviceName, SE_SERVICE,
DACL_SECURITY_INFORMATION, NULL, NULL,
&pDacl, NULL, &pDescriptor );
// add an entry to allow the users to start and stop the service
EXPLICIT_ACCESS access;
ZeroMemory( &access, sizeof(access) );
access.grfAccessMode = GRANT_ACCESS;
access.grfAccessPermissions = SERVICE_START | SERVICE_STOP;
access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
access.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
access.Trustee.ptstrName = userGroup;
PACL pNewDacl;
SetEntriesInAcl( 1, &access, pDacl, &pNewDacl );
// write the changes back to the service
SetNamedSecurityInfo( serviceName, SE_SERVICE,
DACL_SECURITY_INFORMATION, NULL, NULL,
pNewDacl, NULL );
LocalFree( pNewDacl );
LocalFree( pDescriptor );
}
Это могло также быть сделано от C# с помощью P/Invoke, но это - немного больше работы.
Если Вы все еще конкретно хотите смочь перечислить сервисы как эти пользователи, необходимо предоставить им SC_MANAGER_ENUMERATE_SERVICE
прямо на SCM. К сожалению, согласно MSDN, безопасность SCM может только быть изменена на Windows Server 2003 sp1 или позже.
Спасибо за ту строку кода Charlie. Вот то, что я закончил тем, что делал. Я получил идею от этого веб-сайта: http://www.codeproject.com/KB/cs/svcmgr.aspx?display=Print
Я также должен был добавить учетную запись, я получаю доступ к этому относительно группы Продвинутых пользователей на сервере.
public static ServiceControllerStatus FindService()
{
ServiceControllerStatus status = ServiceControllerStatus.Stopped;
try
{
string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
string serviceName = ConfigurationManager.AppSettings["ServiceName"].ToLower();
ImpersonationUtil.Impersonate();
ServiceController service = new ServiceController(serviceName, machineName);
status = service.Status;
}
catch(Exception ex)
{
status = ServiceControllerStatus.Stopped;
SaveError(ex, "Utilities - FindService()");
}
return status;
}
И вот мой другой класс с ImpersonationUtil. Явитесь олицетворением ():
public static class ImpersonationUtil
{
public static bool Impersonate()
{
string logon = ConfigurationManager.AppSettings["ImpersonationUserName"];
string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
WindowsImpersonationContext impersonationContext = null;
if (LogonUser(logon, domain, password, 2, 0, ref token) != 0)
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
impersonationContext = new WindowsIdentity(tokenDuplicate).Impersonate();
//
return (impersonationContext != null);
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
}
Можно попытаться использовать олицетворение ASP.NET в web.config файле и указать учетную запись пользователя, которая имеет соответствующие полномочия:
<system.web>
<identity impersonate="true" userName="Username" password="Password" />
</system.web
Смотрите на эту статью о MSDN. Я полагаю, что существуют другие опции, которые не требуют хранения пароля в web.config файле, таком как размещение его в ключе реестра вместо этого.
Это заставит рабочий процесс ASP.NET работать под контекстом указанного пользователя вместо пользователя, вошел в веб-приложение. Однако это излагает проблему безопасности, и я сильно заново продумал бы Ваш дизайн. Можно хотеть полагать, что наличие веб-страницы ASP.NET в свою очередь исчерпывает запрос к некоторому другому процессу, который на самом деле управляет сервисами, даже другим сервисом окон, или запишите запрос в таблицу базы данных, которую сервис окон периодически опрашивает.