Esempio n. 1
0
def _commit_files(files, result, module):
    result['changed'] = len(files) > 0

    if not result['changed']:
        result['message'] = "No files need to be unset"

    if module.check_mode:
        if len(files) > 0:
            result['message'] = "These files will be commited: {}".format(" ".join(files))
        return

    if not result['changed']:
        return

    startd = datetime.datetime.now()

    ucr = ConfigRegistry()
    ucr.load()

    ucr_handlers = configHandlers()
    ucr_handlers.load()
    ucr_handlers.update()

    ucr_handlers.commit(ucr, files)

    endd = datetime.datetime.now()
    result['start'] = str(startd)
    result['end'] = str(endd)
    result['delta'] = str(endd - startd)
    result['meta']['commited_templates'] = files
    result['message'] = "These files were be commited: {}".format(" ".join(files))
    result['failed'] = 0
Esempio n. 2
0
# 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
# <http://www.gnu.org/licenses/>.

__package__='' 	# workaround for PEP 366
import listener
import os
import time
import univention.debug as ud
import univention.config_registry
## for the ucr commit below in postrun we need ucr configHandlers
from univention.config_registry import configHandlers
ucr_handlers = configHandlers()
ucr_handlers.load()
from univention.config_registry.interfaces import Interfaces
interfaces = Interfaces(listener.configRegistry)

hostname = listener.baseConfig['hostname']
domainname = listener.baseConfig['domainname']
ip = str(interfaces.get_default_ip_address().ip)
ldap_base = listener.baseConfig['ldap/base']

name='cups-printers'
description='Manage CUPS printer configuration'
filter='(|(objectClass=univentionPrinter)(objectClass=univentionPrinterGroup))'
attributes=['univentionPrinterSpoolHost', 'univentionPrinterModel', 'univentionPrinterURI', 'univentionPrinterLocation', 'description', 'univentionPrinterSambaName','univentionPrinterPricePerPage','univentionPrinterPricePerJob','univentionPrinterQuotaSupport','univentionPrinterGroupMember', 'univentionPrinterACLUsers', 'univentionPrinterACLGroups', 'univentionPrinterACLtype', 'univentionPrinterUseClientDriver',]

EMPTY = ('',)
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

from __future__ import absolute_import
from __future__ import print_function
import listener
import os
import univention.debug
import univention.lib.listenerSharePath
import cPickle
import urllib
# for the ucr commit below in postrun we need ucr configHandlers
from univention.config_registry import configHandlers, ConfigRegistry
from univention.config_registry.interfaces import Interfaces
ucr_handlers = configHandlers()
ucr_handlers.load()

domainname = listener.baseConfig['domainname']

name = 'samba-shares'
description = 'Create configuration for Samba shares'
filter = '(&(objectClass=univentionShare)(objectClass=univentionShareSamba))'  # filter fqdn/ip in handler
attributes = []
modrdn = '1'

tmpFile = '/var/cache/univention-directory-listener/samba-shares.oldObject'


def _validate_smb_share_name(name):
    if not name or len(name) > 80:
Esempio n. 4
0
	def handler(self, dn, new, old, name=None):
		"""Handle LDAP ACL extensions on Master, Backup and Slave"""

		if not listener.configRegistry.get('ldap/server/type'):
			return

		if not listener.configRegistry.get('server/role') in ('domaincontroller_master'):
			# new, ignore first *inactive* appearance, has to be activated on master first
			if new and not old and new.get('univentionLDAPACLActive', ['FALSE'])[0] != 'TRUE':
				ud.debug(ud.LISTENER, ud.PROCESS, '%s: ignore first appearance of %s, not yet activated' % (name, dn))
				return
			# ignore change unless (re) activated
			if new and old:
				if not new.get('univentionLDAPACLActive', ['FALSE'])[0] == 'TRUE':
					ud.debug(ud.LISTENER, ud.PROCESS, '%s: ignore modify of %s, not yet activated' % (name, dn))
					return

		# Check UCS version requirements first and skip new if they are not met.
		if new:
			univentionUCSVersionStart = new.get('univentionUCSVersionStart', [None])[0]
			univentionUCSVersionEnd = new.get('univentionUCSVersionEnd', [None])[0]
			current_UCS_version = "%s-%s" % (listener.configRegistry.get('version/version'), listener.configRegistry.get('version/patchlevel'))
			if univentionUCSVersionStart and UCS_Version(current_UCS_version) < UCS_Version(univentionUCSVersionStart):
				ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s requires at least UCR version %s.' % (name, new['cn'][0], univentionUCSVersionStart))
				new = None
			elif univentionUCSVersionEnd and UCS_Version(current_UCS_version) > UCS_Version(univentionUCSVersionEnd):
				ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s specifies compatibility only up to and including UCR version %s.' % (name, new['cn'][0], univentionUCSVersionEnd))
				new = None

		if new:
			new_version = new.get('univentionOwnedByPackageVersion', [None])[0]
			if not new_version:
				return

			new_pkgname = new.get('univentionOwnedByPackage', [None])[0]
			if not new_pkgname:
				return

			ud.debug(ud.LISTENER, ud.PROCESS, '%s: %s active? %s' % (name, dn, new.get('univentionLDAPACLActive')))

			if old:  # check for trivial changes
				diff_keys = [key for key in new.keys() if new.get(key) != old.get(key) and key not in ('entryCSN', 'modifyTimestamp', 'modifiersName')]
				if diff_keys == ['univentionLDAPACLActive'] and new.get('univentionLDAPACLActive')[0] == 'TRUE':
					# ignore status change on master, already activated
					if listener.configRegistry.get('server/role') in ('domaincontroller_master'):
						ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: activation status changed.' % (name, new['cn'][0]))
						return
				elif diff_keys == ['univentionAppIdentifier']:
					ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: App identifier changed.' % (name, new['cn'][0]))
					return
				ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: changed attributes: %s' % (name, new['cn'][0], diff_keys))

				if new_pkgname == old.get('univentionOwnedByPackage', [None])[0]:
					old_version = old.get('univentionOwnedByPackageVersion', ['0'])[0]
					rc = apt.apt_pkg.version_compare(new_version, old_version)
					if not rc > -1:
						ud.debug(ud.LISTENER, ud.WARN, '%s: New version is lower than version of old object (%s), skipping update.' % (name, old_version))
						return

			try:
				new_object_data = bz2.decompress(new.get('univentionLDAPACLData')[0])
			except TypeError:
				ud.debug(ud.LISTENER, ud.ERROR, '%s: Error uncompressing data of object %s.' % (name, dn))
				return

			new_basename = new.get('univentionLDAPACLFilename')[0]
			new_filename = os.path.join(self.ucr_slapd_conf_subfile_dir, new_basename)
			listener.setuid(0)
			try:
				backup_filename = None
				backup_ucrinfo_filename = None
				backup_backlink_filename = None
				if old:
					old_filename = os.path.join(self.ucr_slapd_conf_subfile_dir, old.get('univentionLDAPACLFilename')[0])
					if os.path.exists(old_filename):
						backup_fd, backup_filename = tempfile.mkstemp()
						ud.debug(ud.LISTENER, ud.INFO, '%s: Moving old file %s to %s.' % (name, old_filename, backup_filename))
						try:
							shutil.move(old_filename, backup_filename)
						except IOError:
							ud.debug(ud.LISTENER, ud.WARN, '%s: Error renaming old file %s, removing it.' % (name, old_filename))
							os.unlink(old_filename)
							backup_filename = None
							os.close(backup_fd)

					# plus the old backlink file
					old_backlink_filename = "%s.info" % old_filename
					if os.path.exists(old_backlink_filename):
						backup_backlink_fd, backup_backlink_filename = tempfile.mkstemp()
						ud.debug(ud.LISTENER, ud.INFO, '%s: Moving old backlink file %s to %s.' % (name, old_backlink_filename, backup_backlink_filename))
						try:
							shutil.move(old_backlink_filename, backup_backlink_filename)
						except IOError:
							ud.debug(ud.LISTENER, ud.WARN, '%s: Error renaming old backlink file %s, removing it.' % (name, old_backlink_filename))
							os.unlink(old_backlink_filename)
							backup_backlink_filename = None
							os.close(backup_backlink_fd)

					# and the old UCR registration
					old_ucrinfo_filename = os.path.join(self.ucr_info_basedir, "%s%s.info" % (self.file_prefix, old.get('univentionLDAPACLFilename')[0]))
					if os.path.exists(old_ucrinfo_filename):
						backup_ucrinfo_fd, backup_ucrinfo_filename = tempfile.mkstemp()
						ud.debug(ud.LISTENER, ud.INFO, '%s: Moving old UCR info file %s to %s.' % (name, old_ucrinfo_filename, backup_ucrinfo_filename))
						try:
							shutil.move(old_ucrinfo_filename, backup_ucrinfo_filename)
						except IOError:
							ud.debug(ud.LISTENER, ud.WARN, '%s: Error renaming old UCR info file %s, removing it.' % (name, old_ucrinfo_filename))
							os.unlink(old_ucrinfo_filename)
							backup_ucrinfo_filename = None
							os.close(backup_ucrinfo_fd)

				if not os.path.isdir(self.ucr_slapd_conf_subfile_dir):
					if os.path.exists(self.ucr_slapd_conf_subfile_dir):
						ud.debug(ud.LISTENER, ud.WARN, '%s: Directory name %s occupied, renaming blocking file.' % (name, self.ucr_slapd_conf_subfile_dir))
						shutil.move(self.ucr_slapd_conf_subfile_dir, "%s.bak" % self.ucr_slapd_conf_subfile_dir)
					ud.debug(ud.LISTENER, ud.INFO, '%s: Create directory %s.' % (name, self.ucr_slapd_conf_subfile_dir))
					os.makedirs(self.ucr_slapd_conf_subfile_dir, 0o755)

				# Create new extension file
				try:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Writing new extension file %s.' % (name, new_filename))
					with open(new_filename, 'w') as f:
						f.write(new_object_data)
				except IOError:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Error writing file %s.' % (name, new_filename))
					return

				# plus backlink file
				try:
					new_backlink_filename = "%s.info" % new_filename
					ud.debug(ud.LISTENER, ud.INFO, '%s: Writing backlink file %s.' % (name, new_backlink_filename))
					with open(new_backlink_filename, 'w') as f:
						f.write("%s\n" % dn)
				except IOError:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Error writing backlink file %s.' % (name, new_backlink_filename))
					return

				# and UCR registration
				try:
					new_ucrinfo_filename = os.path.join(self.ucr_info_basedir, "%s%s.info" % (self.file_prefix, new.get('univentionLDAPACLFilename')[0]))
					ud.debug(ud.LISTENER, ud.INFO, '%s: Writing UCR info file %s.' % (name, new_ucrinfo_filename))
					with open(new_ucrinfo_filename, 'w') as f:
						f.write("Type: multifile\nMultifile: etc/ldap/slapd.conf\n\nType: subfile\nMultifile: etc/ldap/slapd.conf\nSubfile: etc/ldap/slapd.conf.d/%s\n" % new_basename)
				except IOError:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Error writing UCR info file %s.' % (name, new_ucrinfo_filename))
					return

				# Commit to slapd.conf
				ucr = ConfigRegistry()
				ucr.load()
				ucr_handlers = configHandlers()
				ucr_handlers.load()
				ucr_handlers.update()
				ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])

				# validate
				p = subprocess.Popen(['/usr/sbin/slaptest', '-u'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
				stdout, stderr = p.communicate()
				if p.returncode != 0:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: slapd.conf validation failed:\n%s.' % (name, stdout))
					# Revert changes
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Removing new file %s.' % (name, new_filename))
					os.unlink(new_filename)
					os.unlink(new_backlink_filename)
					os.unlink(new_ucrinfo_filename)
					if backup_filename:
						ud.debug(ud.LISTENER, ud.ERROR, '%s: Restoring previous file %s.' % (name, old_filename))
						try:
							shutil.move(backup_filename, old_filename)
							os.close(backup_fd)
						except IOError:
							ud.debug(ud.LISTENER, ud.ERROR, '%s: Error reverting to old file %s.' % (name, old_filename))
					# plus backlink file
					if backup_backlink_filename:
						ud.debug(ud.LISTENER, ud.ERROR, '%s: Restoring previous backlink file %s.' % (name, old_backlink_filename))
						try:
							shutil.move(backup_backlink_filename, old_backlink_filename)
							os.close(backup_backlink_fd)
						except IOError:
							ud.debug(ud.LISTENER, ud.ERROR, '%s: Error reverting to old backlink file %s.' % (name, old_backlink_filename))
					# and the old UCR registration
					if backup_ucrinfo_filename:
						ud.debug(ud.LISTENER, ud.ERROR, '%s: Restoring previous UCR info file %s.' % (name, old_ucrinfo_filename))
						try:
							shutil.move(backup_ucrinfo_filename, old_ucrinfo_filename)
							os.close(backup_ucrinfo_fd)
						except IOError:
							ud.debug(ud.LISTENER, ud.ERROR, '%s: Error reverting to old UCR info file %s.' % (name, old_ucrinfo_filename))
					# Commit and exit
					ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])
					return
				ud.debug(ud.LISTENER, ud.INFO, '%s: validation successful.' % (name,))

				# cleanup backup
				if backup_filename:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Removing backup of old file %s.' % (name, backup_filename))
					os.unlink(backup_filename)
					os.close(backup_fd)
				# plus backlink file
				if backup_backlink_filename:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Removing backup of old backlink file %s.' % (name, backup_backlink_filename))
					os.unlink(backup_backlink_filename)
					os.close(backup_backlink_fd)
				# and the old UCR registration
				if backup_ucrinfo_filename:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Removing backup of old UCR info file %s.' % (name, backup_ucrinfo_filename))
					os.unlink(backup_ucrinfo_filename)
					os.close(backup_ucrinfo_fd)

				self._todo_list.append(dn)
				self._do_reload = True

			finally:
				listener.unsetuid()
		elif old:
			old_filename = os.path.join(self.ucr_slapd_conf_subfile_dir, old.get('univentionLDAPACLFilename')[0])
			# plus backlink file
			old_backlink_filename = "%s.info" % old_filename
			# and the old UCR registration
			old_ucrinfo_filename = os.path.join(self.ucr_info_basedir, "%s%s.info" % (self.file_prefix, old.get('univentionLDAPACLFilename')[0]))
			if os.path.exists(old_filename):
				listener.setuid(0)
				try:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Removing extension %s.' % (name, old['cn'][0]))
					if os.path.exists(old_ucrinfo_filename):
						os.unlink(old_ucrinfo_filename)
					if os.path.exists(old_backlink_filename):
						os.unlink(old_backlink_filename)
					os.unlink(old_filename)

					ucr = ConfigRegistry()
					ucr.load()
					ucr_handlers = configHandlers()
					ucr_handlers.load()
					ucr_handlers.update()
					ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])

					self._todo_list.append(dn)
					self._do_reload = True

				finally:
					listener.unsetuid()
Esempio n. 5
0
	def handler(self, dn, new, old, name=None):
		"""Handle LDAP schema extensions on Master and Backup"""
		if not listener.configRegistry.get('server/role') in ('domaincontroller_master', 'domaincontroller_backup'):
			return

		if new:
			new_version = new.get('univentionOwnedByPackageVersion', [None])[0]
			if not new_version:
				return

			new_pkgname = new.get('univentionOwnedByPackage', [None])[0]
			if not new_pkgname:
				return

			if old:  # check for trivial changes
				diff_keys = [key for key in new.keys() if new.get(key) != old.get(key) and key not in ('entryCSN', 'modifyTimestamp', 'modifiersName')]
				if diff_keys == ['univentionLDAPSchemaActive'] and new.get('univentionLDAPSchemaActive') == ['TRUE']:
					ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: activation status changed.' % (name, new['cn'][0]))
					return
				elif diff_keys == ['univentionAppIdentifier']:
					ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: App identifier changed.' % (name, new['cn'][0]))
					return
				ud.debug(ud.LISTENER, ud.INFO, '%s: extension %s: changed attributes: %s' % (name, new['cn'][0], diff_keys))

				if new_pkgname == old.get('univentionOwnedByPackage', [None])[0]:
					old_version = old.get('univentionOwnedByPackageVersion', ['0'])[0]
					rc = apt.apt_pkg.version_compare(new_version, old_version)
					if not rc > -1:
						ud.debug(ud.LISTENER, ud.WARN, '%s: New version is lower than version of old object (%s), skipping update.' % (name, old_version))
						return

			try:
				new_object_data = bz2.decompress(new.get('univentionLDAPSchemaData')[0])
			except TypeError:
				ud.debug(ud.LISTENER, ud.ERROR, '%s: Error uncompressing data of object %s.' % (name, dn))
				return

			new_filename = os.path.join(self.basedir, new.get('univentionLDAPSchemaFilename')[0])
			listener.setuid(0)
			try:
				backup_filename = None
				if old:
					old_filename = os.path.join(self.basedir, old.get('univentionLDAPSchemaFilename')[0])
					if os.path.exists(old_filename):
						backup_fd, backup_filename = tempfile.mkstemp()
						ud.debug(ud.LISTENER, ud.INFO, '%s: Moving old file %s to %s.' % (name, old_filename, backup_filename))
						try:
							shutil.move(old_filename, backup_filename)
						except IOError:
							ud.debug(ud.LISTENER, ud.WARN, '%s: Error renaming old file %s, removing it.' % (name, old_filename))
							os.unlink(old_filename)  # no choice
							backup_filename = None
							os.close(backup_fd)

				if not os.path.isdir(self.basedir):
					if os.path.exists(self.basedir):
						ud.debug(ud.LISTENER, ud.WARN, '%s: Directory name %s occupied, renaming blocking file.' % (name, self.basedir))
						shutil.move(self.basedir, "%s.bak" % self.basedir)
					ud.debug(ud.LISTENER, ud.INFO, '%s: Create directory %s.' % (name, self.basedir))
					os.makedirs(self.basedir, 0o755)

				# Create new extension file
				try:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Writing new extension file %s.' % (name, new_filename))
					with open(new_filename, 'w') as f:
						f.write(new_object_data)
				except IOError:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Error writing file %s.' % (name, new_filename))
					return

				ucr = ConfigRegistry()
				ucr.load()
				ucr_handlers = configHandlers()
				ucr_handlers.load()
				ucr_handlers.update()
				ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])

				# validate
				# Slapschema doesn't fail on schema errors, errors are printed to stdout (Bug #45571)
				p = subprocess.Popen(['/usr/sbin/slapschema', ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
				stdout, stderr = p.communicate()
				if p.returncode != 0 or stdout:
					ud.debug(ud.LISTENER, ud.ERROR, '%s: validation failed:\n%s.' % (name, stdout))
					# Revert changes
					ud.debug(ud.LISTENER, ud.ERROR, '%s: Removing new file %s.' % (name, new_filename))
					os.unlink(new_filename)
					if backup_filename:
						ud.debug(ud.LISTENER, ud.ERROR, '%s: Restoring previous file %s.' % (name, old_filename))
						try:
							shutil.move(backup_filename, old_filename)
							os.close(backup_fd)
						except IOError:
							ud.debug(ud.LISTENER, ud.ERROR, '%s: Error reverting to old file %s.' % (name, old_filename))
					# Commit and exit
					ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])
					return
				ud.debug(ud.LISTENER, ud.INFO, '%s: validation successful.' % (name,))

				# cleanup backup
				if backup_filename:
					ud.debug(ud.LISTENER, ud.INFO, '%s: Removing backup of old file %s.' % (name, backup_filename))
					os.unlink(backup_filename)
					os.close(backup_fd)

				self._todo_list.append(dn)
				self._do_reload = True

			finally:
				listener.unsetuid()
		elif old:
			old_filename = os.path.join(self.basedir, old.get('univentionLDAPSchemaFilename')[0])
			if os.path.exists(old_filename):
				listener.setuid(0)
				try:
					backup_fd, backup_filename = tempfile.mkstemp()
					ud.debug(ud.LISTENER, ud.INFO, '%s: Moving old file %s to %s.' % (name, old_filename, backup_filename))
					try:
						shutil.move(old_filename, backup_filename)
					except IOError:
						ud.debug(ud.LISTENER, ud.WARN, '%s: Error renaming old file %s, leaving it untouched.' % (name, old_filename))
						os.close(backup_fd)
						return

					ucr = ConfigRegistry()
					ucr.load()
					ucr_handlers = configHandlers()
					ucr_handlers.load()
					ucr_handlers.update()
					ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])

					# Slapschema doesn't fail on schema errors, errors are printed to stdout (Bug #45571)
					p = subprocess.Popen(['/usr/sbin/slapschema', ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
					stdout, stderr = p.communicate()
					if p.returncode != 0 or stdout:
						ud.debug(ud.LISTENER, ud.WARN, '%s: validation fails without %s:\n%s.' % (name, old_filename, stdout))
						ud.debug(ud.LISTENER, ud.WARN, '%s: Restoring %s.' % (name, old_filename))
						# Revert changes
						try:
							with open(backup_filename, 'r') as original:
								file_data = original.read()
							with open(old_filename, 'w') as target_file:
								target_file.write("### %s: Leftover of removed settings/ldapschema\n" % (datetime.datetime.now(), ) + file_data)
							os.unlink(backup_filename)
							os.close(backup_fd)
						except IOError:
							ud.debug(ud.LISTENER, ud.ERROR, '%s: Error reverting removal of %s.' % (name, old_filename))
						# Commit and exit
						ucr_handlers.commit(ucr, ['/etc/ldap/slapd.conf'])
						return

					ud.debug(ud.LISTENER, ud.INFO, '%s: validation successful, removing backup of old file %s.' % (name, backup_filename))
					os.unlink(backup_filename)
					os.close(backup_fd)

					self._todo_list.append(dn)
					self._do_reload = True

				finally:
					listener.unsetuid()
		return