|
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) |
|
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': |
|
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) |