View | Details | Raw Unified | Return to bug 41005 | Differences between
and this patch

Collapse All | Expand All

(-)a/services/univention-bind/bind.py (-10 / +31 lines)
 Lines 45-50   import time Link Here 
45
import errno
45
import errno
46
import signal
46
import signal
47
import grp
47
import grp
48
import urllib
48
49
49
name = 'bind'
50
name = 'bind'
50
description = 'Update BIND zones'
51
description = 'Update BIND zones'
 Lines 98-106   def handler(dn, new, old): Link Here 
98
			_remove_zone(old['zoneName'][0])
99
			_remove_zone(old['zoneName'][0])
99
		if new.get('zoneName'):
100
		if new.get('zoneName'):
100
			# Change
101
			# Change
101
			# Create an empty file to trigger the postrun()
102
			# Create a file to trigger the postrun()
102
			zonefile = os.path.join(PROXY_CACHE_DIR, "%s.zone" % (new['zoneName'][0],))
103
			zone = new['zoneName'][0]
104
			zonefile = sanitized_path_join(PROXY_CACHE_DIR, "%s.zone" % (zone, ))
103
			proxy_cache = open(zonefile, 'w')
105
			proxy_cache = open(zonefile, 'w')
106
			proxy_cache.write(zone)
104
			proxy_cache.close()
107
			proxy_cache.close()
105
			os.chmod(zonefile, 0o640)
108
			os.chmod(zonefile, 0o640)
106
			chgrp_bind(zonefile)
109
			chgrp_bind(zonefile)
 Lines 125-131   def _new_zone(ucr, zonename, dn): Link Here 
125
		os.mkdir(NAMED_CONF_DIR)
128
		os.mkdir(NAMED_CONF_DIR)
126
		os.chmod(NAMED_CONF_DIR, 0o755)
129
		os.chmod(NAMED_CONF_DIR, 0o755)
127
130
128
	zonefile = os.path.join(NAMED_CONF_DIR, zonename)
131
	zonefile = sanitized_path_join(NAMED_CONF_DIR, zonename)
129
132
130
	# Create empty file and restrict permission
133
	# Create empty file and restrict permission
131
	named_zone = open(zonefile, 'w')
134
	named_zone = open(zonefile, 'w')
 Lines 149-159   def _new_zone(ucr, zonename, dn): Link Here 
149
	named_zone.close()
152
	named_zone.close()
150
153
151
	# Create proxy configuration file
154
	# Create proxy configuration file
152
	proxy_file = os.path.join(NAMED_CONF_DIR, zonename + '.proxy')
155
	proxy_file = sanitized_path_join(NAMED_CONF_DIR, zonename + '.proxy')
153
	proxy_zone = open(proxy_file, 'w')
156
	proxy_zone = open(proxy_file, 'w')
154
	proxy_zone.write('zone "%s" {\n' % (zonename,))
157
	proxy_zone.write('zone "%s" {\n' % (zonename,))
155
	proxy_zone.write('\ttype slave;\n')
158
	proxy_zone.write('\ttype slave;\n')
156
	proxy_zone.write('\tfile "%s.zone";\n' % (zonename,))
159
	proxy_zone.write('\tfile "%s.zone";\n' % (sanitize_filename(zonename),))
157
	proxy_zone.write('\tmasters port 7777 { 127.0.0.1; };\n')
160
	proxy_zone.write('\tmasters port 7777 { 127.0.0.1; };\n')
158
	proxy_zone.write('};\n')
161
	proxy_zone.write('};\n')
159
	proxy_zone.close()
162
	proxy_zone.close()
 Lines 167-174   def _new_zone(ucr, zonename, dn): Link Here 
167
def _remove_zone(zonename):
170
def _remove_zone(zonename):
168
	"""Handle removal of zone."""
171
	"""Handle removal of zone."""
169
	ud.debug(ud.LISTENER, ud.INFO, 'DNS: Removing zone %s' % (zonename,))
172
	ud.debug(ud.LISTENER, ud.INFO, 'DNS: Removing zone %s' % (zonename,))
170
	zonefile = os.path.join(NAMED_CONF_DIR, zonename)
173
	zonefile = sanitized_path_join(NAMED_CONF_DIR, zonename)
171
	cached_zonefile = os.path.join(NAMED_CACHE_DIR, zonename + '.zone')
174
	cached_zonefile = sanitized_path_join(NAMED_CACHE_DIR, zonename + '.zone')
172
	# Remove zone file
175
	# Remove zone file
173
	if os.path.exists(zonefile):
176
	if os.path.exists(zonefile):
174
		os.unlink(zonefile)
177
		os.unlink(zonefile)
 Lines 318-330   def postrun(): Link Here 
318
				__zone_created_or_removed = False
321
				__zone_created_or_removed = False
319
		elif dns_backend == 'ldap':
322
		elif dns_backend == 'ldap':
320
			for filename in os.listdir(PROXY_CACHE_DIR):
323
			for filename in os.listdir(PROXY_CACHE_DIR):
321
				os.remove(os.path.join(PROXY_CACHE_DIR, filename))
324
				filepath = os.path.join(PROXY_CACHE_DIR, filename)
325
				zone = open(filepath, 'rb').read()
326
				os.remove(filepath)
322
				if not os.path.exists(os.path.join(NAMED_CACHE_DIR, filename)):
327
				if not os.path.exists(os.path.join(NAMED_CACHE_DIR, filename)):
323
					ud.debug(ud.LISTENER, ud.PROCESS, 'DNS: %s does not exist. Triggering a bind9 restart.' % (os.path.join(NAMED_CACHE_DIR, filename)))
328
					ud.debug(ud.LISTENER, ud.PROCESS, 'DNS: %s does not exist. Triggering a bind9 restart.' % (os.path.join(NAMED_CACHE_DIR, filename)))
324
					restart = True
329
					restart = True
325
				else:
330
				else:
326
					zone = filename.replace(".zone", "")
331
					_, ext = os.path.splitext(filename)
327
					zones.append(zone)
332
					if ext == '.zone':
333
						zones.append(zone)
334
					else:
335
						ud.debug(ud.LISTENER, ud.WARN, 'DNS: strange file in PROXY_CACHE_DIR: %r' % (filename, ))
328
			if zones:
336
			if zones:
329
				ud.debug(ud.LISTENER, ud.INFO, 'DNS: Zones: %s' % (zones,))
337
				ud.debug(ud.LISTENER, ud.INFO, 'DNS: Zones: %s' % (zones,))
330
		elif dns_backend == 'none':
338
		elif dns_backend == 'none':
 Lines 341-343   def postrun(): Link Here 
341
		_kill_children(pids)
349
		_kill_children(pids)
342
	finally:
350
	finally:
343
		listener.unsetuid()
351
		listener.unsetuid()
352
353
def sanitize_filename(bytestring):
354
	escaped = urllib.quote(bytestring, safe='')
355
	if escaped.startswith('.'): # always encode leading dot because '.' and '..' are special names
356
		escaped = '%20' + escaped[1:]
357
	return escaped
358
359
def sanitized_path_join(directory, unsafe_filename):
360
	filename = sanitize_filename(unsafe_filename)
361
	assert '/' not in filename
362
	assert '\0' not in filename
363
	assert filename not in ('.', '..', )
364
	return os.path.join(directory, filename)
(-)a/services/univention-bind/debian/univention-bind.postinst (+4 lines)
 Lines 82-87   if [ "$1" = "configure" ]; then Link Here 
82
		systemctl --system daemon-reload
82
		systemctl --system daemon-reload
83
	}
83
	}
84
	if [ -n "$2" ]; then
84
	if [ -n "$2" ]; then
85
		if dpkg --compare-versions "$2" lt 10.0.2-6 # update to sanitized filenames
86
		then
87
			univention-directory-listener-ctrl resync bind
88
		fi
85
		invoke-rc.d bind9 crestart
89
		invoke-rc.d bind9 crestart
86
	else
90
	else
87
		invoke-rc.d bind9 start
91
		invoke-rc.d bind9 start

Return to bug 41005