Откройте Directory Module Developer Note
Новая архитектура была представлена в OS X v10.9, Индивидуалисты для разрешения создания собственного компонента Открывают модули Directory. В отличие от DirectoryService, opendirectoryd использует 'модули', реализованные в качестве автономного процесса, использующего XPC для передачи с opendirectoryd. При реализации модуля, поскольку служба XPC гарантирует частное адресное пространство, улучшает безопасность и надежность, так как модули не могут разрушить другой модуль, ни opendirectoryd.
Поддержка плагинов DirectoryService была осуждена и будет удалена в будущем выпуске.
Динамичный / Персистентные Данные
Существует API, доступный, чтобы хранить персистентные данные на основе Базовых типов Основы. Этот API является предпочтительным методом, поскольку он связывает данные с соответствующей конфигурацией. Когда изменения происходят (т.е. «odmoduleconfig_set_dynamicdata»), это кэшируется в памяти и пишется в диск.
Возможности модуля
Модули тегируются как наличие определенных возможностей на основе обратных вызовов, которые они поддерживают. Например:
Аутентификация — поддерживает некоторую форму аутентификации
Соединение — поддерживает соединения
Открытие — способный к определению подходящего списка серверов
Модификация — поддерживает рекордные модификации
Политика — читающий/пишущий политики паролей
Запрос — запросы записей
Разделение на уровни модуля
Новая архитектура модуля позволяет разделять на уровни модулей для реализации различной функциональности или функциональности переопределения в зависимости от потребностей. Как пример, Поддержка Active Directory по умолчанию использует 4 модуля в различных областях для выполнения связи:
ActiveDirectory
Kerberos
NetLogon
LDAP
Проект позволяет модулям «переопределять» функциональность при необходимости и избегает потребности повторно реализовать функциональность в каждом модуле.
Запросы
У большинства действия будет связанный объект запроса (т.е. «od_request_t») передал в обратные вызовы. Запросы могут быть сгенерированы внешне (через вызовы API) или внутренне как артефакт другого вызова. Структура запроса содержит дочерний элемент для порождения отношения, улучшающего возможность отладить проблемы и фильтр к конкретным вопросам. Объект запроса допускает простой самоанализ в работу в полете и полезное журналирование. Активные запросы могут быть просмотрены с помощью “odutil, показывают запросы”.
Уровень перевода с помощью Таблиц отображения
Новый уровень перевода создается непосредственно в ‘opendirectoryd’, позволяющий модулям работать в их собственном пространстве имен. Любой модуль может использовать уровень перевода путем обеспечения надлежащих таблиц отображения в конфигурации узла или через шаблон отображений. Когда таблица отображения будет предоставлена, ‘opendirectoryd’ переведет стандартные атрибуты (т.е. «kODAttributeTypeFullName») к собственному атрибуту присваиваемого значения (т.е. «cn»).
Точки входа модуля
Функциональная таблица должна быть предоставлена модулем, когда загружено. Функциональная таблица сообщает системе, какие обратные вызовы поддерживаются, но не диктует, который будет активен. Использование модуля диктует конфигурация для данного узла. Модуль должен заполнить «odmodule_vtable_s» с надлежащими обратными вызовами и вызовом “odmodule_main ()” соответственно (см. ниже).
int |
main(int argc, char *argv[]) { |
static struct odmodule_vtable_s vtable = { |
.version = ODMODULE_VTABLE_VERSION, |
.odm_initialize = initialize, |
.odm_copy_auth_information = copy_auth_information, |
.odm_configuration_loaded = configuration_loaded, |
.odm_locate_service = locate_service, |
.odm_parse_dynamic_destination = parse_dynamic_destination, |
.odm_create_connection_with_options = create_connection_with_options, |
.odm_copy_details = copy_details, |
.odm_NodeSetCredentials = NodeSetCredentials, |
.odm_NodeSetCredentialsExtended = NodeSetCredentialsExtended, |
... |
}; |
odmodule_main(&vtable); |
return 0; |
} |
Модуль потеряет контроль, как только «odmodule_main» вызывают, и с этим будут только консультироваться через предоставленные обратные вызовы при необходимости. Большинство обратных вызовов имеет прямое отображение на платформу APIs, хотя существуют дополнительные, используемые для поддержки базовой функциональности:
odm_initialize
— вызванный только один раз, когда сначала загружается модульodm_configuration_loaded
— названный в первый раз конфигурация загружается новым UUIDodm_copy_auth_information
— должен быть реализован модулями аутентификации для информирования opendirectoryd возможностейodm_copy_details
— скопируйте подробные данные о соединении (объединенный через все модули для ответа на ODNodeCopyDetails)odm_create_connection_with_options
— создайте новый объект соединения для модуляodm_locate_service
— вызванный неоднократно для определения местоположения доступных серверовodm_parse_dynamic_destination
— используемый для парсинга неизвестного целевого синтаксиса в допустимое место назначения
Только APIs, имеющий реализацию, должен быть соединен проводом к обратному вызову. Все неподдерживаемые обратные вызовы должны быть установлены в NULL соответственно. Строго рекомендуется, чтобы модули реализовали профиль песочницы для ограничения воздействия системы.
Обработка запросов
Существует три (3) типичных кода возврата для большинства функциональных обратных вызовов:
eODCallbackResponseSkip — пропустите текущий модуль и попробуйте следующий
eODCallbackResponseAccepted — принятый текущим модулем и это ответит соответственно
eODCallbackResponseRefused — откажитесь работа (проигнорирует все другие модули),
Обычно модуль только возвратит одно из первых двух значений. Как только запрос был принят, он должен реагировать на тот запрос соответственно. Существует несколько функций отклика, доступных в зависимости от активного обратного вызова:
odrequest_respond_success
odrequest_respond_error
odrequest_respond_recordcreate
и т.д.
Отображение шаблонов
Модули могут обеспечить предварительно установленные таблицы отображения через шаблон, или они могут быть включены непосредственно в конфигурации через APIs ODConfiguration. Таблицы отображения являются по существу словарем стандартных типов записи/атрибута собственному компоненту, составленным или статическим значениям. И собственные и стандартные атрибуты чувствительны к регистру и поэтому должны соответствовать математические ожидания от сервера.
Конфигурационные файлы
Шаблон «конфигурации» во многом как конфигурационный файл, но не имеет специфических особенностей об узле. Это обеспечивает набор по умолчанию опций, разметок модуля, среди прочего. Шаблон конфигурации не необходим, поскольку вся информация может быть включена в конфигурационный файл непосредственно. Ниже снимок сложного шаблона, использующегося для функциональности Active Directory. Снимок показывает, что аутентификация использует три (3) возможных модуля. С модулями консультируются в порядке, представленном в конфигурации.
Расположение модуля повреждается в 4 типа областей:
«аутентификация» - используемый для аутентификации связала APIs
«значение по умолчанию» - используемый для всех категорий вызовов (будет добавлен к хвосту других списков),
«открытие» - используемый для определения местоположения серверов, подходящих для этой конфигурации узла
«сеанс» - используемый для запросов и модификации связал APIs (a.k.a., общий модуль API)
Конфигурация APIs
Objective C базировал конфигурацию, API был добавлен к Открыть платформе Directory. Новый API позволит манипулирование конфигурацией включая шаблон, отображения и опции среди многих других элементов. Существует пять (5) базовых классов: ODConfiguration, Одмэппингс, ODRecordMap, ODAttributeMap и ODModuleEntry. Шаблон проекта предоставит скелетному инструменту конфигурирования все необходимые биты.
Пример создания конфигурации показан ниже этого, использует и пользовательский модуль и предоставленный Apple модуль:
/* create an ODRecordMap container */ |
ODRecordMap *recordMap = [ODRecordMap recordMap]; |
/* map standard attributes to LDAP native equivalent */ |
[recordMap setAttributeMap: [ODAttributeMap attributeMapWithValue: @"cn"] forStandardAttribute: kODAttributeTypeFullName]; |
[recordMap setAttributeMap: [ODAttributeMap attributeMapWithValue: @"homeDirectory"] forStandardAttribute: kODAttributeTypeNFSHomeDirectory]; |
/* create an ODMappings container */ |
ODMappings *mappings = [ODMappings mappings]; |
/* add the newly created ODRecordMap so it is used for Users */ |
[mappings setRecordMap: recordMap forStandardRecordType: kODRecordTypeUsers]; |
/* create an ODConfiguration container */ |
ODConfiguration *configuration = [ODConfiguration configuration]; |
/* add the mappings to the configuration as a default */ |
configuration.defaultMappings = mappings; |
/* create a module entry that will be used in this configuration */ |
ODModuleEntry *myModuleEntry = [ODModuleEntry moduleEntryWithName: @"MyModule" xpcServiceName: @"com.example.myModule"]; |
ODModuleEntry *ldapModuleEntry = [ODModuleEntry moduleEntryWithName: @"ldap" xpcServiceName: nil]; |
/* set a specific option for LDAP */ |
[ldapModuleEntry setOption: @"Use altServer replicas" value: @YES]; |
/* |
* the Apple provided LDAP module will be used for authentication and general APIs |
* the custom Module will be consulted for authentications first |
* the LDAP module will be used to discover servers |
*/ |
configuration.authenticationModuleEntries = @[ myModuleEntry, ldapModuleEntry ]; |
configuration.generalModuleEntries = @[ ldapModuleEntry ]; |
configuration.discoveryModuleEntries = @[ ldapModuleEntry ]; |
/* add a comment to the configuration */ |
configuration.comment = @"Custom configuration for ldap.example.com"; |
/* set a default destination for the configuration */ |
configuration.preferredDestinationHostName = @"ldap.example.com"; |
configuration.preferredDestinationHostPort = 389; |
/* set global options */ |
configuration.queryTimeoutInSeconds = 30; |
configuration.connectionIdleTimeoutInSeconds = 120; |
configuration.connectionSetupTimeoutInSeconds = 15; |
/* give the configuration a name */ |
configuration.nodeName = @"/LDAPv3/ldap.example.com"; |
/* get the appropriate rights to change the configuration of Open Directory, allowing user interaction */ |
NSError *error; |
SFAuthorization *authorization = [[ODSession defaultSession] configurationAuthorizationAllowingUserInteraction: TRUE error: &error]; |
if (authorization) { |
/* attempt to add the configuration to the default session */ |
if (![[ODSession defaultSession] addConfiguration: configuration authorization: authorization error: &error]) { |
/* error occurred */ |
} |
} else { |
/* error occurred */ |
} |
Обработчики аутентификации
С модулями аутентификации будут консультироваться заранее через информационный обратный вызов аутентификации. В настоящее время существует 3 типа запросов, которые могли бы произойти для модуля:
eODAuthInfoAttributes | Определите, какие стандартные или собственные атрибуты необходимы для завершения запроса аутентификации.
Модули аутентификации могут не иметь доступа к рекордным данным, поэтому это должно обеспечить список атрибутов, это должно выполнить запрос. Это позволяет ‘opendirectoryd’ выбирать атрибуты с упреждением прежде, чем вызвать в модуль, чтобы сделать аутентификацию. Существует набор по умолчанию всегда получающихся атрибутов. Если никакие дополнительные атрибуты не требуются, ничто не требуется.
kODAttributeTypeMetaRecordName kODAttributeTypeAuthenticationAuthority kODAttributeTypePasswordPolicyOptions kODAttributeTypePassword kODAttributeTypeGUID kODAttributeTypeUniqueID kODAttributeTypeRecordType |
eODAuthInfoAuthTypes | Массив типов аутентификации, поддерживаемых этим модулем:
kODAuthenticationTypeCRAM_MD5 kODAuthenticationTypeDigest_MD5 kODAuthenticationTypeClearText, и т.д. |
eODAuthInfoMechanisms | Массив механизмов поддерживается модулем аутентификации. Значения соответствуют тем в AuthenticationAuthority (например, «Kerberos», «основной», и т.д.). |
Все обратные вызовы аутентификации будут переданы словарь XPC, названный «add_info», который будет содержать дополнительную информацию, связанную с запросом, указанным выше. В словаре существует три (3) возможных ключа:
kODAuthInfoUserDetails | XPC_TYPE_DICTIONARY ключей имел отношение к пользователю |
kODAuthInfoConnectionDestination | XPC_TYPE_DICTIONARY, содержащий текущее место назначения для соединения на время сеанса. Допускает модуль аутентификации для контакта с тем же сервером, если он выполняет многократные протоколы. |
kODAuthInfoSessionCredentials | XPC_TYPE_DICTIONARY, содержащий текущие учетные данные, присоединил к соединению на время сеанса, обслуживающему вызовы API. Учетные данные сеанса могут требоваться зависящий для завершения работы. |
Журналирование
Рекомендуется, чтобы модули использовали предоставленное журналирование API. Все журналирование будет направлено к «/var/log/opendirectoryd.log». Используя API сохранит ключевые подробные данные о запросе включая любые отношения к другим запросам. API поддерживает форматы стиля CF:
odrequest_log_message(request, <loglevel>, <format string or message>, ...); |
Сообщения журнала имеют стандартизированный формат, которые включают идентификаторы на основе PID и запрашивают IDs, допускающий простую фильтрацию и отладку:
2013-01-01 12:43:02.258999 PDT - 62906.6480.6481, Module: search - ODNodeCreateWithNameAndOptions request, SessionID: 00000000-0000-0000-0000-000000000000, Name: /Local/Default, Options: 0x0 |
2013-01-01 12:43:02.259046 PDT - 62906.6480.6481, Node: /Local/Default, Module: search - found an existing shared connection '/Local/Default:PlistFile:A3129A95-FC85-4E7B-B359-E3F795997716' in pool |
2013-01-01 12:43:02.259055 PDT - 62906.6480.6481, Node: /Local/Default, Module: search - node assigned UUID - EC9BFA56-4CAF-44C2-93F9-AF84930C22EA |
2013-01-01 12:43:02.259088 PDT - 62906.6480.6481, Node: /Local/Default, Module: search - ODNodeCreateWithNameAndOptions completed |
«Идентификатор» для сообщения журнала «62906.6480.6481», который соответствует:
62906
— вызов PID6480
— исходный клиентский запрос6481
— внутренний дочерний запрос, инициированный «поисковым» модулем для удовлетворения ID 6480 запроса
Существует другая информация, включенная в различное сообщение, такое как SessionID, NodeID, текущий Модуль, и т.д. Журналирование может быть скорректировано с помощью “odutil журнал набора <уровень>”, где уровень журнала: «значение по умолчанию», «уведомление», «информация» или «отладка».
Существует способ проверить текущий уровень журнала для предотвращения ненужных и/или дорогих операций для генерации сообщения журнала для невключенного уровня.
if (log_level_enabled(eODLogNotice)) { |
// do more expensive operations |
} |
Возможные уровни включают
eODLogCritical
— перенаправления к system.log такжеeODLogError
— некоторая ошибка произошла (это - уровень журналирования значения по умолчанию),eODLogWarning
— касающийся, но не фатальныйeODLogNotice
— нормальные подробные данные журнала для высокоуровневой информации, это должно быть минимальной информациейeODLogInfo
— некоторая информационная информация (как проверки соединения, сканирования, и т.д.)eODLogDebug
— полная отладочная информация должна была помочь диагностировать включенные проблемы
Расположения установки
Следующее является надлежащими расположениями установки:
/Library/OpenDirectory/Modules/
— все сторонние модули, упакованные в пакете службы XPC (т.е. module.xpc)/Library/OpenDirectory/Templates/
— предусмотренный сторонние шаблоны конфигурации/Library/OpenDirectory/Mappings/
— предусмотренный сторонние шаблоны отображения
Миграция устаревших конфигураций
Это - Ваша ответственность обработать миграцию устаревших параметров конфигурации.
Откройте Directory Module Template
Для использования Открыть Directory Module Template сделайте следующее:
Загрузите шаблон Xcode путем щелчка на ссылку Companion Files при просмотре этого документа в HTML-форме на developer.apple.com веб-сайте.
Создайте шаблонный каталог проекта (если не существует) путем выдачи следующей команды:
mkdir -p ~/Library/Developer/Xcode/Templates/Project\ Templates/System\ Plug\-ins/
Скопируйте содержание файла в получающийся каталог. Можно открыть тот каталог путем ввода следующей команды:
open ~/Library/Developer/Xcode/Templates/Project\ Templates/System\ Plug\-ins/
Повторно запустите XCode и выберите «Open Directory Module» из раздела «Mac-> System Plug-ins» средства выбора проекта.