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