|
31 |
# /usr/share/common-licenses/AGPL-3; if not, see |
31 |
# /usr/share/common-licenses/AGPL-3; if not, see |
32 |
# <http://www.gnu.org/licenses/>. |
32 |
# <http://www.gnu.org/licenses/>. |
33 |
|
33 |
|
|
|
34 |
from __future__ import absolute_import |
34 |
import ldap, string |
35 |
import ldap, string |
35 |
from ldap.filter import escape_filter_chars, filter_format |
36 |
from ldap.filter import escape_filter_chars, filter_format |
36 |
import univention.debug2 as ud |
37 |
import univention.debug2 as ud |
|
46 |
import time |
47 |
import time |
47 |
import sys |
48 |
import sys |
48 |
|
49 |
|
|
|
50 |
from dns.rdtypes.ANY.TXT import TXT |
51 |
from dns import rdatatype |
52 |
from dns import rdataclass |
53 |
from dns.tokenizer import Tokenizer |
54 |
|
49 |
from samba.provision.sambadns import ARecord |
55 |
from samba.provision.sambadns import ARecord |
50 |
# def __init__(self, ip_addr, serial=1, ttl=3600): |
56 |
# def __init__(self, ip_addr, serial=1, ttl=3600): |
51 |
|
57 |
|
|
86 |
self.data.wPriority=priority |
92 |
self.data.wPriority=priority |
87 |
self.data.nameTarget=name |
93 |
self.data.nameTarget=name |
88 |
|
94 |
|
|
|
95 |
class TXTRecord(dnsp.DnssrvRpcRecord): |
96 |
def __init__(self, slist, priority=0, serial=1, ttl=3600): |
97 |
super(TXTRecord, self).__init__() |
98 |
self.wType=dnsp.DNS_TYPE_TXT |
99 |
self.dwSerial=serial |
100 |
self.dwTtlSeconds=ttl |
101 |
stringlist = dnsp.string_list() |
102 |
stringlist.count = len(slist) |
103 |
stringlist.str = slist |
104 |
self.data = stringlist |
105 |
|
89 |
import univention.admin.handlers |
106 |
import univention.admin.handlers |
90 |
import univention.admin.handlers.dns.forward_zone |
107 |
import univention.admin.handlers.dns.forward_zone |
91 |
import univention.admin.handlers.dns.alias |
108 |
import univention.admin.handlers.dns.alias |
|
571 |
mx.append( [str(ndrRecord.data.wPriority), __append_dot(ndrRecord.data.nameTarget)] ) |
588 |
mx.append( [str(ndrRecord.data.wPriority), __append_dot(ndrRecord.data.nameTarget)] ) |
572 |
return mx |
589 |
return mx |
573 |
|
590 |
|
|
|
591 |
def __pack_txtRecord(object, dnsRecords): |
592 |
slist=[] |
593 |
for txtRecord in object['attributes'].get('tXTRecord', []): |
594 |
if txtRecord: |
595 |
ud.debug(ud.LDAP, ud.INFO, '__pack_txtRecord: %s' % txtRecord) |
596 |
txtRecord=univention.s4connector.s4.compatible_modstring(txtRecord) |
597 |
token_list = TXT.from_text(rdataclass.IN, rdatatype.TXT, Tokenizer(txtRecord)).strings |
598 |
ndr_txt_record = ndr_pack(TXTRecord(token_list)) |
599 |
dnsRecords.append(ndr_txt_record) |
600 |
ud.debug(ud.LDAP, ud.INFO, '__pack_txtRecord: %s' % ndr_txt_record) |
601 |
|
602 |
def __unpack_txtRecord(object): |
603 |
txt=[] |
604 |
dnsRecords=object['attributes'].get('dnsRecord', []) |
605 |
for dnsRecord in dnsRecords: |
606 |
dnsRecord=dnsRecord.encode('latin1') |
607 |
ndrRecord=ndr_unpack(dnsp.DnssrvRpcRecord, dnsRecord) |
608 |
if ndrRecord.wType == dnsp.DNS_TYPE_TXT: |
609 |
txt.append(str(TXT(rdataclass.IN, rdatatype.TXT, ndrRecord.data.str))) |
610 |
# or: txt.append(' '.join(['"%s"' % token for token in ndrRecord.data.str])) |
611 |
return txt |
612 |
|
574 |
def __pack_cName(object, dnsRecords): |
613 |
def __pack_cName(object, dnsRecords): |
575 |
for c in object['attributes'].get('cNAMERecord', []): |
614 |
for c in object['attributes'].get('cNAMERecord', []): |
576 |
c=univention.s4connector.s4.compatible_modstring(__remove_dot(c)) |
615 |
c=univention.s4connector.s4.compatible_modstring(__remove_dot(c)) |
|
717 |
|
756 |
|
718 |
__pack_mxRecord(object, dnsRecords) |
757 |
__pack_mxRecord(object, dnsRecords) |
719 |
|
758 |
|
|
|
759 |
__pack_txtRecord(object, dnsRecords) |
760 |
|
720 |
s4connector.lo_s4.modify(soa_dn, [('dnsRecord', old_dnsRecords, dnsRecords)]) |
761 |
s4connector.lo_s4.modify(soa_dn, [('dnsRecord', old_dnsRecords, dnsRecords)]) |
721 |
|
762 |
|
722 |
return True |
763 |
return True |
|
870 |
else: |
911 |
else: |
871 |
__pack_aRecord(object, dnsRecords) |
912 |
__pack_aRecord(object, dnsRecords) |
872 |
|
913 |
|
|
|
914 |
__pack_mxRecord(object, dnsRecords) |
915 |
__pack_txtRecord(object, dnsRecords) |
916 |
|
873 |
dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords) |
917 |
dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords) |
874 |
|
918 |
|
875 |
return True |
919 |
return True |
|
973 |
newRecord['ptr_record']=ptr[0] |
1017 |
newRecord['ptr_record']=ptr[0] |
974 |
newRecord.modify() |
1018 |
newRecord.modify() |
975 |
else: |
1019 |
else: |
976 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_ptr_record_create: do not modify host record') |
1020 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_ptr_record_create: do not modify ptr record') |
977 |
else: |
1021 |
else: |
978 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1022 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
979 |
|
1023 |
|
|
1029 |
newRecord['cname']=c[0] |
1073 |
newRecord['cname']=c[0] |
1030 |
newRecord.modify() |
1074 |
newRecord.modify() |
1031 |
else: |
1075 |
else: |
1032 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_cname_create: do not modify host record') |
1076 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_cname_create: do not modify cname record') |
1033 |
else: |
1077 |
else: |
1034 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1078 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1035 |
|
1079 |
|
|
1108 |
newRecord['location']=srv |
1152 |
newRecord['location']=srv |
1109 |
newRecord.modify() |
1153 |
newRecord.modify() |
1110 |
else: |
1154 |
else: |
1111 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: do not modify host record') |
1155 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: do not modify srv record') |
1112 |
else: |
1156 |
else: |
1113 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1157 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1114 |
|
1158 |
|
|
1189 |
dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords) |
1233 |
dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords) |
1190 |
|
1234 |
|
1191 |
|
1235 |
|
|
|
1236 |
def ucs_txt_record_create(s4connector, object): |
1237 |
_d=ud.function('ucs_txt_record_create') |
1238 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_txt_record_create: object: %s' % object) |
1239 |
udm_property='txt' |
1240 |
|
1241 |
zoneName = object['attributes']['zoneName'][0] |
1242 |
relativeDomainName = object['attributes']['relativeDomainName'][0] |
1243 |
|
1244 |
# unpack the record |
1245 |
c = __unpack_txtRecord(object) |
1246 |
|
1247 |
# Does a host record for this zone already exist? |
1248 |
ol_filter = filter_format('(&(relativeDomainName=%s)(zoneName=%s))', (relativeDomainName, zoneName)) |
1249 |
searchResult=s4connector.lo.search(filter=ol_filter, unique=1) |
1250 |
if len(searchResult) > 0: |
1251 |
superordinate=s4connector_get_superordinate('dns/txt_record', s4connector.lo, searchResult[0][0]) |
1252 |
foundRecord= univention.admin.handlers.dns.txt_record.object(None, s4connector.lo, position=None, dn=searchResult[0][0], superordinate=superordinate, attributes=[], update_zone=False) |
1253 |
foundRecord.open() |
1254 |
|
1255 |
## use normalized TXT records for comparison |
1256 |
normalized_txtRecord_list = [] |
1257 |
for txtRecord in foundRecord['txt']: |
1258 |
normalized_txtRecord = str(TXT.from_text(rdataclass.IN, rdatatype.TXT, Tokenizer(txtRecord))) |
1259 |
normalized_txtRecord_list.append(normalized_txtRecord) |
1260 |
|
1261 |
if set(normalized_txtRecord_list) != set(c): |
1262 |
foundRecord[udm_property]=c |
1263 |
foundRecord.modify() |
1264 |
else: |
1265 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_txt_record_create: do not modify txt record') |
1266 |
else: |
1267 |
zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn) |
1268 |
|
1269 |
superordinate=s4connector_get_superordinate('dns/txt_record', s4connector.lo, zoneDN) |
1270 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_txt_record_create: superordinate: %s' % superordinate) |
1271 |
|
1272 |
position=univention.admin.uldap.position(zoneDN) |
1273 |
|
1274 |
newRecord= univention.admin.handlers.dns.txt_record.object(None, s4connector.lo, position, dn=None, superordinate=superordinate, attributes=[], update_zone=False) |
1275 |
newRecord.open() |
1276 |
newRecord['name']=relativeDomainName |
1277 |
newRecord[udm_property]=c |
1278 |
newRecord.create() |
1279 |
|
1280 |
|
1281 |
def ucs_txt_record_delete(s4connector, object): |
1282 |
_d=ud.function('ucs_txt_record_delete') |
1283 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_txt_record_delete: object: %s' % object) |
1284 |
|
1285 |
zoneName = object['attributes']['zoneName'][0] |
1286 |
relativeDomainName = object['attributes']['relativeDomainName'][0] |
1287 |
|
1288 |
ol_filter = filter_format('(&(relativeDomainName=%s)(zoneName=%s))', (relativeDomainName, zoneName)) |
1289 |
searchResult=s4connector.lo.search(filter=ol_filter, unique=1) |
1290 |
if len(searchResult) > 0: |
1291 |
superordinate=s4connector_get_superordinate('dns/txt_record', s4connector.lo, searchResult[0][0]) |
1292 |
newRecord= univention.admin.handlers.dns.txt_record.object(None, s4connector.lo, position=None, dn=searchResult[0][0], superordinate=superordinate, attributes=[], update_zone=False) |
1293 |
newRecord.open() |
1294 |
newRecord.delete() |
1295 |
else: |
1296 |
ud.debug(ud.LDAP, ud.INFO, 'ucs_txt_record_delete: Object was not found, filter was: %s' % ol_filter) |
1297 |
|
1298 |
return True |
1299 |
|
1300 |
def s4_txt_record_create(s4connector, object): |
1301 |
_d=ud.function('s4_txt_record_create') |
1302 |
|
1303 |
dnsRecords=[] |
1304 |
|
1305 |
__pack_txtRecord(object, dnsRecords) |
1306 |
|
1307 |
dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords) |
1308 |
|
1192 |
def ucs_zone_create(s4connector, object, dns_type): |
1309 |
def ucs_zone_create(s4connector, object, dns_type): |
1193 |
_d=ud.function('ucs_zone_create') |
1310 |
_d=ud.function('ucs_zone_create') |
1194 |
|
1311 |
|
|
1328 |
return 'srv_record' |
1445 |
return 'srv_record' |
1329 |
if univention.admin.handlers.dns.ptr_record.identify(object['dn'], object['attributes']): |
1446 |
if univention.admin.handlers.dns.ptr_record.identify(object['dn'], object['attributes']): |
1330 |
return 'ptr_record' |
1447 |
return 'ptr_record' |
|
|
1448 |
if univention.admin.handlers.dns.txt_record.identify(object['dn'], object['attributes']): |
1449 |
return 'txt_record' |
1331 |
return None |
1450 |
return None |
1332 |
|
1451 |
|
1333 |
def _identify_dns_con_object(s4connector, object): |
1452 |
def _identify_dns_con_object(s4connector, object): |
|
1374 |
return 'srv_record' |
1493 |
return 'srv_record' |
1375 |
elif set((dnsp.DNS_TYPE_A, dnsp.DNS_TYPE_AAAA)) & dns_types: |
1494 |
elif set((dnsp.DNS_TYPE_A, dnsp.DNS_TYPE_AAAA)) & dns_types: |
1376 |
return 'host_record' |
1495 |
return 'host_record' |
|
|
1496 |
elif dnsp.DNS_TYPE_TXT in dns_types: |
1497 |
return 'txt_record' |
1377 |
|
1498 |
|
1378 |
return None |
1499 |
return None |
1379 |
|
1500 |
|
|
1436 |
s4_dns_node_base_delete(s4connector, object) |
1557 |
s4_dns_node_base_delete(s4connector, object) |
1437 |
# ignore move |
1558 |
# ignore move |
1438 |
|
1559 |
|
|
|
1560 |
elif dns_type == 'txt_record': |
1561 |
if object['modtype'] in ['add', 'modify']: |
1562 |
s4_txt_record_create(s4connector, object) |
1563 |
elif object['modtype'] in ['delete']: |
1564 |
s4_dns_node_base_delete(s4connector, object) |
1565 |
# ignore move |
1566 |
|
1439 |
return True |
1567 |
return True |
1440 |
|
1568 |
|
1441 |
def con2ucs (s4connector, key, object): |
1569 |
def con2ucs (s4connector, key, object): |
|
1486 |
elif object['modtype'] in ['delete']: |
1614 |
elif object['modtype'] in ['delete']: |
1487 |
ucs_srv_record_delete(s4connector, object) |
1615 |
ucs_srv_record_delete(s4connector, object) |
1488 |
# ignore move |
1616 |
# ignore move |
|
|
1617 |
elif dns_type == 'txt_record': |
1618 |
if object['modtype'] in ['add', 'modify']: |
1619 |
ucs_txt_record_create(s4connector, object) |
1620 |
elif object['modtype'] in ['delete']: |
1621 |
ucs_txt_record_delete(s4connector, object) |
1622 |
# ignore move |
1489 |
if dns_type in ['forward_zone', 'reverse_zone']: |
1623 |
if dns_type in ['forward_zone', 'reverse_zone']: |
1490 |
if object['modtype'] in ['add', 'modify']: |
1624 |
if object['modtype'] in ['add', 'modify']: |
1491 |
ucs_zone_create(s4connector, object, dns_type) |
1625 |
ucs_zone_create(s4connector, object, dns_type) |
|
1509 |
univention.admin.handlers.dns.alias.identify(dn, attr) or\ |
1643 |
univention.admin.handlers.dns.alias.identify(dn, attr) or\ |
1510 |
univention.admin.handlers.dns.host_record.identify(dn, attr) or\ |
1644 |
univention.admin.handlers.dns.host_record.identify(dn, attr) or\ |
1511 |
univention.admin.handlers.dns.srv_record.identify(dn, attr) or\ |
1645 |
univention.admin.handlers.dns.srv_record.identify(dn, attr) or\ |
1512 |
univention.admin.handlers.dns.ptr_record.identify(dn, attr) |
1646 |
univention.admin.handlers.dns.ptr_record.identify(dn, attr) or\ |
|
|
1647 |
univention.admin.handlers.dns.txt_record.identify(dn, attr) |
1513 |
|
1648 |
|
1514 |
''' |
1649 |
''' |
1515 |
Because the dns/dns.py identify function has been overwritten |
1650 |
Because the dns/dns.py identify function has been overwritten |