На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Как создать COM объект под определенным пользователем.
    Всем привет.

    В общем ситуация такая. Есть два COM компонента. Один из них служба. Пусть будут они называться ProxyService и SomeCom.
    Служба ProxyService запускается и работает от имени User1, в DCONFIG для COM компонента этой службы так же прописан User1.
    У COM компонента SomeCom - в DCONFIG так же прописано запускаться от имени User2.


    Теперь при запуске службы ProxyService она пытается создать COM Объект SomeCOM. Но получает ошибку Class not registered.
    Класс при этом зарегистрирован, оба КОМ зарегистрированны корректно.

    В настройках COM для SomeCom прописаны разрешения на запуск и активацию для пользователя User1, так же в локальных политиках все эти пользователи добавлены в привилегии Log on as service, Log on as batch job.

    Если например для этих двух COM в настройках прописать одинакового пользователя - все запускается. Если разные(причем у упользователя User1 услужбы Proxy пользователь имеет меньше привилегий, чем у пользователя COM - SomeCom) - то выдает Class not registered.

    В какую сторону копать? Может быть еще какие то разрешения нужно выставить? Или как то по особому нужно создавать COM ?

    Добавлено
    Нашел что то вот такое - https://msdn.microsoft.com/en-us/library/ms...687(VS.85).aspx в кратце - использовать Elevation Moniker, но пока только читаю что это и нафига оно нужно.
    Сообщение отредактировано: KILLER -
      Нашел возможное решение проблемы. И вроде как не прибегая к Elevation Moniker. В понедельник проверю окончательно эту идею, но на первых тестах вроде как отработало, и кое что стало ясно из того, как работает COM с настройками безопасности.
      Если не забуду в понедельник отпишу о результатах.
        А создавать экземпляр SomeCOM из-под пользователя User2 посредством LogonUser() и имперсонацией отдельно взятой нитки ProxyService-а под него, не работает, что ль? Log on as service по идее должен разрешать LogonUser(), требуемая привилегия должна у User1 быть в наличии, но возможно, задизабленная по дефолту.
          Цитата Qraizer @
          А создавать экземпляр SomeCOM из-под пользователя User2 посредством LogonUser() и имперсонацией отдельно взятой нитки ProxyService-а под него, не работает, что ль?

          Не знаю. Не пробовал. Изначально все эти компоненты работали как и все - от .\LocalSystem, теперь потребовалось, что бы инсталятор - на этапе установки устанавливал от каких учеток они будут работать. Планировалось все сделать без изменения самих COM. Но выяснилось что чего то не хватает, т.к. если один COM запускает другой COM от пользователя, с меньшими привилегиями, то почему то не видит класс этого COM, который пытается запустить.
            А зачем танцы с разными учётками и созданием компонентов от одного другим? Тогда бы разумнее сделать их создание (запуск) независимым и далее наладить какой-то inter-process communication: через shared memory, через localhost-сокеты или что-то в этом стиле.
            Сообщение отредактировано: Mr.Delphist -
              Цитата Mr.Delphist @
              А зачем танцы с разными учётками и созданием компонентов от одного другим?

              Ну потому что так спроектирована система. Есть два COM компонента. Один из них(Вот этот ProxyService) общается с сервером(который может быть вообще на другой машине), и с агентом, и передает/получает данные от сервера - агенту и назад. Плюс ко всему он сам запускает агентов, потому что они не умеют этого делать.

              Цитата Mr.Delphist @
              Тогда бы разумнее сделать их создание (запуск) независимым и далее наладить какой-то inter-process communication: через shared memory, через localhost-сокеты или что-то в этом стиле.

              В смысле не зависимым? Оно и так сообщается по COM технологии, которой по сути пофигу - на одной машине все это или на разных. Просто изначально писалось все это так, что работало от localhost/network service. И всех все устраивало. А теперь вот нужно сделать так, чтоб разные COM работали под разными юзерами. :-?
                Цитата KILLER @
                В какую сторону копать? Может быть еще какие то разрешения нужно выставить? Или как то по особому нужно создавать COM ?


                В dcomcnfg->Component Services->...->DCOM Config->SomeCom в свойствах есть вкладка Security.
                Наверное надо там в Launch and Activation Permissions, или других, дать нужные права соответствующему пользователю.
                  Цитата KILLER @
                  В смысле не зависимым? Оно и так сообщается по COM технологии, которой по сути пофигу - на одной машине все это или на разных.

                  В том смысле, что сделать их всех out-of-proc серверами, а не COM DLL. На крайний случай, попробовать через суррогатный процесс грузить эти DLL.

                  И да, для работы COM с разных машин надо немало покувыркаться в настройках безопасности: а если керберос-домен, а если просто одноранговая сетка и т.п. После некоторых настроек надо не забывать перезагружаться, даже если конфигуратор не сказал. В общем, ой :)
                    Цитата Олег М @
                    Наверное надо там в Launch and Activation Permissions, или других, дать нужные права соответствующему пользователю.

                    Это все выставлено. Вроде в 1 посту об этом писал.
                      Цитата KILLER @
                      Это все выставлено. Вроде в 1 посту об этом писал.

                      У тебя там написано, что запускается под User1 и права прописаны для User1 и т.д.
                      А надо бы дать одинаковые права на запуск для User1 и User2.

                      Ещё лучше дать права, в DCOM config - Security, для Everyone и проверить что всё работает в принципе.
                        Цитата Олег М @
                        У тебя там написано, что запускается под User1 и права прописаны для User1 и т.д.
                        А надо бы дать одинаковые права на запуск для User1 и User2.

                        Я вообще все возможные варианты перепробовал там задавать, пришел к выводу - Если компонент DCOM1 работает из под User1, а второй DCOM2 работает от User2, и Если при этом DCOM1 запускает DCOM2, то все это будет работать только если User1 у DCOM1 наделен такими же правами или больше, чем User2 у DCOM2(это с учетом всех настроек разрешений и всего остального, которые тут упоминали даже вскользь). Если юзер у COM компонента, который хочет запустить второй - ниже по привилегиям, чем у запускаемого - то облом.
                        Но это все при условии что соблюдается защита COM.
                        Именно по этому создал тему.

                        Основная проблема в том, что COM Service от пользователя NETWORK SERVICE, не может стартануть другой COM, у которого юзер например LocalSystem.
                        Ну и с другими пользователями - ровно то же самое.

                        Цитата Олег М @
                        У тебя там написано, что запускается под User1 и права прописаны для User1 и т.д.

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

                        Цитата Олег М @
                        Ещё лучше дать права, в DCOM config - Security, для Everyone и проверить что всё работает в принципе.

                        Олег М, все права давал, я вообще все перепробовал, все настройки - которые в этой теме даже мельком упоминаются, я пробовал давать на все права, в разных вариациях. Ничего не помогло. Начал читать литературу, наткнулся на очень интересную статью на RSDN(если надо кому, и если не забуду, ну или напомните - как выйду на работу скину ссылку на статью, но в принципе вы ее и сами можете найти - Безопасность COM вроде называется или как то так), там как раз описывается моя ситуация, на сколько я понял, и поясняется как это работает, и что надо допиливать, чтоб заработал мой вариант. Но пока это отложили, в недалеком будущем, думаю вернусь к этой проблеме.
                        Вся фишка в том(по крайней мере я начал к этому склонятся в последнее время), что проблема не в настройках(Ну может и в настройках, но я хз где что можно еще что выставить?), а в самом COM.

                        Перечитал кучу МСДН, и книг, и нигде не упоминается какая то левая настройка. Все что написано в MSDN/Microsoft Support касательно этого вопроса - я все перепробовал, и все бестолку :(
                        Сообщение отредактировано: KILLER -
                          Цитата KILLER @
                          Если юзер у COM компонента, который хочет запустить второй - ниже по привилегиям, чем у запускаемого - то облом.
                          Вообще говоря, известная проблема для сервисов: запустить процесс с правами и привилегиями конкретного пользователя вместо LocalSystem. Естественно, что если создаваемый процесс получит токен привилегированного создателя, то это будет, мягко говоря, сильно неправильно. Поэтому обычный простой старт процесса просто проваливается.
                          Обычно проще всего поступать, как я ранее писал: LogonUser(), имперсонировать под него нитку и затем CreateProcessXXXX() из этой нитки. Как вариант – взять дубликат своего токена, поудалять из него лишнее посредством перечисления его контента, ориентируясь на состав токена пользователя, и т.о. получить токен без привилегий, которые не смог бы удержать токен пользователя. Вероятно, COM в сервисах сталкивается с подобными проблемами при старте компонент-сервера, но тебе возвращает LastError(), как-то обёрнутые в HRESULT.
                          Сообщение отредактировано: Qraizer -
                            Цитата Qraizer @
                            Обычно проще всего поступать, как я ранее писал: LogonUser(), имперсонировать под него нитку и затем CreateProcessXXXX() из этой нитки.

                            Исключено )) И сейчас объясню почему. Я сейчас переделываю инсталятор на новые реквы, и вот эти COM компоненты - которые я устанавливаю - я регистрирую их, прописываю все разрешения в DCOM Config, в политиках и т.д., потом стартую их после установки. Но это не значит что я теперь могу следить за дальнейшей работой этих компонентов. Установка прошла - все, установщик сделал или не сделал свое дело - в данном случае запустил/не запустил. А уж потом - оно должно работать автоматически, и если какой то агент упал, этот ProxyService отслеживает это событие и поднимает его заного.

                            Т.е. то что ты предлагаешь - это нужно пилить непосрдественно в COM компонентах. А я то пока установщик пилю, а эти COM - с другого проекта немного, и я предлагал изменить их, т.к. переходим на новую логику работы. И вот как допилю инсталятор - я до них и доберусь. Но когда я до них доберусь, думаю делать LogonUser в данном случае будет слишком дорогой операцией. Там есть вроде приемы взаимодействия между COM компонентами, чтоб один мог запускать другого даже из под мега ограниченой учеткой. Но я пока до этих COM не добрался.

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

                            Добавлено
                            Просто изначально рассчитывали на то, что новая логика сервисов/агентов заведется без доработки самих сервисов/агентов, путем выставления соответствующих разрешений автоматически на этапе установки. А тут облом оказывается. :-?
                            Сообщение отредактировано: KILLER -
                              Цитата KILLER @
                              Т.е. сами наши COM допиливать нужно.
                              Ну да, это с самого начала было ясно. Почти. Окончательно – после уточнения что более привилегированный юзер не может стартануть процесс под менее привилегированным. И это не в COM дело, это везде так. Просто COM в итоге всё равно запускает сервер компонента через какой-нибудь CreateProcessXXX(), куда ж он денется-то.
                              Цитата KILLER @
                              Но когда я до них доберусь, думаю делать LogonUser в данном случае будет слишком дорогой операцией.
                              Ну это да. Это ж целая рабочая станция создаётся, пусть и неинтерактивная. Но требуется это только один раз, при собственном старте.
                              Правда, держать юзера залогиненным постоянно тоже как-то неправильно. Лучше все-таки при старте сделать LogonUser(), затем сделать дубликат своего собственного токена, поудалять из него лишнее и использовать этот, а юзера после этого можно и разлогинить. Если я правильно понимаю проблему, этого должно хватить.
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0404 ]   [ 17 queries used ]   [ Generated: 23.04.24, 15:24 GMT ]