Доступ запрещен при использовании службы совместного использования портов Net.Tcp

Этот вопрос связан с запуском процессов с определенными учетными данными из службы Windows., но это другая проблема.

Я запустил процесс из службы Windows в системном сеансе (0) с определенными учетными данными, но он не может прослушивать URL-адрес общего доступа к порту. Он использует учетную запись домена «Рабочий» на компьютере с Windows Server 2008.

Мой файл SMSvcHost.exe.config: http://pastie.org/private/jxed8bdft0eir5uc371pq

Я также перезапустил службы и машину, но это все еще дает мне это исключение:

System.ServiceModel.CommunicationException: The service endpoint failed to listen on the URI 'net.tcp://localhost:5400/Agent/384' because access was denied.  Verify that the current user is granted access in the appropriate allowAccounts section of SMSvcHost.exe.config. ---> System.ComponentModel.Win32Exception: Access is denied
   at System.ServiceModel.Activation.SharedMemory.Read(String name, String& content)
   at System.ServiceModel.Channels.SharedConnectionListener.SharedListenerProxy.ReadEndpoint(String sharedMemoryName, String& listenerEndpoint)

Мой код ProcessHelper, запускающий процесс: http://pastie.org/private/iytqehsdfujrgil1decda . Я вызываю метод StartAsUserFromService.

Я предполагаю, что связь между SID в конфиге и учетной записью, под которой запущен процесс, как-то не делается. Но почему?

РЕДАКТИРОВАТЬ:

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

Как я могу найти, где находится отсутствующее разрешение?

РЕДАКТИРОВАТЬ:

Я переустановил .NET 4.5.1 на машину и все обновления Windows, но все равно не повезло.

РЕДАКТИРОВАТЬ:

Является ли это правильным способом дублирования токена пользователя, чтобы он мог использовать совместное использование портов? В частности, бит SecurityDescriptor?

private static ImpersonationResult ImpersonateUser(string domain, string username, string password)
{
    IntPtr token = IntPtr.Zero;
    IntPtr primaryToken = IntPtr.Zero;

    try
    {
        // Get token
        bool bImpersonated = LogonUser(
            username,
            domain,
            password,
            (int)LogonType.NetworkClearText,
            (int)LogonProvider.Default,
            ref token);

        if (!bImpersonated)
        {
            throw new Exception(string.Format("Failed to impersonate identity. Error code: {0}", Marshal.GetLastWin32Error()));
        }

        SecurityDescriptor sd = new SecurityDescriptor();
        IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
        Marshal.StructureToPtr(sd, ptr, false);
        InitializeSecurityDescriptor(ptr, 1);
        sd = (SecurityDescriptor)Marshal.PtrToStructure(ptr, typeof(SecurityDescriptor));

        // Set up security
        bool bDecriptorSet = SetSecurityDescriptorDacl(
            ref sd,
            true,
            IntPtr.Zero,
            false);

        if (!bDecriptorSet)
        {
            throw new Exception(string.Format("Failed to set security descriptor. Error code: {0}", Marshal.GetLastWin32Error()));
        }

        SecurityAttributes processAttributes = new SecurityAttributes();
        processAttributes.lpSecurityDescriptor = ptr;
        processAttributes.nLength = (uint)Marshal.SizeOf(sd);
        processAttributes.bInheritHandle = true;

        // Duplicate token
        bool bTokenDuplicated = DuplicateTokenEx(
            token,
            0,
            ref processAttributes,
            (int)SecurityImpersonationLevel.SecurityImpersonation,
            (int)TokenType.TokenPrimary,
            ref primaryToken);

        if (!bTokenDuplicated)
        {
            throw new Exception(string.Format("Failed to duplicate identity token. Error code: {0}", Marshal.GetLastWin32Error()));
        }

        SecurityAttributes threadAttributes = new SecurityAttributes();
        threadAttributes.lpSecurityDescriptor = IntPtr.Zero;
        threadAttributes.nLength = 0;
        threadAttributes.bInheritHandle = false;

        // Got the token
        return new ImpersonationResult()
            {
                Token = primaryToken,
                ProcessAttributes = processAttributes,
                ThreadAttributes = threadAttributes
            };
    }
    finally
    {
        FreeToken(token);
    }
}

private static void FreeToken(IntPtr token)
{
    if (token != IntPtr.Zero)
    {
        CloseHandle(token);
    }
}

РЕДАКТИРОВАТЬ:

Вот часть app.config моего процесса, который включает совместное использование портов: /а>

Вот часть app.config службы, которая запускает процесс: /а>. У него нет проблем с использованием общего доступа к порту, потому что он работает под системной учетной записью.

Сама служба общего доступа к портам включена, и я уже упоминал, что несколько раз перезагружал машину.

Роль «Сервер приложений» не установлена, но когда я добавляю ее, роль общего доступа к портам TCP уже отмечена и неактивна, поэтому ее должно было установить что-то еще. Он поставляется с .NET 4.5.1?


person Edgar    schedule 13.02.2014    source источник
comment
будьте осторожны, файл конфигурации поставляется с образцом раздела <system.serviceModel.activation>, который ЗАКОММЕНТИРОВАН. отредактировав его в блокноте, вы можете это пропустить. обязательно найдите <!-- и --> в этом файле.   -  person Menahem    schedule 18.02.2014
comment
Моя конфигурация правильная: pastie.org/private/jxed8bdft0eir5uc371pq   -  person Edgar    schedule 18.02.2014
comment
действительно, конфиг выглядит хорошо. Вы пытались не привязываться к localhost, а к имени машины?   -  person Menahem    schedule 18.02.2014


Ответы (3)


Предисловие: Пожалуйста, используйте для одного вопроса одну тему...

PortSharing: ГДЕ вы включили совместное использование портов? Мы не можем увидеть это в вашем файле конфигурации. Дополнительные сведения см. в разделе Как: Настроить службу Windows Communication Foundation для использования общего доступа к порту

Вы установили роль «Сервер приложений» на свой сервер? См. также: Контрольный список: использование общего доступа к TCP-порту, чтобы разрешить нескольким приложениям WCF использовать один и тот же TCP-порт< /а>

Включено ли совместное использование портов в системе? См. Как включить службу общего доступа к портам Net.TCP

Кроме того, вы перезапустили свой сервер? Иногда это необходимо (или, по крайней мере, все службы, использующие этот порт), см.: http://blogs.msdn.com/b/joncole/archive/2010/06/10/tcp-port-sharing.-access-is-denied.aspx

Подробное описание совместного использования портов: http://blogs.msdn.com/b/andreal/archive/2009/04/05/net-tcp-ip-port-sharing.aspx

Также имейте в виду, что вы должны добавить некоторые учетные записи для активации, если это необходимо: Настройка сети. Служба совместного использования портов TCP

Вы уверены, что SmSvcHost.exe.config разрешает доступ из вашей учетной записи, под которой запущен ваш процесс?

<configuration>
  <system.serviceModel.activation>
   <net.tcp listenBacklog="16" <!—16 * # of processors -->
      maxPendingAccepts="4"<!— 4 * # of processors -->
      maxPendingConnections="100"
      receiveTimeout="00:00:30" <!—30 seconds -->
      teredoEnabled="false">
      <allowAccounts>
         <!-- LocalSystem account -->
         <add securityIdentifier="S-1-5-18"/>
         <!-- LocalService account -->
         <add securityIdentifier="S-1-5-19"/>
         <!-- Administrators account -->
         <add securityIdentifier="S-1-5-20"/>
         <!-- Network Service account -->
         <add securityIdentifier="S-1-5-32-544" />
         <!-- IIS_IUSRS account (Vista only) -->
         <add securityIdentifier="S-1-5-32-568"/>
       </allowAccounts>
   </net.tcp>
 </system.serviceModel.activation>

person Jochen Kalmbach    schedule 14.02.2014
comment
Полная страница также: blogs.msdn.com/b/andreal/archive/2009/04/05/ и msdn.microsoft.com/en-us/library/aa702669.aspx - person Jochen Kalmbach; 14.02.2014
comment
@Edgar: добавьте свою конкретную учетную запись в файл SmSvcHost.exe.config! Смотрите отредактированный ответ! - person Jochen Kalmbach; 15.02.2014
comment
Я уже сделал это, мой пример конфигурации связан с вопросом. - person Edgar; 16.02.2014

Оказывается, тип входа в систему вызывал некорректную работу разрешений со службой общего доступа к портам. Я изменил его на LogonType.Batch, и он начал работать.

Полный код:

Помощник по процессу: http://pastie.org/private/dlkytj8rbigs8ixwtg

TokenImpersonationContext: http://pastie.org/private/nu3pvpghoea6pwwlvjuq.

person Edgar    schedule 27.02.2014

(Еще один ответ, который может кому-то помочь)

Оказывается, в моем случае вошедший в систему пользователь не имел прав Администрирования. Изменение типа учетной записи на Администратора решило проблему. Я тоже ничего не менял в SmSvcHost.exe.config

person mehul9595    schedule 13.09.2017