Re[6]: [.Net 4, cross-process singleton] Покритикуйте код
От: Jolly Roger  
Дата: 05.10.10 06:18
Оценка: 14 (1)
Здравствуйте, Sinix, Вы писали:

S>Увы да, нужен именно logon session sid. Сейчас осталась единственная дырка: локально заходим одновременно под двумя пользователями, под первым запускаем сервер, под вторым (от имени первого) — клиента.


Ну Вам конечно виднее, но всё-же по-моему Вам таки нужен Terminal Service Session ID.

S>Если его добыть — даём права только сессии — вуаля

S>Сейчас осталась единственная дырка: локально заходим одновременно под двумя пользователями, под первым запускаем сервер, под вторым (от имени первого) — клиента.

Так если ориентироваться на Logon Session, то я, воспользовавшись LsaLogonUser, задам токену тот LUID, который был присвоен токену сессии сервера и — вуаля — Ваш сервер примет такое подключение, хотя клиент будет находиться в другой терминальной сессии.

Logon session ID и Terminal Service Session ID — это вещи из параллельных миров. Logon session формируется при логоне юзера. Даже внутри одной пользовательской(терминальной) сессии могут быть процессы с токенами, у которых разные logon session. А это:

локально заходим одновременно под двумя пользователями

как раз таки создание двух терминальных сессий. На XP Fast User Switching реализуется именно через Terminal Service. С Висты оно уже есть всегда — сервисы работают в нулевой терминальной сессии, для вошедшего юзера создаётся терминальная сессия с ID = 1.
"Нормальные герои всегда идут в обход!"
Re[7]: [.Net 4, cross-process singleton] Покритикуйте код
От: Sinix  
Дата: 05.10.10 06:55
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>как раз таки создание двух терминальных сессий. На XP Fast User Switching реализуется именно через Terminal Service. С Висты оно уже есть всегда — сервисы работают в нулевой терминальной сессии, для вошедшего юзера создаётся терминальная сессия с ID = 1.

О как. Забил, коллега реализовал вариант на WCF. Спасибо
Re[7]: [.Net 4, cross-process singleton] Покритикуйте код
От: Sinix  
Дата: 05.10.10 08:51
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

*истерически хихикая и нецензурно бормоча.
Как выяснилось, реализация на WCF "работает" благодаря двум ньюансам в реализации.
Во-первых:

What I see instead is a handle to a pipe named something like...

\\.\pipe\197ad019-6e5f-48cb-8f88-02ae11dfd8c0

...
So in order to locate the correct pipe, a client of a WCF NetNamedPipe service endpoint has to:
— know that the special metadata mechanism exists
— know how to derive from the endpoint URI the name of the file mapping object through which the metadata is published
— located the file mapping object and use it to open a view on the shared memory
— know how to interpret the metadata stored in the shared memory, and translate it into the name of the pipe currently being used by the endpoint


Во-вторых:

If my WCF server process using a Named Pipe-based endpoint doesn't have privileges to create a Global kernel object it silently fails and creates a local one which will not be visible to processes outside of its session.

Кратко: без прав админа WCF не найдёт Named Pipe, запущенный в 2й сессии.

В результате, запустив сампл от имени администратора и без, мы получим _два_ сервера. Коллеге как-то удалось сделать так, чтобы все дальнейшие запуски обращаются к серверу, запущенному с правами администратора

На закуску:

The ACL set up when WCF creates the named pipe looks like this..

— Deny Full Access to NETWORK USERS — that is: deny the access rights specified by the access mask GENERIC_ALL, to any security context having membership of the group with well-known SID S-1-5-2
— Allow the access rights specified by the access mask 0x0012019f, to EVERYONE (the well-known SID S-1-1-0)
— Allow the access rights specified by the access mask 0x0012019f, to the well-known SID S-1-3-0 (CREATOR OWNER)

Вариант с WCF ещё беззащитней моего.

  Код от коллеги, чуть сокращён
using System;
using System.ServiceModel;

namespace WCFSample
{
  [ServiceContract]
  public interface IServiceContract
  {
    [OperationContract]
    void StartOnServer(string[] args);
  }

  public class Service: IServiceContract
  {
    public void StartOnServer(string[] args)
    {
      Console.WriteLine(string.Join(",", args));
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        ServerStart(@"net.pipe://127.0.0.1/wtfService");
      }
      catch (AddressAlreadyInUseException)
      {
        try
        {
          ClientStart(@"net.pipe://127.0.0.1/wtfService");
        }
        catch (Exception ex)
        {
          Console.WriteLine(ex);
          Console.ReadKey();
        }
      }
    }

    private static void ServerStart(string channelUri)
    {
      ServiceHost host = new ServiceHost(typeof(Service), new Uri(channelUri));
      try
      {
        host.AddServiceEndpoint(typeof(IServiceContract),
          new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport),
          new Uri(channelUri));
        host.Open();

        Console.WriteLine("Service is ready, press any key to terminate.");
        Console.ReadKey();
        // ((Service) as Service).LaucnhStartUpWindow();
      }
      catch (CommunicationException ex)
      {
        // Console.WriteLine(ex);
        Console.WriteLine("Client starting...");
        host.Abort();
        throw;
      }
    }

    private static void ClientStart(string channelUri)
    {
      ChannelFactory<IServiceContract> factory =
        new ChannelFactory<IServiceContract>
            (new NetNamedPipeBinding(), new EndpointAddress(channelUri));
      IServiceContract proxy = factory.CreateChannel();

      try
      {
        //signal server that a new instance is selected
        proxy.StartOnServer(new[] { "Hello", "world" });
      }
      catch (EndpointNotFoundException ex)
      {
        Console.WriteLine(ex);
        //return false to indicate this instance is first instance
        // return false;
      }
    }
  }
}
Re[8]: [.Net 4, cross-process singleton] Покритикуйте код
От: Jolly Roger  
Дата: 05.10.10 09:35
Оценка: +1 :)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Jolly Roger, Вы писали:


S>*истерически хихикая и нецензурно бормоча.


Спокойствие, только спокойствие!(c)

S>Как выяснилось, реализация на WCF "работает" благодаря двум ньюансам в реализации.


Ну первое — вроде ничего страшного, нет?

S>Во-вторых:

S>

S>If my WCF server process using a Named Pipe-based endpoint doesn't have privileges to create a Global kernel object it silently fails and creates a local one which will not be visible to processes outside of its session.

S>Кратко: без прав админа WCF не найдёт Named Pipe, запущенный в 2й сессии.

Хм. Возможно, я отстал от жизни, но с каких пор пайпы стали делиться на локальные и глобальные?! По жизни, пайп, созданный в любой сессии, виден как во всех сессиях данной машины, так и в сети. Для открытия может не хватить прав, да, но виден-то будет всем
Пайпы именуются так: "\\.\pipe\PipeName", ни о каких Local-Global и речи нет.

Во-вторых, с каких пор для создания пайпа стала нужна SeCreateGlobal, про которую русским языком по-английски написано:

"Required to create named file mapping objects in the global namespace during Terminal Services sessions. "

, да ещё и в описании namespaces добавлено:

... must have SeCreateGlobalPrivilege enabled in order to create a file-mapping object in the global namespace successfully. The privilege check is limited to the creation of file-mapping objects, and does not apply to opening existing ones.


а для всяких там пайпрв и прочих мьютексов она нафиг не сдалась Тот товарисЧ чуть-чуть напутал с интерпритацией результатов, он без SeCreateGlobal shared section создать не может, а чистые пайпы работать будут.

S>На закуску:

S>

S>The ACL set up when WCF creates the named pipe looks like this..

S>- Deny Full Access to NETWORK USERS — that is: deny the access rights specified by the access mask GENERIC_ALL, to any security context having membership of the group with well-known SID S-1-5-2
S>- Allow the access rights specified by the access mask 0x0012019f, to EVERYONE (the well-known SID S-1-1-0)
S>- Allow the access rights specified by the access mask 0x0012019f, to the well-known SID S-1-3-0 (CREATOR OWNER)

S>Вариант с WCF ещё беззащитней моего.

Да. "Доктор, а может всё-таки COM? Чё сразу в морг-то?"

PS Код пока не смотрел.
"Нормальные герои всегда идут в обход!"
Re[9]: [.Net 4, cross-process singleton] Покритикуйте код
От: Sinix  
Дата: 05.10.10 09:47
Оценка: +1
Здравствуйте, Jolly Roger, Вы писали:

JR>Ну первое — вроде ничего страшного, нет?

Да. Но в результате на ровном месте — ничего не запрещало использовать обычные имена — мы получили грабли, приведшие к п.2. Очевидно, у обычных пайпов был фатальный недостаток.

JR>Хм. Возможно, я отстал от жизни, но с каких пор пайпы стали делиться на локальные и глобальные?!

Не пайпы, а shared memory section, используемая для получения метаданных. Вы же сами цитату нашли

... must have SeCreateGlobalPrivilege enabled in order to create a file-mapping object in the global namespace successfully. The privilege check is limited to the creation of file-mapping objects, and does not apply to opening existing ones.

Кстати, теперь понял (см выделенное) почему новые клиенты коннектятся к серверу, запущенному от админа.

JR>а для всяких там пайпрв и прочих мьютексов она нафиг не сдалась Тот товарисЧ чуть-чуть напутал с интерпритацией результатов, он без SeCreateGlobal shared section создать не может, а чистые пайпы работать будут.

Чистые — да. NetNamedPipeBinding — нет.

JR>Да. "Доктор, а может всё-таки COM? Чё сразу в морг-то?"

+100
Re[10]: [.Net 4, cross-process singleton] Покритикуйте код
От: Jolly Roger  
Дата: 05.10.10 09:59
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Jolly Roger, Вы писали:


JR>>Ну первое — вроде ничего страшного, нет?

S>Да. Но в результате на ровном месте — ничего не запрещало использовать обычные имена — мы получили грабли, приведшие к п.2. Очевидно, у обычных пайпов был фатальный недостаток.

S>Не пайпы, а shared memory section, используемая для получения метаданных. Вы же сами цитату нашли


Ну я её не то чтобы нашёл, просто знал, где лежит Да, товарисч прав, я просто бегло и не до конца просмотрел ссылку, виноват

JR>>Да. "Доктор, а может всё-таки COM? Чё сразу в морг-то?"

S>+100

"Нормальные герои всегда идут в обход!"
Re[9]: [.Net 4, cross-process singleton] Покритикуйте код
От: Константин Л. Франция  
Дата: 05.10.10 14:11
Оценка: :)
Здравствуйте, Jolly Roger, Вы писали:

[]

JR>Да. "Доктор, а может всё-таки COM? Чё сразу в морг-то?"


писать на .net outproc com-сервера та еще задача. да еще и singleton. там большая засада с MTA и вообще.

я бы написал com-обвязку для этого на с++, а на с++\cli интероп с c# кодом. не советую писать всё на .net
Re[7]: [.Net 4, cross-process singleton] Покритикуйте код
От: Аноним  
Дата: 05.10.10 14:31
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Jolly Roger, Вы писали:


JR>>Ну дык каждый ищет там, где ему светлее


S>C COMом знаком только заочно, связываться сейчас ради решения "один раз сделал — всю жизнь мучаешься" не рискну. Ну, и смысл откатываться с устаревшего, но работающего remoting'а на ещё более легаси, но, возможно, работающий ещё лучше COM+ —


Как вариант остается типичный Windows Service — будет честный синглтон, но да, его нужно регистрировать.
Re[7]: [.Net 4, cross-process singleton] Покритикуйте код
От: Jolly Roger  
Дата: 05.10.10 17:06
Оценка:
Здравствуйте, Sinix, Вы писали:

S>C COMом знаком только заочно, связываться сейчас ради решения "один раз сделал — всю жизнь мучаешься" не рискну. Ну, и смысл откатываться с устаревшего, но работающего remoting'а на ещё более легаси, но, возможно, работающий ещё лучше COM+ —


Я тут чего подумал В принципе, если ограничить клиентов работой через диспинтерфейс, то вроде ничего сложного-то в реализации и нет. ID-binding, он конечно помедленней, чем early, но не так уж и сильно, зато работает без всякой регистрации и дополнительных телодвижений, и даже библиотека типов не нужна. А в NET есть аттрибут ClassInterface с типом, кроме прочих, AutoDispatch — похоже, оно самое. Если хотите, завтра выберу время и попробую пример набросать.
"Нормальные герои всегда идут в обход!"
Re[8]: [.Net 4, cross-process singleton] Покритикуйте код
От: Sinix  
Дата: 06.10.10 00:32
Оценка:
Здравствуйте, Jolly Roger, Вы писали:


JR>Я тут чего подумал В принципе, если ограничить клиентов работой через диспинтерфейс...

Не, сеньксь конечно, но я остановился на варианте с разрешением на пайп только для session logon sid.
http://msdn.microsoft.com/en-us/library/aa446670.aspx
Берётся оттуда же:
http://msdn.microsoft.com/en-us/library/aa379626.aspx
Документации нет никакой, только случайные упоминания, но оно работает.
Re[9]: [.Net 4, cross-process singleton] Покритикуйте код
От: Jolly Roger  
Дата: 06.10.10 01:11
Оценка: 5 (1)
Здравствуйте, Sinix, Вы писали:

S>http://msdn.microsoft.com/en-us/library/aa446670.aspx

S>Берётся оттуда же:
S>http://msdn.microsoft.com/en-us/library/aa379626.aspx
S>Документации нет никакой, только случайные упоминания, но оно работает.

Кое-чего можно посмотреть. Вот здесь утилиты от Руссиновича (раньше было Sysinternals, с некоторых пор Windows Sysinternals). Они все полезные, но в данном случае нас интересует logonsessions.exe. Ей можно посмотреть список всех Logon Sessions, существующих в данный момент, кто логинился, как, когда, в какой терминальной сессии. Можно, например, войти под пользователем X, потом через контекстное меню Run As запустить какой-нибудь блокнот от имени того-же пользователя X, и сравнить список логон сессий до и после, просто для информации
"Нормальные герои всегда идут в обход!"
Re[10]: to AndrewVK
От: Константин Л. Франция  
Дата: 06.10.10 12:25
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, Jolly Roger, Вы писали:


КЛ>[]


JR>>Да. "Доктор, а может всё-таки COM? Чё сразу в морг-то?"


КЛ>писать на .net outproc com-сервера та еще задача. да еще и singleton. там большая засада с MTA и вообще.


КЛ>я бы написал com-обвязку для этого на с++, а на с++\cli интероп с c# кодом. не советую писать всё на .net


что тебя так развеселило? Есть положительный опыт написания com local server полностью на .net? Так покажи нам
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.