Добавляем параметры OwnCloud/NextCloud к freeipa АЛД ПРО
Задача: расширить схему и добавить дополнительные параметры пользователям так, чтобы параметры можно было определять простыми LDAP-запросами, а управлять из интерфейса IPA
Покажу на примере атрибутов для работы с OwnCloud/NextCloud.
1. Создаем файл определения атрибутов схемы ```file.ldif```
dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( 1.3.6.1.4.1.49213.1.1.1 NAME 'owncloudEnabled' DESC 'whether user or group should be available in owncloud' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE) attributeTypes: ( 1.3.6.1.4.1.49213.1.1.2 NAME 'owncloudQuota' DESC 'defines how much disk space is available for the user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE) - add: objectclasses objectClasses: ( 1.3.6.1.4.1.49213.1.2.1 NAME 'owncloudUser' DESC 'A owncloud user' SUP top AUXILIARY MAY ( owncloudEnabled $ owncloudQuota ) )
Создаем скрипт модуля ```userncenabled.py```
from ipaserver.plugins import user from ipalib.parameters import Bool from ipalib import _ user.user.takes_params = user.user.takes_params + ( Bool( "owncloudenabled?", cli_name="owncloudenabled", label=_("Owncloud Share enabled?"), doc=_( "Whether or not a owncloud share is created for this user (default is false)." ), default=False, autofill=True, ), ) user.user.default_attributes.append("owncloudenabled") # pylint: disable-msg=unused-argument,invalid-name,line-too-long def useradd_precallback(self, ldap, dn, entry, attrs_list, *keys, **options): """Callback for `register_pre_callback`. See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details. """ entry["objectclass"].append("ownclouduser") return dn user.user_add.register_pre_callback(useradd_precallback) # pylint: disable-msg=unused-argument,invalid-name,line-too-long def usermod_precallback(self, ldap, dn, entry, attrs_list, *keys, **options): """Callback for `register_pre_callback`. See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details. """ if "objectclass" not in entry.keys(): old_entry = ldap.get_entry(dn, ["objectclass"]) entry["objectclass"] = old_entry["objectclass"] entry["objectclass"].append("ownclouduser") return dn user.user_mod.register_pre_callback(usermod_precallback)
Создаем скрипт модуля ```userncquota.py```
from ipaserver.plugins import user from ipalib.parameters import Str from ipalib.text import _ user.user.takes_params = user.user.takes_params + ( Str( "owncloudquota?", cli_name="owncloudquota", label=_("Owncloud Share Quota"), doc=_( "Defines Owncloud share quota in Bytes. " 'Allowed values are "none",' '"default", e.g. "1024 MB" (default is "default").' ), default="default", autofill=True, pattern="^(default|none|[0-9]+ [MGT]B)quot;, pattern_errmsg="".join( 'may only be "none", ' '"default" or a number of mega-, giga- or terabytes (e.g. 1024 MB)' ), ), ) user.user.default_attributes.append("owncloudquota") def useradd_precallback(self, ldap, dn, entry, attrs_list, *keys, **options): """Callback for `register_pre_callback`. See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details. """ entry["objectclass"].append("ownclouduser") return dn user.user_add.register_pre_callback(useradd_precallback) def usermod_precallback(self, ldap, dn, entry, attrs_list, *keys, **options): if "objectclass" not in entry.keys(): old_entry = ldap.get_entry(dn, ["objectclass"]) entry["objectclass"] = old_entry["objectclass"] entry["objectclass"].append("ownclouduser") return dn user.user_mod.register_pre_callback(usermod_precallback)
Создаем скрипт модуля webUI ```userncenabled.js```
define([ 'freeipa/phases', 'freeipa/user'], function(phases, user_mod) { function get_item(array, attr, value) { for (var i=0,l=array.length; i<l; i++) { if (array[i][attr] === value) return array[i]; } return null; } var nc_enabled_plugin = {}; nc_enabled_plugin.add_nc_enabled_pre_op = function() { var facet = get_item(user_mod.entity_spec.facets, '$type', 'details'); var section = get_item(facet.sections, 'name', 'account'); section.fields.push({ $type: 'checkbox', name: 'owncloudenabled', label: 'Owncloud Share enabled', flags: ['w_if_no_aci'] }); return true; }; phases.on('customization', nc_enabled_plugin.add_nc_enabled_pre_op); return nc_enabled_plugin; });
Создаем скрипт модуля webUI ```userncquota.js```
define([ 'freeipa/phases', 'freeipa/user'], function(phases, user_mod) { function get_item(array, attr, value) { for (var i=0,l=array.length; i<l; i++) { if (array[i][attr] === value) return array[i]; } return null; } var nc_quota_plugin = {}; nc_quota_plugin.add_nc_quota_pre_op = function() { var facet = get_item(user_mod.entity_spec.facets, '$type', 'details'); var section = get_item(facet.sections, 'name', 'account'); section.fields.push({ name: 'owncloudquota', label: 'Owncloud Share Quota', flags: ['w_if_no_aci'] }); return true; }; phases.on('customization', nc_quota_plugin.add_nc_quota_pre_op); return nc_quota_plugin; });
Добавляем в схему нужный класс и нужные атрибуты
ldapadd -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -f file.ldif
Проверяем, что класс добавился
ldapsearch -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -x -s base -b 'cn=schema' objectclasses | grep -i owncloud
Проверяем, что атрибут добавился
ldapsearch -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -x -s base -b 'cn=schema' attributetypes | grep -i owncloud
ipa config-mod --addattr=ipaUserObjectClasses=owncloudUser
Копируем скрипты и перезапускаем
cp usernc*.py /usr/lib/python3/dist-packages/ipaserver/plugins/ cd /usr/lib/python3/dist-packages/ipaserver/plugins/ python -m compileall usernc* && python -O -m compileall usernc* apachectl graceful
Копируем модули к WebUI и перезапускаем
mkdir /usr/share/ipa/ui/js/plugins/{userncenabled,userncquota} cp userncenabled.js /usr/share/ipa/ui/js/plugins/userncenabled/ cp userncquota.js /usr/share/ipa/ui/js/plugins/userncquota/ apachectl graceful
После этого в UI FreeIpa можно добавлять\изменять параметры
А так можно определить через LDAP-запрос
ldapsearch -H ldap://$HOSTNAME -Y GSSAPI "uid=slakwik" -o ldif-wrap=no | grep own
Модификация несложная, но напомню, что самодельные модули между КД АЛД ПРО не копируются и нужно разложить эти python и js скрипты на все КД домена.