Univention Bugzilla – Attachment 2016 Details for
Bug 15687
UDM - IPv6 im Backend
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch: univention-directory-manager-modules 5.1.13 für univention-directory-manager-modules 5.0.45 aus trunk
univention-directory-manager-modules-5.1.13.patch (text/plain), 54.21 KB, created by
Kai Bolte
on 2009-11-13 14:25 CET
(
hide
)
Description:
Patch: univention-directory-manager-modules 5.1.13 für univention-directory-manager-modules 5.0.45 aus trunk
Filename:
MIME Type:
Creator:
Kai Bolte
Created:
2009-11-13 14:25 CET
Size:
54.21 KB
patch
obsolete
>Index: debian/changelog >=================================================================== >--- debian/changelog (Revision 13639) >+++ debian/changelog (Arbeitskopie) >@@ -1,3 +1,105 @@ >+univention-directory-manager-modules (5.1.13-1) unstable; urgency=low >+ >+ * merged with trunk v5.0.45-1 (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Fri, 13 Nov 2009 13:49:52 +0100 >+ >+univention-directory-manager-modules (5.1.12-2) unstable; urgency=low >+ >+ * udm now stores IPv6 addresses as aAAARecord for forward zones in LDAP >+ (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Fri, 13 Nov 2009 12:27:41 +0100 >+ >+univention-directory-manager-modules (5.1.12-1) unstable; urgency=low >+ >+ * merged with trunk (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Wed, 4 Nov 2009 14:04:51 +0100 >+ >+univention-directory-manager-modules (5.1.11-1) unstable; urgency=low >+ >+ * make DNS filters IPv6-capable (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Wed, 4 Nov 2009 11:48:49 +0100 >+ >+univention-directory-manager-modules (5.1.10-1) unstable; urgency=low >+ >+ * small bugfixes in syntax check (Bug #15555) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Tue, 13 Oct 2009 09:39:47 +0200 >+ >+univention-directory-manager-modules (5.1.9-1) unstable; urgency=low >+ >+ * use ipaddr module for syntax check (Bug #15555) >+ * fixed typos >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Mon, 12 Oct 2009 14:08:31 +0200 >+ >+univention-directory-manager-modules (5.1.8-1) unstable; urgency=low >+ >+ * German translations update in syntax (Bug #15555) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Fri, 9 Oct 2009 12:22:16 +0200 >+ >+univention-directory-manager-modules (5.1.7-1) unstable; urgency=low >+ >+ * IPv6 forward and reverse zones are now correctly stored in ldap (Bug #15687) >+ * fixes in DNS syntax check and add another IPv6 syntax check >+ * first version which uses new ipaddr module >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Thu, 8 Oct 2009 11:51:26 +0200 >+ >+univention-directory-manager-modules (5.1.6-1) unstable; urgency=low >+ >+ * add IPv6 to 'ipAdress' syntax check >+ * bugfixes in IPv6 DNS-handling (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Mon, 28 Sep 2009 14:42:14 +0200 >+ >+univention-directory-manager-modules (5.1.5-1) unstable; urgency=low >+ >+ * add IPv6 syntax check for DNS and some comments (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Tue, 22 Sep 2009 09:19:30 +0200 >+ >+univention-directory-manager-modules (5.1.4-1) unstable; urgency=low >+ >+ * alias, forward_zone and ptr_record are now IPv6-ready ( Bug #15687) >+ * bugfixes in reverse_zone and host_record >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Mon, 21 Sep 2009 14:09:35 +0200 >+ >+univention-directory-manager-modules (5.1.3-1) unstable; urgency=low >+ >+ * udm reverse_zone is now IPv6-ready (Bug #15687) >+ * add syntax-checking for IPv6-subnets >+ * nicer code in dns/host_record >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Fri, 18 Sep 2009 13:26:19 +0200 >+ >+univention-directory-manager-modules (5.1.2-1) unstable; urgency=low >+ >+ * removed aaaa in UDM (Bug #15687) >+ * udm dns/host_record create and modify now handles aRecord and aAAARecord >+ attributes in ldap depending on IP address version >+ * udm dns/host_record modify ... --append and --remove checks also IP address >+ version, --set replaces all old entries >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Mon, 14 Sep 2009 15:54:16 +0200 >+ >+univention-directory-manager-modules (5.1.1-1) unstable; urgency=low >+ >+ * add possibility to create AAAA records with UDM: --set aaaa="IPv6-address" (Bug #15687) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Fri, 4 Sep 2009 17:32:34 +0200 >+ >+univention-directory-manager-modules (5.1.0-1) unstable; urgency=low >+ >+ * add possibility to add IPv6 addresses and check syntax for IPv4 / IPv6 in module computers (Bug #15555) >+ >+ -- Kai-Wilhelm Bolte <bolte@univention.de> Wed, 2 Sep 2009 11:56:53 +0200 >+ > univention-directory-manager-modules (5.0.45-1) unstable; urgency=low > > * fix some more policy translation bugs (Bug: #14815) >Index: modules/univention/admin/handlers/dns/alias.py >=================================================================== >--- modules/univention/admin/handlers/dns/alias.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/alias.py (Arbeitskopie) >@@ -143,12 +143,19 @@ > > def lookup(co, lo, filter_s, base='', superordinate=None, scope="sub", unique=0, required=0, timeout=-1, sizelimit=0): > >- filter=univention.admin.filter.conjunction('&', [ >+ filter=univention.admin.filter.conjunction('|', [ >+ univention.admin.filter.conjunction('&', [ > univention.admin.filter.expression('objectClass', 'dNSZone'), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('ARecord', '*')]), >- univention.admin.filter.expression('CNAMERecord', '*') >+ univention.admin.filter.expression('CNAMERecord', '*')]), >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.ip6.arpa')]), # IPv6 >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('AAAARecord', '*')]), >+ univention.admin.filter.expression('CNAMERecord', '*')]) > ]) > > if superordinate: >@@ -165,12 +172,12 @@ > return res > > def identify(dn, attr, canonical=0): >- >+ # IPv4 + IPv6 > return 'dNSZone' in attr.get('objectClass', []) and\ > '@' not in attr.get('relativeDomainName', []) and\ >- not attr['zoneName'][0].endswith('.in-addr.arpa') and\ >+ not attr['zoneName'][0].endswith('.arpa') and\ > '*' in attr.get('CNAMERecord', []) and\ >- not '*' in attr.get('ARecord', []) >+ not ('*' in attr.get('ARecord', []) or '*' in attr.get('AAAARecord', [])) > > def lookup_alias_filter(lo, filter_s): > _re=re.compile('(.*)\(dnsAlias=([^=,]+)\)(.*)') >Index: modules/univention/admin/handlers/dns/forward_zone.py >=================================================================== >--- modules/univention/admin/handlers/dns/forward_zone.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/forward_zone.py (Arbeitskopie) >@@ -265,7 +265,8 @@ > def _ldap_modlist(self): > ml=univention.admin.handlers.simpleLdap._ldap_modlist(self) > if self.hasChanged(['nameserver', 'contact', 'serial', 'refresh', 'retry', 'expire', 'ttl']): >- ipaddr = re.compile ('^([0-9]{1,3}\.){3}[0-9]{1,3}$') # matches ip addresses - they shouldn't end with a dot! >+ # match IPv4 OR IPv6 address (incl. IPv4-mapped IPv6), they shouldn't end with a dot >+ ipaddr = re.compile ('^((0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})(\.(0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})){3})|((?!.*?::.*?::)[0-9a-fA-F]{0,4}(?:(?:(?<!::):|(?<=::))[0-9a-fA-F]{0,4}){5}(?:(?:(?<!::):|(?<=::))(?:[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2}0)(?:\.(?:[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2}|0)){3}|(?:(?:(?<!::):|(?<=::))[0-9a-fA-F]{0,4}){2}))$') > if len (self['nameserver'][0]) > 0 \ > and ipaddr.match (self['nameserver'][0]) == None \ > and self['nameserver'][0].find (':') == -1 \ >@@ -283,10 +284,15 @@ > > def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=0, required=0, timeout=-1, sizelimit=0): > >- filter=univention.admin.filter.conjunction('&', [ >+ filter=univention.admin.filter.conjunction('|', [ >+ univention.admin.filter.conjunction('&', [ > univention.admin.filter.expression('objectClass', 'dNSZone'), > univention.admin.filter.expression('relativeDomainName', '@'), >- univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]) >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.in-addr.arpa')])]), >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.expression('relativeDomainName', '@'), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.ip6.arpa')])]) # IPv6 > ]) > > if filter_s: >@@ -304,4 +310,4 @@ > > return 'dNSZone' in attr.get('objectClass', []) and\ > ['@'] == attr.get('relativeDomainName', []) and\ >- not attr['zoneName'][0].endswith('.in-addr.arpa') >+ not attr['zoneName'][0].endswith('.arpa') # IPv6 + IPv4 >Index: modules/univention/admin/handlers/dns/ptr_record.py >=================================================================== >--- modules/univention/admin/handlers/dns/ptr_record.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/ptr_record.py (Arbeitskopie) >@@ -123,10 +123,15 @@ > > def lookup(co, lo, filter_s, base='', superordinate=None,scope="sub", unique=0, required=0, timeout=-1, sizelimit=0): > >- filter=univention.admin.filter.conjunction('&', [ >+ filter=univention.admin.filter.conjunction('|', [ >+ univention.admin.filter.conjunction('&', [ > univention.admin.filter.expression('objectClass', 'dNSZone'), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), >- univention.admin.filter.expression('zoneName', '*.in-addr.arpa') >+ univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]), >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), >+ univention.admin.filter.expression('zoneName', '*.ip6.arpa')]) # IPv6 > ]) > > if superordinate: >@@ -146,4 +151,4 @@ > > return 'dNSZone' in attr.get('objectClass', []) and\ > '@' not in attr.get('relativeDomainName', []) and\ >- attr['zoneName'][0].endswith('.in-addr.arpa') >+ attr['zoneName'][0].endswith('.arpa') # IPv4 + IPv6 >Index: modules/univention/admin/handlers/dns/reverse_zone.py >=================================================================== >--- modules/univention/admin/handlers/dns/reverse_zone.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/reverse_zone.py (Arbeitskopie) >@@ -174,18 +174,38 @@ > ] > > def mapSubnet(subnet): >- q=subnet.split('.') >- q.reverse() >- return string.join(q, '.')+'.in-addr.arpa' >- >+ v=[] >+ if ':' in subnet: # IPv6 >+ q=subnet.split(':') >+ for t in q: >+ u=t.zfill(4) >+ v.append((u)) >+ [v.append('0000') for x in v if len(v) < 4] >+ v=list(''.join(v)) >+ v.reverse() >+ return string.join(v, '.')+'.ip6.arpa' >+ else: >+ q=subnet.split('.') >+ q.reverse() >+ return string.join(q, '.')+'.in-addr.arpa' >+ > def unmapSubnet(zone): > if type(zone) == types.ListType: > zone=zone[0] >- zone=zone.replace('.in-addr.arpa', '') >- q=zone.split('.') >- q.reverse() >- return string.join(q, '.') > >+ if zone.find('ip6')!=-1: # IPv6 >+ zone=zone.replace('.ip6.arpa', '') >+ q=zone.split('.') >+ q.reverse() >+ q=[''.join(q[0:4]),''.join(q[4:8]),''.join(q[8:12]),''.join(q[12:16])] >+ return string.join(q, ':') >+ >+ else: >+ zone=zone.replace('.in-addr.arpa', '') >+ q=zone.split('.') >+ q.reverse() >+ return string.join(q, '.') >+ > mapping=univention.admin.mapping.mapping() > mapping.register('subnet', 'zoneName', mapSubnet, unmapSubnet) > mapping.register('zonettl','dNSTTL', None, univention.admin.mapping.ListToString) >@@ -263,11 +283,16 @@ > > def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=0, required=0, timeout=-1, sizelimit=0): > >- filter=univention.admin.filter.conjunction('&', [ >- univention.admin.filter.expression('objectClass', 'dNSZone'), >- univention.admin.filter.expression('relativeDomainName', '@'), >- univention.admin.filter.expression('zoneName', '*.in-addr.arpa') >- ]) >+ filter=univention.admin.filter.conjunction('|', [ >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.expression('relativeDomainName', '@'), >+ univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]), >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.expression('relativeDomainName', '@'), >+ univention.admin.filter.expression('zoneName', '*.ip6.arpa')]) # IPv6 >+ ]) > > if filter_s: > filter_p=univention.admin.filter.parse(filter_s) >@@ -283,7 +308,7 @@ > > return 'dNSZone' in attr.get('objectClass', []) and\ > ['@'] == attr.get('relativeDomainName', []) and\ >- attr['zoneName'][0].endswith('.in-addr.arpa') >+ attr['zoneName'][0].endswith('.arpa') # IPv4 + IPv6 > > def quickDescription(rdn): > >Index: modules/univention/admin/handlers/dns/srv_record.py >=================================================================== >--- modules/univention/admin/handlers/dns/srv_record.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/srv_record.py (Arbeitskopie) >@@ -163,9 +163,9 @@ > filter=univention.admin.filter.conjunction('&', [ > univention.admin.filter.expression('objectClass', 'dNSZone'), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), >- univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.arpa')]), > univention.admin.filter.expression('sRVRecord', '*'), >- ]) >+ ]) # IPv4 + IPv6 > > if superordinate: > filter.expressions.append(univention.admin.filter.expression('zoneName', superordinate.mapping.mapValue('zone', superordinate['zone']))) >@@ -184,4 +184,4 @@ > > return 'dNSZone' in attr.get('objectClass', []) and\ > '@' not in attr.get('relativeDomainName', []) and\ >- not attr['zoneName'][0].endswith('.in-addr.arpa') >+ not attr['zoneName'][0].endswith('.arpa') # IPv4 + IPv6 >Index: modules/univention/admin/handlers/dns/host_record.py >=================================================================== >--- modules/univention/admin/handlers/dns/host_record.py (Revision 13639) >+++ modules/univention/admin/handlers/dns/host_record.py (Arbeitskopie) >@@ -129,7 +129,6 @@ > > mapping=univention.admin.mapping.mapping() > mapping.register('name', 'relativeDomainName', None, univention.admin.mapping.ListToString) >-mapping.register('a', 'aRecord') > mapping.register('mx', 'mXRecord', mapMX, unmapMX) > mapping.register('txt', 'tXTRecord') > mapping.register('zonettl', 'dNSTTL', None, univention.admin.mapping.ListToString) >@@ -158,6 +157,15 @@ > > univention.admin.handlers.simpleLdap.__init__(self, co, lo, position, dn, superordinate) > >+ def open(self): # IPv6 >+ univention.admin.handlers.simpleLdap.open(self) >+ self.info['a']=[] >+ if self.oldattr.has_key('aRecord'): >+ self.info['a'].extend((self.oldattr.get('aRecord'))) >+ if self.oldattr.has_key('aAAARecord'): >+ self.info['a'].extend((self.oldattr.get('aAAARecord'))) >+ self.save() # safe current state as old state >+ > def exists(self): > return self._exists > >@@ -170,6 +178,34 @@ > (self.superordinate.mapping.mapName('zone'), self.superordinate.mapping.mapValue('zone', self.superordinate['zone'])), > ] > >+ def _ldap_modlist(self): # IPv6 >+ ml=univention.admin.handlers.simpleLdap._ldap_modlist(self) >+ old = self.oldinfo.get('a') >+ new = self.info.get('a') >+ ao=[] >+ an=[] >+ aaaao=[] >+ aaaan=[] >+ >+ if old != new: >+ if old: >+ for addr in old: >+ if ':' in addr: # IPv6 >+ aaaao.append((addr)) >+ else: >+ ao.append((addr)) >+ i=i+1 >+ if new: >+ for addr in new: >+ if ':' in addr: # IPv6 >+ aaaan.append((addr)) >+ else: >+ an.append((addr)) >+ ml.append(('aRecord', ao, an)) >+ ml.append(('aAAARecord', aaaao, aaaan)) >+ #print 'DEBUG: ml: "%s" ' %ml >+ return ml >+ > def _ldap_post_create(self): > self._updateZone() > >@@ -182,13 +218,20 @@ > > def lookup(co, lo, filter_s, base='', superordinate=None,scope="sub", unique=0, required=0, timeout=-1, sizelimit=0): > >- filter=univention.admin.filter.conjunction('&', [ >+ filter=univention.admin.filter.conjunction('|', [ >+ univention.admin.filter.conjunction('&', [ > univention.admin.filter.expression('objectClass', 'dNSZone'), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.in-addr.arpa')]), > univention.admin.filter.conjunction('!', [univention.admin.filter.expression('CNAMERecord', '*')]), >- univention.admin.filter.conjunction('!', [univention.admin.filter.expression('SRVRecord', '*')]) >- ]) >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('SRVRecord', '*')])]), >+ univention.admin.filter.conjunction('&', [ >+ univention.admin.filter.expression('objectClass', 'dNSZone'), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('relativeDomainName', '@')]), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('zoneName', '*.ip6.arpa')]), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('CNAMERecord', '*')]), >+ univention.admin.filter.conjunction('!', [univention.admin.filter.expression('SRVRecord', '*')])]) >+ ]) # IPv6 > > if superordinate: > filter.expressions.append(univention.admin.filter.expression('zoneName', superordinate.mapping.mapValue('zone', superordinate['zone']))) >@@ -206,9 +249,11 @@ > def identify(dn, attr, canonical=0): > > univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'ALIAS(host_record) identify DN=%s'% dn) >+ # IPv4 + IPv6 > return 'dNSZone' in attr.get('objectClass', []) and\ > '@' not in attr.get('relativeDomainName', []) and\ >- not attr['zoneName'][0].endswith('.in-addr.arpa') and\ >+ not attr['zoneName'][0].endswith('.arpa') and\ > '*' not in attr.get('CNAMERecord', []) and\ > '*' not in attr.get('SRVRecord', []) and\ >- ('*' in attr.get('ARecord', []) or '*' in attr.get('MXRecord', []) ) >+ ('*' in attr.get('ARecord', []) or '*' in attr.get('AAAARecord', []) or '*' in attr.get('MXRecord', []) ) >+ >Index: modules/univention/admin/handlers/__init__.py >=================================================================== >--- modules/univention/admin/handlers/__init__.py (Revision 13639) >+++ modules/univention/admin/handlers/__init__.py (Arbeitskopie) >@@ -29,6 +29,7 @@ > # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > > import copy, types, sys, re, string, ldap >+import ipaddr # IPv6 address handling > import univention.debug > import univention.admin.filter > import univention.admin.uldap >@@ -983,13 +984,21 @@ > # HELPER > def __ip_from_ptr( self, zoneName, relativeDomainName ): > >- zoneName = zoneName.replace( '.in-addr.arpa', '' ).split( '.' ) >- zoneName.reverse( ) >- relativeDomainName = relativeDomainName.split( '.' ) >- relativeDomainName.reverse( ) >+ if zoneName.find('ip6')!=-1: # IPv6 >+ zoneName=zoneName.replace('.ip6.arpa', '').split( '.' ) >+ zoneName.reverse( ) >+ zoneName=(''.join(zoneName[0:4]) + ':' + ''.join(zoneName[4:8]) + ':' + ''.join(zoneName[8:12]) + ':' + ''.join(zoneName[12:16])) >+ relativeDomainName = relativeDomainName.split( '.' ) >+ relativeDomainName.reverse( ) >+ relativeDomainName=(''.join(relativeDomainName[0:4]) + ':' + ''.join(relativeDomainName[4:8]) + ':' + ''.join(relativeDomainName[8:12]) + ':' + ''.join(relativeDomainName[12:16])) >+ return '%s:%s' % ( zoneName, relativeDomainName ) >+ else: >+ zoneName = zoneName.replace( '.in-addr.arpa', '' ).split( '.' ) >+ zoneName.reverse( ) >+ relativeDomainName = relativeDomainName.split( '.' ) >+ relativeDomainName.reverse( ) >+ return '%s.%s' % ( string.join( zoneName, '.' ) , string.join( relativeDomainName, '.' ) ) > >- return '%s.%s' % ( string.join( zoneName, '.' ) , string.join( relativeDomainName, '.' ) ) >- > def __is_mac( self, mac ): > _re = re.compile( '^[ 0-9a-fA-F ][ 0-9a-fA-F ]??$' ) > m = mac.split( ':' ) >@@ -1001,12 +1010,14 @@ > return False > > def __is_ip( self, ip ): >- _re = re.compile( '^[ 0-9 ]+\.[ 0-9 ]+\.[ 0-9 ]+\.[ 0-9 ]+$' ) >- if _re.match ( ip ): >- univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'IP[%s]? -> Yes' % ip ) >- return True >- univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'IP[%s]? -> No' % ip ) >- return False >+ # return True if valid IPv4 (0.0.0.0 is allowed) or IPv6 address >+ try: >+ ipaddr.IPAddress(ip) >+ except ValueError: >+ univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'IP[%s]? -> No' % ip ) >+ return False >+ univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'IP[%s]? -> Yes' % ip ) >+ return True > > def open( self ): > simpleLdap.open( self ) >@@ -1362,16 +1373,29 @@ > univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'we should create a dns reverse object: zoneDn="%s", name="%s", ip="%s"' % ( zoneDn, name, ip ) ) > if name and zoneDn and ip: > univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'dns reverse object: start' ) >- subnet = ldap.explode_dn( zoneDn, 1 )[ 0 ].replace( '.in-addr.arpa', '' ).split( '.' ) >- subnet.reverse( ) >- subnet = string.join( subnet, '.' ) + '.' >- ipPart = ip.replace( subnet, '' ) >- if ipPart == ip: >- raise univention.admin.uexceptions.missingInformation, _( 'Reverse zone and IP address are incompatible.' ) >- >- pointer = string.split( ipPart, '.' ) >- pointer.reverse( ) >- ipPart = string.join( pointer, '.' ) >+ if ip.find(':')!=-1: # IPv6, e.g. ip=2001:db8:100::5 >+ subnet = ldap.explode_dn( zoneDn, 1 )[ 0 ].replace( '.ip6.arpa', '' ).split( '.' ) >+ subnet.reverse( ) >+ subnet=[''.join(subnet[0:4]),''.join(subnet[4:8]),''.join(subnet[8:12]),''.join(subnet[12:16])] >+ subnet = string.join( subnet, ':' ) + ':' # e.g. '2001:0db8:0100:0000:' >+ ip6=(ipaddr.IPv6Address(ip)).exploded # use Python Module ipaddr to 'explode' IPv6 address >+ ipPart = ip6.replace( subnet, '' )# e.g. '0000:0000:0000:0005' >+ if ipPart == ip: >+ raise univention.admin.uexceptions.missingInformation, _( 'Reverse zone and IP address are incompatible.' ) >+ pointer = string.split( ipPart, ':' ) >+ pointer=list(''.join(pointer)) # e.g. ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '5'] >+ pointer.reverse() >+ ipPart=string.join(pointer, '.') # e.g. '5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0' >+ else: >+ subnet = ldap.explode_dn( zoneDn, 1 )[ 0 ].replace( '.in-addr.arpa', '' ).split( '.' ) >+ subnet.reverse( ) >+ subnet = string.join( subnet, '.' ) + '.' >+ ipPart = ip.replace( subnet, '' ) >+ if ipPart == ip: >+ raise univention.admin.uexceptions.missingInformation, _( 'Reverse zone and IP address are incompatible.' ) >+ pointer = string.split( ipPart, '.' ) >+ pointer.reverse( ) >+ ipPart = string.join( pointer, '.' ) > tmppos = univention.admin.uldap.position( self.position.getDomain( ) ) > # check in which forward zone the ip is set > hostname_list = [] >@@ -1485,34 +1509,61 @@ > > def __add_dns_forward_object( self, name, zoneDn, ip ): > univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'we should add a dns forward object: zoneDn="%s", name="%s", ip="%s"' % ( zoneDn, name, ip ) ) >- if name and ip and zoneDn: >- results = self.lo.search( base = zoneDn, scope = 'domain', attr = [ 'aRecord' ], filter = '(&(relativeDomainName=%s)(!(cNAMERecord=*)))' % ( name ), unique = 0 ) >- if not results: >- try: >- self.lo.add( 'relativeDomainName=%s,%s'% ( name, zoneDn ), [\ >+ if ip.find(':')!=-1: #IPv6 >+ if name and ip and zoneDn: >+ results = self.lo.search( base = zoneDn, scope = 'domain', attr = [ 'aAAARecord' ], filter = '(&(relativeDomainName=%s)(!(cNAMERecord=*)))' % ( name ), unique = 0 ) >+ if not results: >+ try: >+ self.lo.add( 'relativeDomainName=%s,%s'% ( name, zoneDn ), [\ > ( 'objectClass', [ 'top', 'dNSZone' ]),\ > ( 'zoneName', univention.admin.uldap.explodeDn( zoneDn, 1 )[ 0 ]),\ >+ ( 'aAAARecord', [ ip ]),\ >+ ( 'relativeDomainName', [ name ])]) >+ except univention.admin.uexceptions.objectExists: >+ raise univention.admin.uexceptions.dnsAliasRecordExists >+ >+ # TODO: check if zoneDn really a forwardZone, maybe it is a container under a zone >+ zone = univention.admin.handlers.dns.forward_zone.object( self.co, self.lo, self.position, zoneDn ) >+ zone.open() >+ zone.modify() >+ else: >+ for dn, attr in results: >+ if attr.has_key( 'aAAARecord' ): >+ new_ip_list = copy.deepcopy( attr[ 'aAAARecord' ] ) >+ if not ip in new_ip_list: >+ new_ip_list.append( ip ) >+ self.lo.modify( dn, [ ( 'aAAARecord', attr[ 'aAAARecord' ], new_ip_list ) ] ) >+ else: >+ self.lo.modify( dn, [ ( 'aAAARecord', '' , ip ) ] ) >+ pass >+ else: >+ if name and ip and zoneDn: >+ results = self.lo.search( base = zoneDn, scope = 'domain', attr = [ 'aRecord' ], filter = '(&(relativeDomainName=%s)(!(cNAMERecord=*)))' % ( name ), unique = 0 ) >+ if not results: >+ try: >+ self.lo.add( 'relativeDomainName=%s,%s'% ( name, zoneDn ), [\ >+ ( 'objectClass', [ 'top', 'dNSZone' ]),\ >+ ( 'zoneName', univention.admin.uldap.explodeDn( zoneDn, 1 )[ 0 ]),\ > ( 'ARecord', [ ip ]),\ > ( 'relativeDomainName', [ name ])]) >- except univention.admin.uexceptions.objectExists: >- raise univention.admin.uexceptions.dnsAliasRecordExists >+ except univention.admin.uexceptions.objectExists: >+ raise univention.admin.uexceptions.dnsAliasRecordExists > >- # TODO: check if zoneDn really a forwardZone, maybe it is a container under a zone >- zone = univention.admin.handlers.dns.forward_zone.object( self.co, self.lo, self.position, zoneDn ) >- zone.open() >- zone.modify() >- else: >- for dn, attr in results: >- if attr.has_key( 'aRecord' ): >- new_ip_list = copy.deepcopy( attr[ 'aRecord' ] ) >- if not ip in new_ip_list: >- new_ip_list.append( ip ) >- self.lo.modify( dn, [ ( 'aRecord', attr[ 'aRecord' ], new_ip_list ) ] ) >- else: >- self.lo.modify( dn, [ ( 'aRecord', '' , ip ) ] ) >- pass >+ # TODO: check if zoneDn really a forwardZone, maybe it is a container under a zone >+ zone = univention.admin.handlers.dns.forward_zone.object( self.co, self.lo, self.position, zoneDn ) >+ zone.open() >+ zone.modify() >+ else: >+ for dn, attr in results: >+ if attr.has_key( 'aRecord' ): >+ new_ip_list = copy.deepcopy( attr[ 'aRecord' ] ) >+ if not ip in new_ip_list: >+ new_ip_list.append( ip ) >+ self.lo.modify( dn, [ ( 'aRecord', attr[ 'aRecord' ], new_ip_list ) ] ) >+ else: >+ self.lo.modify( dn, [ ( 'aRecord', '' , ip ) ] ) >+ pass > >- > def __add_dns_alias_object( self, name, dnsForwardZone, dnsAliasZoneContainer, alias ): > univention.debug.debug( univention.debug.ADMIN, univention.debug.INFO, 'add a dns alias object: name="%s", dnsForwardZone="%s", dnsAliasZoneContainer="%s", alias="%s"' % ( name, dnsForwardZone, dnsAliasZoneContainer, alias ) ) > if name and dnsForwardZone and dnsAliasZoneContainer and alias: >@@ -1814,38 +1865,75 @@ > return ml > > def calc_dns_reverse_entry_name(self, sip, reverseDN): >- subnet=ldap.explode_dn(reverseDN, 1)[0].replace('.in-addr.arpa','').split('.') >- ip=sip.split('.') >- zoneNet=subnet >- zoneNet.reverse() >- length=len(zoneNet) >- count=0 >- match=1 >- for i in zoneNet: >- if count == length: >- break >+ if sip.find(':')!=-1: # IPv6 >+ subnet=ldap.explode_dn(reverseDN, 1)[0].replace('.ip6.arpa','').split('.') >+ ip6=ipaddr.IPv6Address(sip) # use Python Module ipaddr to 'explode' IPv6 address >+ ip6=ip6.exploded >+ ip6=ip6.split(':') >+ ip6=list(''.join(ip6)) >+ zoneNet=subnet >+ zoneNet.reverse() >+ length=len(zoneNet) >+ count=0 >+ match=1 >+ for i in zoneNet: >+ if count == length: >+ break > >- if not ip[count] == i: >- match=0 >- count += 1 >+ if not ip6[count] == i: >+ match=0 >+ count += 1 > >- if match == 1: >- stop=(4-length) >- rmIP='' >- ip.reverse() >+ if match == 1: >+ stop=(32-length) >+ rmIP='' >+ ip6.reverse() >+ count=0 >+ for i in ip6: >+ if count == stop: >+ break >+ if len(rmIP) > 0: >+ rmIP=rmIP+'.'+ip6[count] >+ else: >+ rmIP=ip6[count] >+ count += 1 >+ return rmIP >+ else: >+ return 0 >+ >+ else: >+ subnet=ldap.explode_dn(reverseDN, 1)[0].replace('.in-addr.arpa','').split('.') >+ ip=sip.split('.') >+ zoneNet=subnet >+ zoneNet.reverse() >+ length=len(zoneNet) > count=0 >- for i in ip: >- if count == stop: >+ match=1 >+ for i in zoneNet: >+ if count == length: > break >- if len(rmIP) > 0: >- rmIP=rmIP+'.'+ip[count] >- else: >- rmIP=ip[count] >- count=count+1 >- return rmIP >- else: >- return 0 > >+ if not ip[count] == i: >+ match=0 >+ count += 1 >+ >+ if match == 1: >+ stop=(4-length) >+ rmIP='' >+ ip.reverse() >+ count=0 >+ for i in ip: >+ if count == stop: >+ break >+ if len(rmIP) > 0: >+ rmIP=rmIP+'.'+ip[count] >+ else: >+ rmIP=ip[count] >+ count=count+1 >+ return rmIP # for ip='10.200.2.5' and subnet='2.200.10.in-addr.arpa' -> rmIP='5' ('5.2' for 200.10.in-addr.arpa) >+ else: >+ return 0 >+ > def _ldap_pre_create(self): > self.check_common_name_length() > >Index: modules/univention/admin/de.po >=================================================================== >--- modules/univention/admin/de.po (Revision 13639) >+++ modules/univention/admin/de.po (Arbeitskopie) >@@ -6,8 +6,8 @@ > msgstr "" > "Project-Id-Version: PACKAGE VERSION\n" > "Report-Msgid-Bugs-To: \n" >-"POT-Creation-Date: 2009-08-07 14:05+0200\n" >-"PO-Revision-Date: 2009-08-07 10:29+0200\n" >+"POT-Creation-Date: 2009-11-04 13:48+0100\n" >+"PO-Revision-Date: 2009-11-04 14:01+0100\n" > "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" > "Language-Team: LANGUAGE <LL@li.org>\n" > "MIME-Version: 1.0\n" >@@ -20,23 +20,23 @@ > msgid ": type was %s" > msgstr ": Typ war %s" > >-#: modules.py:163 modules.py:346 >+#: modules.py:166 modules.py:353 > msgid "Custom" > msgstr "Benutzerdefiniert" > >-#: modules.py:832 >+#: modules.py:839 > msgid "Search" > msgstr "Suchen" > >-#: modules.py:832 >+#: modules.py:839 > msgid "Search object(s)" > msgstr "Objekt(e) suchen" > >-#: modules.py:832 >+#: modules.py:839 > msgid "Add" > msgstr "Hinzufügen" > >-#: modules.py:832 >+#: modules.py:839 > msgid "Add object(s)" > msgstr "Objekt(e) hinzufügen" > >@@ -181,80 +181,79 @@ > msgid "cannot find fqdn of " > msgstr "FQDN konnte nicht gefunden werden: " > >-#: syntax.py:104 >+#: syntax.py:105 > msgid "not enough arguments" > msgstr "Nicht genug Parameter" > >-#: syntax.py:108 >+#: syntax.py:109 > msgid "too many arguments" > msgstr "Zu viele Parameter" > >-#: syntax.py:118 >+#: syntax.py:119 > msgid "Invalid syntax" > msgstr "Falsche Syntax" > >-#: syntax.py:237 >+#: syntax.py:247 > msgid "Value must be a number!" > msgstr "Der Wert muss eine Zahl sein." > >-#: syntax.py:249 >+#: syntax.py:259 > msgid "Value must be 0 or 1" > msgstr "Der Wert muss 0 oder 1 sein." > >-#: syntax.py:261 >+#: syntax.py:271 > msgid "" > "Value must be an integer followed by one of GB,MB,KB,B or nothing (equals B)!" > msgstr "" > "Der Wert muss eine Zahl sein. Optional kann noch eine Einheit mittels GB,MB," > "KB oder B angegeben werden." > >-#: syntax.py:268 >+#: syntax.py:278 > msgid "Value may not contain whitespace or exclamation mark !" > msgstr "Der Wert darf keine Leerzeichen oder Ausrufezeichen enthalten." > >-#: syntax.py:275 >+#: syntax.py:285 > msgid "undefined" > msgstr "nicht definiert" > >-#: syntax.py:276 >+#: syntax.py:286 > msgid "mails" > msgstr "Mails" > >-#: syntax.py:277 >+#: syntax.py:287 > msgid "events" > msgstr "Kalender" > >-#: syntax.py:278 >+#: syntax.py:288 > msgid "contacts" > msgstr "Kontakte" > >-#: syntax.py:279 >+#: syntax.py:289 > msgid "tasks" > msgstr "Aufgaben" > >-#: syntax.py:280 >+#: syntax.py:290 > msgid "notes" > msgstr "Notizen" > >-#: syntax.py:281 >+#: syntax.py:291 > msgid "journals" > msgstr "Journal" > >-#: syntax.py:293 syntax.py:317 syntax.py:380 syntax.py:646 syntax.py:655 >-#: syntax.py:665 >+#: syntax.py:303 syntax.py:327 syntax.py:390 > msgid "Value may not contain other than numbers, letters and dots!" > msgstr "Der Wert darf nur Zahlen, Buchstaben und Punkte enthalten." > >-#: syntax.py:304 >+#: syntax.py:314 > msgid "Value may not contain other than numbers, letters, dots and spaces!" > msgstr "" > "Der Wert darf nur Zahlen, Buchstaben, Leerzeichen und Punkte enthalten." > >-#: syntax.py:326 >+#: syntax.py:336 > msgid "Field must only contain ASCII characters!" > msgstr "Der Wert darf nur ASCII Buchstaben enthalten!" > >-#: syntax.py:339 >+#: syntax.py:349 > msgid "" > "Value may not contain other than numbers, letters and dots, and may not be " > "admin!" >@@ -262,191 +261,194 @@ > "Der Wert darf nur Zahlen, Buchstaben und Punkte enthalten. Ausnahme ist die " > "Bezeichnug 'admin', die auch nicht verwendet werden darf" > >-#: syntax.py:351 syntax.py:368 >+#: syntax.py:361 syntax.py:378 > msgid "" > "Username must only contain numbers, letters and dots, and may not be 'admin'!" > msgstr "" > "Der Wert darf nur Zahlen, Buchstaben und Punkte enthalten. Ausnahme ist die " > "Bezeichnug 'admin', die auch nicht verwendet werden darf" > >-#: syntax.py:363 >+#: syntax.py:373 > msgid "Only the first letter of the username may be uppercase!" > msgstr "Nur der erste Buchstabe des Benutzernames darf groà geschrieben sein!" > >-#: syntax.py:388 >+#: syntax.py:398 > msgid ", a path must begin with \"/\"!" > msgstr ", eine Pfadangabe muss mit \\\"/\\\" beginnen." > >-#: syntax.py:392 >+#: syntax.py:402 > msgid "Value may not contain double quotes (\")!" > msgstr "Der Wert darf kein Anführungszeichen (\") enthalten!" > >-#: syntax.py:406 >+#: syntax.py:416 > msgid "The password is to short, at least 8 characters needed." > msgstr "Das Passwort ist zu kurz, mindestens 8 Zeichen sind erforderlich." > >-#: syntax.py:414 >+#: syntax.py:424 > msgid "Empty password not allowed!" > msgstr "Ein leeres Passwort ist nicht erlaubt!" > >-#: syntax.py:427 >+#: syntax.py:437 > msgid "Not a valid hostname!" > msgstr "Kein gültiger Hostname" > >-#: syntax.py:441 >+#: syntax.py:451 > msgid "Not a valid windows hostname!" > msgstr "Kein gültiger Windows-Hostname" > >-#: syntax.py:453 syntax.py:456 >+#: syntax.py:463 > msgid "Not a valid IP address!" > msgstr "Keine gültige IP-Adresse" > >-#: syntax.py:484 >+#: syntax.py:491 > msgid "Not a valid hostname or IP address!" > msgstr "Kein gültiger Hostname oder IP-Adresse" > >-#: syntax.py:527 >+#: syntax.py:534 > msgid "Not a valid netmask!" > msgstr "Keine gültige Netzwerkmaske." > >-#: syntax.py:531 >+#: syntax.py:538 > msgid "First Address" > msgstr "Erste Adresse" > >-#: syntax.py:531 >+#: syntax.py:538 > msgid "Last Address" > msgstr "Letzte Adresse" > >-#: syntax.py:542 >+#: syntax.py:549 > msgid "tcp" > msgstr "" > >-#: syntax.py:542 >+#: syntax.py:549 > msgid "udp" > msgstr "" > >-#: syntax.py:554 >+#: syntax.py:561 > msgid "Not an absolute path!" > msgstr "Keine absolute Pfadangabe" > >-#: syntax.py:565 syntax.py:576 >+#: syntax.py:572 syntax.py:583 > msgid "Not a valid email address!" > msgstr "Keine gültige E-Mail-Adresse" > >-#: syntax.py:588 >+#: syntax.py:595 > msgid "" > "The given date does not confirm iso8601, example: \"2009-01-01T12:00:00+01:00" > "\"." > msgstr "" > >-#: syntax.py:606 >+#: syntax.py:613 > msgid "Not a valid Date" > msgstr "Kein gültiges Datum" > >-#: syntax.py:620 >+#: syntax.py:625 > msgid "" >-"An IP subnet consists of one to three numbers ranging from 0 to 255 " >-"separated by dots." >-msgstr "" >-"Ein IP-Subnetz muss mit ein bis drei Zahlen zwischen 0 und 255 angegeben " >-"werden, die mit einem Punkt getrennt werden." >+"An IPv4 subnet consists of one to three numbers ranging from 0 to 255 " >+"separated by dots, an IPv6 subnet consists of one to four groups of one to " >+"four hexadecimal digits separated by colons (:)." >+msgstr "Ein IPv4-Subnetz muss mit ein bis drei Zahlen zwischen 0 und 255 angegeben werden, die mit einem Punkt getrennt werden, ein IPv6-Subnetz muss mit ein bis vier Gruppen aus ein bis vier hexadezimalen Zeichen angegeben werden, die mit einem Doppelpunkt getrennt werden." > >-#: syntax.py:635 >+#: syntax.py:637 > msgid "" >-"The name of a reverse zone consists of the reversed subnet address followed " >-"by .in-addr.arpa. Example: \"0.168.192.in-addr.arpa\"" >-msgstr "" >-"Der Name einer Reverse Lookup Zone besteht aus dem inversen Subnetz, gefolgt " >-"von .in-addr.arpa. z.B.: \"0.168.192.in-addr.arpa\"" >+"The name of a reverse zone for IPv4 consists of the reversed subnet address " >+"followed by .in-addr.arpa (example: \"0.168.192.in-addr.arpa\") or for IPv6 " >+"in nibble format followed by .ip6.arpa (example: \"0.0.0.0.0.0.1.0.8.b." >+"d.0.1.0.0.2.ip6.arpa\")" >+msgstr "Der Name einer IPv4 Reverse Lookup Zone besteht aus dem inversen Subnetz, gefolgt von .in-addr.arpa (z.B.: \"0.168.192.in-addr.arpa\") oder für IPv6 im Nibble Format, gefolgt von .ip6.arpa (z.B. \"0.0.0.0.0.0.1.0.8.b.d.0.1.0.0.2.ip6.arpa\")." > >-#: syntax.py:643 >+#: syntax.py:645 > msgid "Missing value!" > msgstr "Fehlender Wert!" > >-#: syntax.py:671 >+#: syntax.py:648 syntax.py:657 syntax.py:667 >+msgid "Value may not contain other than numbers, letters, dots and colons!" >+msgstr "Der Wert darf nur Zahlen, Buchstaben, Leerzeichen, Punkte und Doppelpunkte enthalten." >+ >+#: syntax.py:673 > msgid "Key" > msgstr "" > >-#: syntax.py:671 >+#: syntax.py:673 > msgid "Value" > msgstr "" > >-#: syntax.py:676 syntax.py:686 >+#: syntax.py:678 syntax.py:694 > msgid "Priority" > msgstr "Priorität" > >-#: syntax.py:676 >+#: syntax.py:678 > msgid "Mail Server" > msgstr "Mail-Server" > >-#: syntax.py:681 >+#: syntax.py:683 > msgid "Service" > msgstr "Dienst" > >-#: syntax.py:681 >+#: syntax.py:683 > msgid "Protocol" > msgstr "Protokoll" > >-#: syntax.py:686 >+#: syntax.py:689 >+msgid "Street" >+msgstr "StraÃe" >+ >+#: syntax.py:689 >+msgid "Postal code" >+msgstr "Postleitzahl" >+ >+#: syntax.py:689 >+msgid "City" >+msgstr "Stadt" >+ >+#: syntax.py:694 > msgid "Weight" > msgstr "Gewichtung" > >-#: syntax.py:686 >+#: syntax.py:694 > msgid "Port" > msgstr "Port" > >-#: syntax.py:686 >+#: syntax.py:694 > msgid "Server" > msgstr "Server" > >-#: syntax.py:696 >+#: syntax.py:704 > msgid "Not a valid time format" > msgstr "Keine gültige Zeitangabe" > >-#: syntax.py:696 >-msgid "Street" >-msgstr "StraÃe" >- >-#: syntax.py:696 >-msgid "Postal code" >-msgstr "Postleitzahl" >- >-#: syntax.py:696 >-msgid "City" >-msgstr "Stadt" >- >-#: syntax.py:709 >+#: syntax.py:717 > msgid "Not a valid time interval" > msgstr "Kein gültiges Zeitintervall" > >-#: syntax.py:715 >+#: syntax.py:723 > msgid "Ethernet" > msgstr "Ethernet" > >-#: syntax.py:715 >+#: syntax.py:723 > msgid "FDDI" > msgstr "FDDI" > >-#: syntax.py:715 >+#: syntax.py:723 > msgid "Token-Ring" > msgstr "Token-Ring" > >-#: syntax.py:724 syntax.py:740 >+#: syntax.py:732 syntax.py:748 > msgid "" > "Value must have 6 two digit hexadecimal numbers separated by \"-\" or \":\" !" > msgstr "" > "Der Wert muss 6 mal 2 Hexadezimalwerte beinhalten, die mit einem \"-\" oder " > "\":\"getrennt werden" > >-#: syntax.py:744 >+#: syntax.py:752 > msgid "Type" > msgstr "Typ" > >-#: syntax.py:744 >+#: syntax.py:752 > msgid "Address" > msgstr "Adresse" > >-#: syntax.py:757 >+#: syntax.py:765 > msgid "" > "Value may not contain other than numbers, letters, underscore (\"_\") and " > "minus (\"-\")!" >@@ -454,35 +456,35 @@ > "Der Wert darf nur Zahlen, Buchstaben, Unterstriche (\"_\") und Minuszeichen " > "(\"-\") enthalten." > >-#: syntax.py:761 >+#: syntax.py:769 > msgid "Driver" > msgstr "Treiber" > >-#: syntax.py:761 >+#: syntax.py:769 > msgid "Description" > msgstr "Beschreibung" > >-#: syntax.py:785 syntax.py:850 >+#: syntax.py:793 syntax.py:858 > msgid "Not a valid LDAP DN" > msgstr "Kein gültiger LDAP-DN" > >-#: syntax.py:816 >+#: syntax.py:824 > msgid "Invitation Policy" > msgstr "Richtlinie für Einladungen" > >-#: syntax.py:823 >+#: syntax.py:831 > msgid "Shared folder user ACL" > msgstr "Benutzer ACLs für gemeinsame Ordner" > >-#: syntax.py:828 syntax.py:839 >+#: syntax.py:836 syntax.py:847 > msgid "Not a valid shared folder ACL" > msgstr "Keine gültige ACL für gemeinsame Ordner" > >-#: syntax.py:834 >+#: syntax.py:842 > msgid "Shared folder group ACL" > msgstr "Gruppen ACLs für gemeinsame Ordner" > >-#: syntax.py:871 >+#: syntax.py:879 > msgid "" > "Value consists of two integer numbers separated by an \"x\" (e.g. \"1024x768" > "\")" >@@ -490,312 +492,312 @@ > "Der Wert muss zwei ganzzahlige Werte mit einem \"x\" dazwischen beinhalten " > "(z.B. \"1024x768\")" > >-#: syntax.py:880 >+#: syntax.py:888 > msgid "" > "Value consists of two integer numbers separated by a \"-\" (e.g. \"30-70\")" > msgstr "" > "Der Wert muss aus zwei durch ein \"-\" getrennte ganzzahlige Werte bestehen " > "(z.B. \"30-70\")" > >-#: syntax.py:1116 >+#: syntax.py:1203 > msgid "User ID" > msgstr "Benutzer-ID" > >-#: syntax.py:1121 >+#: syntax.py:1208 > msgid "Group ID" > msgstr "Gruppen-ID" > >-#: syntax.py:1129 >+#: syntax.py:1216 > msgid "Windows Terminal Server Hosts" > msgstr "Windows Terminalserver" > >-#: syntax.py:1134 >+#: syntax.py:1221 > msgid "Linux Terminal Server Hosts" > msgstr "Linux Terminalserver" > >-#: syntax.py:1139 >+#: syntax.py:1226 > msgid "Authentication Server" > msgstr "Authentisierungsserver" > >-#: syntax.py:1144 >+#: syntax.py:1231 > msgid "File Server" > msgstr "Fileserver" > >-#: syntax.py:1161 syntax.py:1166 >+#: syntax.py:1248 syntax.py:1253 > msgid "Primary Group" > msgstr "Primäre Gruppe" > >-#: syntax.py:1171 >+#: syntax.py:1258 > msgid "Network" > msgstr "Netzwerk" > >-#: syntax.py:1177 syntax.py:1192 >+#: syntax.py:1264 syntax.py:1279 > msgid "DNS Entry" > msgstr "DNS-Eintrag" > >-#: syntax.py:1182 syntax.py:1197 >+#: syntax.py:1269 syntax.py:1284 > msgid "DNS Entry Reverse" > msgstr "Reverse Lookup DNS-Eintrag" > >-#: syntax.py:1187 syntax.py:1202 >+#: syntax.py:1274 syntax.py:1289 > msgid "DHCP Entry" > msgstr "DHCP-Eintrag" > >-#: syntax.py:1207 >+#: syntax.py:1294 > msgid "DNS Entry Alias" > msgstr "Alias DNS-Eintrag" > >-#: syntax.py:1199 >+#: syntax.py:1305 > #, python-format > msgid "Entry does not have dnsEntryAlias Syntax: %s" > msgstr "Eintrag hat nicht dnsEntryAlias Syntax: %s" > >-#: syntax.py:1204 >+#: syntax.py:1310 > msgid "Share" > msgstr "Freigabe" > >-#: syntax.py:1599 syntax.py:1618 syntax.py:1632 syntax.py:1671 syntax.py:1760 >+#: syntax.py:1702 syntax.py:1721 syntax.py:1735 syntax.py:1774 syntax.py:1863 > msgid "all" > msgstr "Alle" > >-#: syntax.py:1600 >+#: syntax.py:1703 > msgid "January" > msgstr "Januar" > >-#: syntax.py:1601 >+#: syntax.py:1704 > msgid "February" > msgstr "Februar" > >-#: syntax.py:1602 >+#: syntax.py:1705 > msgid "March" > msgstr "März" > >-#: syntax.py:1603 >+#: syntax.py:1706 > msgid "April" > msgstr "April" > >-#: syntax.py:1604 >+#: syntax.py:1707 > msgid "May" > msgstr "Mai" > >-#: syntax.py:1605 >+#: syntax.py:1708 > msgid "June" > msgstr "Juni" > >-#: syntax.py:1606 >+#: syntax.py:1709 > msgid "July" > msgstr "Juli" > >-#: syntax.py:1607 >+#: syntax.py:1710 > msgid "August" > msgstr "August" > >-#: syntax.py:1608 >+#: syntax.py:1711 > msgid "September" > msgstr "September" > >-#: syntax.py:1609 >+#: syntax.py:1712 > msgid "October" > msgstr "Oktober" > >-#: syntax.py:1610 >+#: syntax.py:1713 > msgid "November" > msgstr "November" > >-#: syntax.py:1611 >+#: syntax.py:1714 > msgid "December" > msgstr "Dezember" > >-#: syntax.py:1619 >+#: syntax.py:1722 > msgid "Monday" > msgstr "Montag" > >-#: syntax.py:1620 >+#: syntax.py:1723 > msgid "Tuesday" > msgstr "Dienstag" > >-#: syntax.py:1621 >+#: syntax.py:1724 > msgid "Wednesday" > msgstr "Mittwoch" > >-#: syntax.py:1622 >+#: syntax.py:1725 > msgid "Thursday" > msgstr "Donnerstag" > >-#: syntax.py:1623 >+#: syntax.py:1726 > msgid "Friday" > msgstr "Freitag" > >-#: syntax.py:1624 >+#: syntax.py:1727 > msgid "Saturday" > msgstr "Samstag" > >-#: syntax.py:1625 >+#: syntax.py:1728 > msgid "Sunday" > msgstr "Sonntag" > >-#: syntax.py:1820 >+#: syntax.py:1923 > msgid "Domain Group" > msgstr "Globale Gruppe" > >-#: syntax.py:1821 >+#: syntax.py:1924 > msgid "Local Group" > msgstr "Lokale Gruppe" > >-#: syntax.py:1822 >+#: syntax.py:1925 > msgid "Well-Known Group" > msgstr "Bekannte Gruppe" > >-#: syntax.py:1831 syntax.py:1838 syntax.py:1845 >+#: syntax.py:1934 syntax.py:1941 syntax.py:1948 > msgid "Soft limit" > msgstr "Soft-Limit" > >-#: syntax.py:1831 syntax.py:1838 syntax.py:1845 >+#: syntax.py:1934 syntax.py:1941 syntax.py:1948 > msgid "Hard limit" > msgstr "Hard-Limit" > >-#: syntax.py:1831 syntax.py:1845 >+#: syntax.py:1934 syntax.py:1948 > msgid "Group" > msgstr "Gruppe" > >-#: syntax.py:1838 >+#: syntax.py:1941 > msgid "User" > msgstr "Benutzer" > >-#: syntax.py:1861 >+#: syntax.py:1964 > msgid "synchronous" > msgstr "synchron" > >-#: syntax.py:1862 >+#: syntax.py:1965 > msgid "asynchronous" > msgstr "asynchron" > >-#: syntax.py:1873 >+#: syntax.py:1976 > #, python-format > msgid "\"%s\" is not a Univention Admin Module." > msgstr "\"%s\" ist kein Univention Admin Modul" > >-#: syntax.py:1911 >+#: syntax.py:2014 > msgid "None" > msgstr "Keine" > >-#: syntax.py:1916 >+#: syntax.py:2019 > msgid "About" > msgstr "Ãber" > >-#: syntax.py:1916 >+#: syntax.py:2019 > msgid "Browse" > msgstr "Navigation" > >-#: syntax.py:1916 >+#: syntax.py:2019 > msgid "Wizards" > msgstr "Assistenten" > >-#: syntax.py:1916 >+#: syntax.py:2019 > msgid "Personal Settings" > msgstr "Persönliche Einstellungen" > >-#: syntax.py:1930 >+#: syntax.py:2033 > msgid "No Reboot" > msgstr "Nicht neu starten" > >-#: syntax.py:1931 >+#: syntax.py:2034 > msgid "Immediately" > msgstr "Sofort" > >-#: syntax.py:1937 >+#: syntax.py:2040 > msgid "Groupware Account" > msgstr "Groupware Konto" > >-#: syntax.py:1938 >+#: syntax.py:2041 > msgid "Kerberos Principal" > msgstr "Kerberos Prinzipal" > >-#: syntax.py:1939 >+#: syntax.py:2042 > msgid "Personal Information" > msgstr "Persönliche Information" > >-#: syntax.py:1940 >+#: syntax.py:2043 > msgid "Samba Account" > msgstr "Samba Konto" > >-#: syntax.py:1941 >+#: syntax.py:2044 > msgid "Posix Account" > msgstr "Posix Konto" > >-#: syntax.py:1942 >+#: syntax.py:2045 > msgid "Mail Account" > msgstr "Mail Konto" > >-#: syntax.py:1950 >+#: syntax.py:2053 > msgid "Disconnect" > msgstr "Trennen" > >-#: syntax.py:1951 >+#: syntax.py:2054 > msgid "Reset" > msgstr "Zurücksetzen" > >-#: syntax.py:1959 >+#: syntax.py:2062 > msgid "All Clients" > msgstr "Von jedem Client" > >-#: syntax.py:1960 >+#: syntax.py:2063 > msgid "Previously used Client" > msgstr "Nur von vorherigem Client" > >-#: syntax.py:1968 syntax.py:1979 >+#: syntax.py:2071 syntax.py:2082 > msgid "Disabled" > msgstr "Deaktiviert" > >-#: syntax.py:1969 >+#: syntax.py:2072 > msgid "Enabled: Input: on, Message: on" > msgstr "Aktiviert: Eingabe: ein, Benachrichtigen: ein" > >-#: syntax.py:1970 >+#: syntax.py:2073 > msgid "Enabled: Input: on, Message: off" > msgstr "Aktiviert: Eingabe: an, Benachrichtigen: aus" > >-#: syntax.py:1971 >+#: syntax.py:2074 > msgid "Enabled: Input: off, Message: on" > msgstr "Aktiviert: Eingabe: aus, Benachrichtigen: an" > >-#: syntax.py:1972 >+#: syntax.py:2075 > msgid "Enabled: Input: off, Message: off" > msgstr "Aktiviert: Eingabe: aus, Benachrichtigen: aus" > >-#: syntax.py:1980 >+#: syntax.py:2083 > msgid "Enabled: Set by Caller" > msgstr "" > >-#: syntax.py:1981 >+#: syntax.py:2084 > msgid "Enabled: No Call Back" > msgstr "" > >-#: syntax.py:2064 >+#: syntax.py:2172 > msgid "NFS-Share" > msgstr "NFS-Freigabe" > >-#: syntax.py:2077 >+#: syntax.py:2185 > msgid "Language code must be in format \"xx_XX\"!" > msgstr "Sprach-Code muss im Format \"xx_XX\" angegeben werden!" > >-#: syntax.py:2083 syntax.py:2087 syntax.py:2090 syntax.py:2093 >+#: syntax.py:2191 syntax.py:2195 syntax.py:2198 syntax.py:2201 > msgid "Language code (e.g. en_US)" > msgstr "Sprachcode (z.B. de_DE)" > >-#: syntax.py:2083 >+#: syntax.py:2191 > msgid "Text" > msgstr "Text" > >-#: syntax.py:2087 >+#: syntax.py:2195 > msgid "Translated short description" > msgstr "Ãbersetzte Kurzbeschreibung" > >-#: syntax.py:2090 >+#: syntax.py:2198 > msgid "Translated long description" > msgstr "Ãbersetzte Langbeschreibung" > >-#: syntax.py:2093 >+#: syntax.py:2201 > msgid "Translated tab name" > msgstr "Ãbersetzter Karteikartenname" > >@@ -880,8 +882,8 @@ > "The DNS alias entry for this host should contain the zone name, the alias " > "zone container DN and the alias." > msgstr "" >-"Der DNS-Alias Eintrag für diesen Rechner sollte den Zonennamen, die LDAP-DN des Alias-Zonencontainers und " >-"den Alias-Namen enthalten." >+"Der DNS-Alias Eintrag für diesen Rechner sollte den Zonennamen, die LDAP-DN " >+"des Alias-Zonencontainers und den Alias-Namen enthalten." > > #: uexceptions.py:102 > msgid "Next IP address not found." >@@ -1075,7 +1077,7 @@ > "Zum Zuweisen von Nagios-Diensten wird ein Eintrag in der DNS Forward Zone " > "benötigt!" > >-#: uexceptions.py:228 >+#: uexceptions.py:234 > msgid "" > "The DNS forward entry could not be created. Please remove existing alias " > "records or comparable DNS objects with the same name as this host from the " >@@ -1085,7 +1087,7 @@ > "DNS-Alias Records oder vergleichbare DNS-Objekte mit dem Namen dieses " > "Rechners aus der DNS-Forward-Zone entfernt werden." > >-#: uexceptions.py:231 >+#: uexceptions.py:237 > msgid "Circular group dependency detected: " > msgstr "Zyklische Gruppen-Abhängigkeit festgestellt: " > >@@ -1102,7 +1104,7 @@ > msgid "Authentication failed" > msgstr "Authentisierung fehlgeschlagen" > >-#: uldap.py:357 >+#: uldap.py:361 > msgid "Moving childs is not supported." > msgstr "Das Verschieben von Kindsknoten wird nicht unterstützt." > >Index: modules/univention/admin/syntax.py >=================================================================== >--- modules/univention/admin/syntax.py (Revision 13639) >+++ modules/univention/admin/syntax.py (Arbeitskopie) >@@ -29,6 +29,7 @@ > # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > > import re, string, types, math, time, operator >+import ipaddr # IPv6 address handling > import univention.debug > import univention.admin.modules > import univention.admin.uexceptions >@@ -451,18 +452,16 @@ > > class ipAddress(simple): > name='ipAddress' >- min_length=7 >- max_length=15 >- _re = re.compile('^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$') >- >+ min_length=2 >+ max_length=39 >+ # match IPv4 (0.0.0.0 is allowed) or IPv6 address (with IPv4-mapped IPv6) > def parse(self, text): >- if text and self._re.match(text) != None: >- for q in text.split('.'): >- if int(q) > 255: >- raise univention.admin.uexceptions.valueError, _("Not a valid IP address!") >- return >+ if text != None: >+ try: >+ ipaddr.IPAddress(text) >+ except ValueError: >+ raise univention.admin.uexceptions.valueError, _("Not a valid IP address!") > return text >- raise univention.admin.uexceptions.valueError, _("Not a valid IP address!") > > class hostOrIP(simple): > name='host' >@@ -470,14 +469,13 @@ > max_length=0 > > def ipAddress(self, text): >- _re = re.compile('(^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$)') >- if text and _re.match(text) != None: >- for q in text.split('.'): >- if int(q) > 255: >- return False >+ # match IPv4 (0.0.0.0 is allowed) or IPv6 address (incl. IPv4-mapped IPv6) >+ if text != None: >+ try: >+ ipaddr.IPAddress(text) >+ except ValueError: >+ return False > return True >- else: >- return False > > def hostName(self, text): > _re = re.compile("(^[a-zA-Z])(([a-zA-Z0-9-]*)([a-zA-Z0-9]$))?$") >@@ -491,7 +489,7 @@ > return text > else: > raise univention.admin.uexceptions.valueError, _('Not a valid hostname or IP address!') >- >+# TODO: IPv6 > class netmask(simple): > name='netmask' > min_length=1 >@@ -617,61 +615,56 @@ > class reverseLookupSubnet(simple): > name='reverseLookupSubnet' > min_length=1 >- max_length=15 >- _re = re.compile('^[0-9]+(\.[0-9]+)?(\.[0-9]+)?$') >+ max_length=19 >+ _re = re.compile('^((0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})(\.(0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})){0,2})$|^([0-9a-fA\ >+-F]{1,4}(?:(?:(?<!::):|(?<=::))[0-9a-fA-F]{0,4}){1,3})$') # IPv4 + IPv6 > > def parse(self, text): > if self._re.match(text) != None: >- for q in text.split('.'): >- if int(q) > 255: >- return > return text >- raise univention.admin.uexceptions.valueError,_("An IP subnet consists of one to three numbers ranging from 0 to 255 separated by dots.") >+ raise univention.admin.uexceptions.valueError,_("An IPv4 subnet consists of one to three numbers ranging from 0 to 255 separated by dots, an IPv6 subnet consists of one to four groups of one to four hexadecimal digits separated by colons (:).") > > class reverseLookupZoneName(simple): > name='reverseLookupZoneName' > min_length=14 >- max_length=30 #? >- _re=re.compile('^[0-9]+(\.[0-9]+)?(\.[0-9]+)?\.in-addr\.arpa$') >+ max_length=72 # IPv6 >+ # TODO: check re.compile IPv6 >+ _re = re.compile('^((0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})(\.(0|[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2})){3}\.in-addr\.arpa$)|((?!.*?::.*?::)[0-9a-fA-F]{0,4}(?:(?:(?<!::):|(?<=::))[0-9a-fA-F]{0,4}){5}(?:(?:(?<!::):|(?<=::))(?:[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2}|0)(?:\.(?:[3-9][0-9]?|2(?:5[0-5]|[0-4]?[0-9])?|1[0-9]{0,2}|0)){3}|(?:(?:(?<!::):|(?<=::))[0-9a-fA-F]{0,4}){2})\.ip6\.arpa)$') # IPv6 > > def parse(self, text): > if self._re.match(text) != None: >- t=text.replace('in-addr.arpa', '') >- for q in t.split('.'): >- if int(q) > 255: >- return > return text >- raise univention.admin.uexceptions.valueError,_("The name of a reverse zone consists of the reversed subnet address followed by .in-addr.arpa. Example: \"0.168.192.in-addr.arpa\"") >+ raise univention.admin.uexceptions.valueError,_("The name of a reverse zone for IPv4 consists of the reversed subnet address followed by .in-addr.arpa (example: \"0.168.192.in-addr.arpa\") or for IPv6 in nibble format followed by .ip6.arpa (example: \"0.0.0.0.0.0.1.0.8.b.d.0.1.0.0.2.ip6.arpa\")") > > class dnsName(simple): > name='dnsName' >- _re = re.compile('^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9.]$') >+ _re = re.compile('^[a-zA-Z0-9:][a-zA-Z0-9.:_-]*[a-zA-Z0-9.]$') # IPv6 > > def parse(self, text): > if text==None: > raise univention.admin.uexceptions.valueError, _("Missing value!") > if self._re.match(text) != None: > return text >- raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters and dots!") >+ raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters, dots and colons!") > > class dnsName_umlauts(simple): > name='dnsName_umlauts' >- _re = re.compile('(?u)(^\w[\w -.]*\w$)|\w*$') >+ _re = re.compile('(?u)(^\w[\w -.:]*\w$)|\w*$') # IPv6 > > def parse(self, text): > if self._re.match(text) != None: > return text >- raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters and dots!") >+ raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters, dots and colons!") > > class dnsNameDot(simple): > name='dnsName' >- _re = re.compile('^[0-9a-zA-Z.-]+$') >+ _re = re.compile('^[0-9a-zA-Z.:-]+$') # IPv6 > > def parse(self, text): > if self._re.match(text) != None: > return text > >- raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters and dots!") >+ raise univention.admin.uexceptions.valueError, _("Value may not contain other than numbers, letters, dots and colons!") > > > class keyAndValue(complex):
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 15687
:
1963
|
2016
|
2038