diff --git a/base/univention-lib/debian/control b/base/univention-lib/debian/control index a8b100e..1370824 100644 --- a/base/univention-lib/debian/control +++ b/base/univention-lib/debian/control @@ -21,7 +21,8 @@ Depends: ${python:Depends}, python-ldb, python-samba, python-ldap, - python-imaging + python-imaging, + python-univention-lib-umc, Provides: ${python:Provides} Description: UCS - common scripting functions for Python scripts This package contains Python functions used by various @@ -37,6 +38,7 @@ Architecture: all Depends: ${misc:Depends}, python-univention-config-registry (>= 10.0.0-1), python-univention-lib (= ${binary:Version}), + shell-univention-lib-umc, pwgen Description: UCS - common scripting functions for shell scripts This package contains shell functions used by various diff --git a/base/univention-lib/python/umc_connection.py b/base/univention-lib/python/umc_connection.py deleted file mode 100644 index 65c6d05..0000000 --- a/base/univention-lib/python/umc_connection.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/python2.7 -# -*- coding: utf-8 -*- -# -# Univention Common Python Library -# Connections to remote UMC Servers -# -# Copyright 2013-2016 Univention GmbH -# -# http://www.univention.de/ -# -# All rights reserved. -# -# The source code of this program is made available -# under the terms of the GNU Affero General Public License version 3 -# (GNU AGPL V3) as published by the Free Software Foundation. -# -# Binary versions of this program provided by Univention to you as -# well as other copyrighted, protected or trademarked materials like -# Logos, graphics, fonts, specific documentations and configurations, -# cryptographic keys etc. are subject to a license agreement between -# you and Univention and not subject to the GNU AGPL V3. -# -# In the case you use this program under the terms of the GNU AGPL V3, -# the program is provided in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public -# License with the Debian GNU/Linux or Univention distribution in file -# /usr/share/common-licenses/AGPL-3; if not, see -# . - -from httplib import HTTPSConnection, HTTPException -from json import loads, dumps -from socket import error as SocketError - -from univention.config_registry import ConfigRegistry -ucr = ConfigRegistry() -ucr.load() - - -class UMCConnection(object): - - def __init__(self, host, username=None, password=None, error_handler=None): - self._host = host - self._headers = { - 'Content-Type': 'application/json; charset=UTF-8', - 'Accept': 'application/json; q=1, text/html; q=0.5; */*; q=0.1', - 'X-Requested-With': 'XMLHttpRequest', - } - self._error_handler=error_handler - if username is not None: - self.auth(username, password) - - def get_connection(self): - '''Creates a new HTTPSConnection to the host''' - # once keep-alive is over, the socket closes - # so create a new connection on every request - return HTTPSConnection(self._host) - - @classmethod - def get_machine_connection(cls, error_handler=None): - '''Creates a connection with the credentials of the local host - to the DC Master''' - username = '%s$' % ucr.get('hostname') - password = '' - try: - with open('/etc/machine.secret') as machine_file: - password = machine_file.readline().strip() - except (OSError, IOError) as e: - if error_handler: - error_handler('Could not read /etc/machine.secret: %s' % e) - try: - connection = cls(ucr.get('ldap/master')) - connection.auth(username, password) - return connection - except (HTTPException, SocketError) as e: - if error_handler: - error_handler('Could not connect to UMC on %s: %s' % (ucr.get('ldap/master'), e)) - return None - - def auth(self, username, password, auth_type=None): - '''Tries to authenticate against the host and preserves the - cookie. Has to be done only once (but keep in mind that the - session probably expires after 10 minutes of inactivity)''' - data = self.build_data({'username' : username, 'password' : password, 'auth_type': auth_type}) - con = self.get_connection() - try: - con.request('POST', '/umcp/auth', data, headers=self._headers) - except Exception as e: - # probably unreachable - if self._error_handler: - self._error_handler(str(e)) - error_message = '%s: Authentication failed while contacting: %s' % (self._host, e) - raise HTTPException(error_message) - else: - try: - response = con.getresponse() - cookie = response.getheader('set-cookie') - if cookie is None: - raise ValueError('No cookie') - self._headers['Cookie'] = cookie # FIXME: transform Set-Cookie to Cookie - except Exception as e: - if self._error_handler: - self._error_handler(str(e)) - error_message = '%s: Authentication failed: %s' % (self._host, response.read()) - raise HTTPException(error_message) - - def build_data(self, data, flavor=None): - '''Returns a dictionary as expected by the UMC Server''' - data = {'options' : data} - if flavor: - data['flavor'] = flavor - return dumps(data) - - def request(self, url, data=None, flavor=None, command='command'): - '''Sends a request and returns the data from the response. url - as in the XML file of that UMC module. - command may be anything that UMCP understands, especially: - * command (default) - * get (and url could be 'ucr' then) - * set (and url would be '' and data could be {'locale':'de_DE'}) - * upload (url could be 'udm/license/import') - ''' - if data is None: - data = {} - data = self.build_data(data, flavor) - con = self.get_connection() - umcp_command = '/umcp/%s' % command - if url: - umcp_command = '%s/%s' % (umcp_command, url) - con.request('POST', umcp_command, data, headers=self._headers) - response = con.getresponse() - if response.status != 200: - error_message = '%s on %s (%s): %s' % (response.status, self._host, url, response.read()) - if response.status == 403: - # 403 is either command is unknown - # or command is known but forbidden - if self._error_handler: - self._error_handler(error_message) - raise NotImplementedError('command forbidden: %s' % url) - raise HTTPException(error_message) - content = response.read() - content = loads(content) # FIXME: inspect Content-Type response header - if isinstance(content, dict): - return content.get('result', content) - return content diff --git a/base/univention-lib/python/umc_module.py b/base/univention-lib/python/umc_module.py deleted file mode 100644 index 2f93295..0000000 --- a/base/univention-lib/python/umc_module.py +++ /dev/null @@ -1,73 +0,0 @@ -import univention.admin.uexceptions -import bz2 -import zlib -from PIL import Image -import StringIO -import magic -MIME_TYPE = magic.open(magic.MAGIC_MIME_TYPE) -MIME_TYPE.load() -MIME_DESCRIPTION = magic.open(magic.MAGIC_NONE) -MIME_DESCRIPTION.load() - -UMC_ICON_BASEDIR = "/usr/share/univention-management-console-frontend/js/dijit/themes/umc/icons" - -compression_mime_type_handlers = { - "application/x-gzip": lambda x: zlib.decompress(x, 16+zlib.MAX_WBITS), - "application/x-bzip2": bz2.decompress -} - -def get_mime_type(data): - return MIME_TYPE.buffer(data) - -def get_mime_description(data): - return MIME_DESCRIPTION.buffer(data) - -def compression_mime_type_of_buffer(data): - mime_type = get_mime_type(data) - if mime_type in compression_mime_type_handlers: - return (mime_type, compression_mime_type_handlers[mime_type]) - else: - raise univention.admin.uexceptions.valueError( "Not a supported compression format: %s" % (mime_type,)) - -def uncompress_buffer(data): - try: - (mime_type, compression_mime_type_handler) = compression_mime_type_of_buffer(data) - return (mime_type, compression_mime_type_handler(data)) - except univention.admin.uexceptions.valueError: - return (None, data) - -def uncompress_file(filename): - with open(filename, 'r') as f: - return uncompress_buffer(f.read()) - -def image_mime_type_of_buffer(data): - mime_type = get_mime_type(data) - if mime_type in ('image/jpeg', 'image/png', 'image/svg+xml', 'application/x-gzip'): - return mime_type - else: - raise univention.admin.uexceptions.valueError( "Not a supported image format: %s" % (mime_type,)) - -def imagedimensions_of_buffer(data): - fp = StringIO.StringIO(data) - im=Image.open(fp) - return im.size - -def imagecategory_of_buffer(data): - (compression_mime_type, uncompressed_data) = uncompress_buffer(data) - mime_type = image_mime_type_of_buffer(uncompressed_data) - if mime_type in ('image/jpeg', 'image/png'): - return (mime_type, compression_mime_type, "%sx%s" % imagedimensions_of_buffer(uncompressed_data)) - elif mime_type in ('image/svg+xml', 'application/x-gzip'): - return (mime_type, compression_mime_type, "scalable") - -def default_filename_suffix_for_mime_type(mime_type, compression_mime_type): - if mime_type == 'image/svg+xml': - if not compression_mime_type: - return '.svg' - elif compression_mime_type == 'application/x-gzip': - return '.svgz' - elif mime_type == 'image/png': - return '.png' - elif mime_type == 'image/jpeg': - return '.jpg' - return None diff --git a/base/univention-lib/shell/umc.sh b/base/univention-lib/shell/umc.sh deleted file mode 100644 index 6452d31..0000000 --- a/base/univention-lib/shell/umc.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh -# -*- coding: utf-8 -*- -# -# Univention Lib -# shell function for creating UMC operation and acl objects -# -# Copyright 2011-2016 Univention GmbH -# -# http://www.univention.de/ -# -# All rights reserved. -# -# The source code of this program is made available -# under the terms of the GNU Affero General Public License version 3 -# (GNU AGPL V3) as published by the Free Software Foundation. -# -# Binary versions of this program provided by Univention to you as -# well as other copyrighted, protected or trademarked materials like -# Logos, graphics, fonts, specific documentations and configurations, -# cryptographic keys etc. are subject to a license agreement between -# you and Univention and not subject to the GNU AGPL V3. -# -# In the case you use this program under the terms of the GNU AGPL V3, -# the program is provided in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public -# License with the Debian GNU/Linux or Univention distribution in file -# /usr/share/common-licenses/AGPL-3; if not, see -# . - - -eval "$(/usr/sbin/univention-config-registry shell ldap/base)" - -BIND_ARGS="$@" - -umc_frontend_new_hash () { - # create new timestamps for index.html and debug.html in order to - # avoid caching problems in browsers - timestamp=$(date +'%Y%d%m%H%M%S') - for ifile in index.html debug.html error.html js/umc/login.html; do - f="/usr/share/univention-management-console-frontend/$ifile" - [ -w "$f" ] && sed -i 's/\$\(.*\)\$/$'$timestamp'$/' "$f" - done - - # update the symlinks to the js/css directories - for idir in css js; do - rm -f "/usr/share/univention-management-console-frontend/${idir}_\$"*\$ || true - ln -s "$idir" "/usr/share/univention-management-console-frontend/${idir}_\$${timestamp}\$" || true - done - - return 0 -} - -umc_init () { - - eval "$(/usr/sbin/univention-config-registry shell groups/default/domainadmins groups/default/domainusers)" - - # containers - udm container/cn create $BIND_ARGS --ignore_exists --position "cn=univention,$ldap_base" --set name=UMC || exit $? - udm container/cn create $BIND_ARGS --ignore_exists --position "cn=policies,$ldap_base" --set name=UMC --set policyPath=1 || exit $? - udm container/cn create $BIND_ARGS --ignore_exists --position "cn=UMC,cn=univention,$ldap_base" --set name=operations || exit $? - - # default admin policy - udm policies/umc create $BIND_ARGS --ignore_exists --set name=default-umc-all \ - --position "cn=UMC,cn=policies,$ldap_base" || exit $? - - # link default admin policy to the group "Domain Admins" - group_admins="${groups_default_domainadmins:-Domain Admins}" - udm groups/group modify $BIND_ARGS --ignore_exists --dn "cn=$group_admins,cn=groups,$ldap_base" \ - --policy-reference="cn=default-umc-all,cn=UMC,cn=policies,$ldap_base" || exit $? - - # default user policy - udm policies/umc create $BIND_ARGS --ignore_exists --set name=default-umc-users \ - --position "cn=UMC,cn=policies,$ldap_base" || exit $? - - # link default user policy to the group "Domain Users" - group_users="${groups_default_domainusers:-Domain Users}" - udm groups/group modify $BIND_ARGS --ignore_exists --dn "cn=$group_users,cn=groups,$ldap_base" \ - --policy-reference="cn=default-umc-users,cn=UMC,cn=policies,$ldap_base" || exit $? -} - -_umc_remove_old () { - # removes an object and ignores all errors - name=$1; shift - module=$1; shift - container=$1 - - udm $module remove $BIND_ARGS --dn "cn=$name,$container,$ldap_base" 2>/dev/null || true -} - -umc_operation_create () { - # example: umc_operation_create "udm" "UDM" "users/user" "udm/*:objectType=users/*" - name=$1; shift - description=$1; shift - flavor=$1; shift - operations="" - for oper in "$@"; do - operations="$operations --append operation=$oper " - done - udm settings/umc_operationset create $BIND_ARGS --ignore_exists \ - --position "cn=operations,cn=UMC,cn=univention,$ldap_base" \ - --set name="$name" \ - --set description="$description" \ - --set flavor="$flavor" $operations || exit $? -} - -umc_policy_append () { - # example: umc_policy_append "default-umc-all" "udm-all" "udm-users" - policy="$1"; shift - - ops="" - for op in "$@"; do - ops="$ops --append allow=cn=$op,cn=operations,cn=UMC,cn=univention,$ldap_base " - done - - udm policies/umc modify $BIND_ARGS --ignore_exists \ - --dn "cn=$policy,cn=UMC,cn=policies,$ldap_base" $ops || exit $? -} diff --git a/management/univention-management-console/debian/control b/management/univention-management-console/debian/control index e999998..68cfd92 100644 --- a/management/univention-management-console/debian/control +++ b/management/univention-management-console/debian/control @@ -169,3 +169,32 @@ Description: UCS Management Console - Web server an integrated, directory driven solution for managing corporate environments. For more information about UCS, refer to: http://www.univention.de/ + +Package: python-univention-lib-umc +Architecture: all +Depends: ${python:Depends}, + ${misc:Depends}, + python-univention-config-registry, +Provides: ${python:Provides} +Description: common UMC scripting functions for Python scripts + This package contains Python functions used by various + components of UCS. + . + It is part of Univention Corporate Server (UCS), an + integrated, directory driven solution for managing + corporate environments. For more information about UCS, + refer to: http://www.univention.de/ + +Package: shell-univention-lib +Architecture: all +Depends: ${misc:Depends}, + python-univention-config-registry, + python-univention-lib-umc, +Description: common UMC scripting functions for shell scripts + This package contains shell functions used by various + components of UCS. + . + It is part of Univention Corporate Server (UCS), an + integrated, directory driven solution for managing + corporate environments. For more information about UCS, + refer to: http://www.univention.de/ diff --git a/management/univention-management-console/lib/python/umc_connection.py b/management/univention-management-console/lib/python/umc_connection.py new file mode 100644 index 0000000..65c6d05 --- /dev/null +++ b/management/univention-management-console/lib/python/umc_connection.py @@ -0,0 +1,148 @@ +#!/usr/bin/python2.7 +# -*- coding: utf-8 -*- +# +# Univention Common Python Library +# Connections to remote UMC Servers +# +# Copyright 2013-2016 Univention GmbH +# +# http://www.univention.de/ +# +# All rights reserved. +# +# The source code of this program is made available +# under the terms of the GNU Affero General Public License version 3 +# (GNU AGPL V3) as published by the Free Software Foundation. +# +# Binary versions of this program provided by Univention to you as +# well as other copyrighted, protected or trademarked materials like +# Logos, graphics, fonts, specific documentations and configurations, +# cryptographic keys etc. are subject to a license agreement between +# you and Univention and not subject to the GNU AGPL V3. +# +# In the case you use this program under the terms of the GNU AGPL V3, +# the program is provided in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License with the Debian GNU/Linux or Univention distribution in file +# /usr/share/common-licenses/AGPL-3; if not, see +# . + +from httplib import HTTPSConnection, HTTPException +from json import loads, dumps +from socket import error as SocketError + +from univention.config_registry import ConfigRegistry +ucr = ConfigRegistry() +ucr.load() + + +class UMCConnection(object): + + def __init__(self, host, username=None, password=None, error_handler=None): + self._host = host + self._headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Accept': 'application/json; q=1, text/html; q=0.5; */*; q=0.1', + 'X-Requested-With': 'XMLHttpRequest', + } + self._error_handler=error_handler + if username is not None: + self.auth(username, password) + + def get_connection(self): + '''Creates a new HTTPSConnection to the host''' + # once keep-alive is over, the socket closes + # so create a new connection on every request + return HTTPSConnection(self._host) + + @classmethod + def get_machine_connection(cls, error_handler=None): + '''Creates a connection with the credentials of the local host + to the DC Master''' + username = '%s$' % ucr.get('hostname') + password = '' + try: + with open('/etc/machine.secret') as machine_file: + password = machine_file.readline().strip() + except (OSError, IOError) as e: + if error_handler: + error_handler('Could not read /etc/machine.secret: %s' % e) + try: + connection = cls(ucr.get('ldap/master')) + connection.auth(username, password) + return connection + except (HTTPException, SocketError) as e: + if error_handler: + error_handler('Could not connect to UMC on %s: %s' % (ucr.get('ldap/master'), e)) + return None + + def auth(self, username, password, auth_type=None): + '''Tries to authenticate against the host and preserves the + cookie. Has to be done only once (but keep in mind that the + session probably expires after 10 minutes of inactivity)''' + data = self.build_data({'username' : username, 'password' : password, 'auth_type': auth_type}) + con = self.get_connection() + try: + con.request('POST', '/umcp/auth', data, headers=self._headers) + except Exception as e: + # probably unreachable + if self._error_handler: + self._error_handler(str(e)) + error_message = '%s: Authentication failed while contacting: %s' % (self._host, e) + raise HTTPException(error_message) + else: + try: + response = con.getresponse() + cookie = response.getheader('set-cookie') + if cookie is None: + raise ValueError('No cookie') + self._headers['Cookie'] = cookie # FIXME: transform Set-Cookie to Cookie + except Exception as e: + if self._error_handler: + self._error_handler(str(e)) + error_message = '%s: Authentication failed: %s' % (self._host, response.read()) + raise HTTPException(error_message) + + def build_data(self, data, flavor=None): + '''Returns a dictionary as expected by the UMC Server''' + data = {'options' : data} + if flavor: + data['flavor'] = flavor + return dumps(data) + + def request(self, url, data=None, flavor=None, command='command'): + '''Sends a request and returns the data from the response. url + as in the XML file of that UMC module. + command may be anything that UMCP understands, especially: + * command (default) + * get (and url could be 'ucr' then) + * set (and url would be '' and data could be {'locale':'de_DE'}) + * upload (url could be 'udm/license/import') + ''' + if data is None: + data = {} + data = self.build_data(data, flavor) + con = self.get_connection() + umcp_command = '/umcp/%s' % command + if url: + umcp_command = '%s/%s' % (umcp_command, url) + con.request('POST', umcp_command, data, headers=self._headers) + response = con.getresponse() + if response.status != 200: + error_message = '%s on %s (%s): %s' % (response.status, self._host, url, response.read()) + if response.status == 403: + # 403 is either command is unknown + # or command is known but forbidden + if self._error_handler: + self._error_handler(error_message) + raise NotImplementedError('command forbidden: %s' % url) + raise HTTPException(error_message) + content = response.read() + content = loads(content) # FIXME: inspect Content-Type response header + if isinstance(content, dict): + return content.get('result', content) + return content diff --git a/management/univention-management-console/lib/python/umc_module.py b/management/univention-management-console/lib/python/umc_module.py new file mode 100644 index 0000000..e57dd1a --- /dev/null +++ b/management/univention-management-console/lib/python/umc_module.py @@ -0,0 +1,73 @@ +import univention.admin.uexceptions +import bz2 +import zlib +from PIL import Image +import StringIO +import magic +MIME_TYPE = magic.open(magic.MAGIC_MIME_TYPE) +MIME_TYPE.load() +MIME_DESCRIPTION = magic.open(magic.MAGIC_NONE) +MIME_DESCRIPTION.load() + +UMC_ICON_BASEDIR = "/usr/share/univention-management-console-frontend/js/dijit/themes/umc/icons" + +compression_mime_type_handlers = { + "application/x-gzip": lambda x: zlib.decompress(x, 16+zlib.MAX_WBITS), + "application/x-bzip2": bz2.decompress +} + +def get_mime_type(data): + return MIME_TYPE.buffer(data) + +def get_mime_description(data): + return MIME_DESCRIPTION.buffer(data) + +def compression_mime_type_of_buffer(data): + mime_type = get_mime_type(data) + if mime_type in compression_mime_type_handlers: + return (mime_type, compression_mime_type_handlers[mime_type]) + else: + raise univention.admin.uexceptions.valueError( "Not a supported compression format: %s" % (mime_type,)) + +def uncompress_buffer(data): + try: + (mime_type, compression_mime_type_handler) = compression_mime_type_of_buffer(data) + return (mime_type, compression_mime_type_handler(data)) + except univention.admin.uexceptions.valueError: + return (None, data) + +def uncompress_file(filename): + with open(filename, 'r') as f: + return uncompress_buffer(f.read()) + +def image_mime_type_of_buffer(data): + mime_type = get_mime_type(data) + if mime_type in ('image/jpeg', 'image/png', 'image/svg+xml', 'application/x-gzip'): + return mime_type + else: + raise univention.admin.uexceptions.valueError( "Not a supported image format: %s" % (mime_type,)) + +def imagedimensions_of_buffer(data): + fp = StringIO.StringIO(data) + im=Image.open(fp) + return im.size + +def imagecategory_of_buffer(data): + (compression_mime_type, uncompressed_data) = uncompress_buffer(data) + mime_type = image_mime_type_of_buffer(uncompressed_data) + if mime_type in ('image/jpeg', 'image/png'): + return (mime_type, compression_mime_type, "%sx%s" % imagedimensions_of_buffer(uncompressed_data)) + elif mime_type in ('image/svg+xml', 'application/x-gzip'): + return (mime_type, compression_mime_type, "scalable") + +def default_filename_suffix_for_mime_type(mime_type, compression_mime_type): + if mime_type == 'image/svg+xml': + if not compression_mime_type: + return '.svg' + elif compression_mime_type == 'application/x-gzip': + return '.svgz' + elif mime_type == 'image/png': + return '.png' + elif mime_type == 'image/jpeg': + return '.jpg' + return None diff --git a/management/univention-management-console/lib/shell/umc.sh b/management/univention-management-console/lib/shell/umc.sh new file mode 100644 index 0000000..6452d31 --- /dev/null +++ b/management/univention-management-console/lib/shell/umc.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# -*- coding: utf-8 -*- +# +# Univention Lib +# shell function for creating UMC operation and acl objects +# +# Copyright 2011-2016 Univention GmbH +# +# http://www.univention.de/ +# +# All rights reserved. +# +# The source code of this program is made available +# under the terms of the GNU Affero General Public License version 3 +# (GNU AGPL V3) as published by the Free Software Foundation. +# +# Binary versions of this program provided by Univention to you as +# well as other copyrighted, protected or trademarked materials like +# Logos, graphics, fonts, specific documentations and configurations, +# cryptographic keys etc. are subject to a license agreement between +# you and Univention and not subject to the GNU AGPL V3. +# +# In the case you use this program under the terms of the GNU AGPL V3, +# the program is provided in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License with the Debian GNU/Linux or Univention distribution in file +# /usr/share/common-licenses/AGPL-3; if not, see +# . + + +eval "$(/usr/sbin/univention-config-registry shell ldap/base)" + +BIND_ARGS="$@" + +umc_frontend_new_hash () { + # create new timestamps for index.html and debug.html in order to + # avoid caching problems in browsers + timestamp=$(date +'%Y%d%m%H%M%S') + for ifile in index.html debug.html error.html js/umc/login.html; do + f="/usr/share/univention-management-console-frontend/$ifile" + [ -w "$f" ] && sed -i 's/\$\(.*\)\$/$'$timestamp'$/' "$f" + done + + # update the symlinks to the js/css directories + for idir in css js; do + rm -f "/usr/share/univention-management-console-frontend/${idir}_\$"*\$ || true + ln -s "$idir" "/usr/share/univention-management-console-frontend/${idir}_\$${timestamp}\$" || true + done + + return 0 +} + +umc_init () { + + eval "$(/usr/sbin/univention-config-registry shell groups/default/domainadmins groups/default/domainusers)" + + # containers + udm container/cn create $BIND_ARGS --ignore_exists --position "cn=univention,$ldap_base" --set name=UMC || exit $? + udm container/cn create $BIND_ARGS --ignore_exists --position "cn=policies,$ldap_base" --set name=UMC --set policyPath=1 || exit $? + udm container/cn create $BIND_ARGS --ignore_exists --position "cn=UMC,cn=univention,$ldap_base" --set name=operations || exit $? + + # default admin policy + udm policies/umc create $BIND_ARGS --ignore_exists --set name=default-umc-all \ + --position "cn=UMC,cn=policies,$ldap_base" || exit $? + + # link default admin policy to the group "Domain Admins" + group_admins="${groups_default_domainadmins:-Domain Admins}" + udm groups/group modify $BIND_ARGS --ignore_exists --dn "cn=$group_admins,cn=groups,$ldap_base" \ + --policy-reference="cn=default-umc-all,cn=UMC,cn=policies,$ldap_base" || exit $? + + # default user policy + udm policies/umc create $BIND_ARGS --ignore_exists --set name=default-umc-users \ + --position "cn=UMC,cn=policies,$ldap_base" || exit $? + + # link default user policy to the group "Domain Users" + group_users="${groups_default_domainusers:-Domain Users}" + udm groups/group modify $BIND_ARGS --ignore_exists --dn "cn=$group_users,cn=groups,$ldap_base" \ + --policy-reference="cn=default-umc-users,cn=UMC,cn=policies,$ldap_base" || exit $? +} + +_umc_remove_old () { + # removes an object and ignores all errors + name=$1; shift + module=$1; shift + container=$1 + + udm $module remove $BIND_ARGS --dn "cn=$name,$container,$ldap_base" 2>/dev/null || true +} + +umc_operation_create () { + # example: umc_operation_create "udm" "UDM" "users/user" "udm/*:objectType=users/*" + name=$1; shift + description=$1; shift + flavor=$1; shift + operations="" + for oper in "$@"; do + operations="$operations --append operation=$oper " + done + udm settings/umc_operationset create $BIND_ARGS --ignore_exists \ + --position "cn=operations,cn=UMC,cn=univention,$ldap_base" \ + --set name="$name" \ + --set description="$description" \ + --set flavor="$flavor" $operations || exit $? +} + +umc_policy_append () { + # example: umc_policy_append "default-umc-all" "udm-all" "udm-users" + policy="$1"; shift + + ops="" + for op in "$@"; do + ops="$ops --append allow=cn=$op,cn=operations,cn=UMC,cn=univention,$ldap_base " + done + + udm policies/umc modify $BIND_ARGS --ignore_exists \ + --dn "cn=$policy,cn=UMC,cn=policies,$ldap_base" $ops || exit $? +}