|
|
|
@ -9942,7 +9942,7 @@ domain name)")
|
|
|
|
|
'help':_("new ip address")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(18,),
|
|
|
|
|
'longOption':"mxhosts",
|
|
|
|
|
'longOption':"mx",
|
|
|
|
|
'optVal':"MAIL_SERVERS",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("new hostnames mail servers for mail exchanger (comma \
|
|
|
|
@ -9982,12 +9982,18 @@ reverse zone")
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("master autoritative DNS server for zone (hostname server)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
'longOption':"ipserver",
|
|
|
|
|
'optVal':"IPSERVER",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("ip for master autoritative DNS server for zone")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
'longOption':"ip",
|
|
|
|
|
'optVal':"IP_ZONE",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("ip zone")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
'longOption':"email",
|
|
|
|
|
'optVal':"email",
|
|
|
|
@ -10000,6 +10006,13 @@ reverse zone")
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("All autoritative DNS servers for zone (comma delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
'longOption':"mx",
|
|
|
|
|
'optVal':"MAIL_SERVERS",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("host names mail servers for mail exchanger (comma \
|
|
|
|
|
delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(19,),
|
|
|
|
|
'longOption':"refresh",
|
|
|
|
|
'optVal':"REFRESH",
|
|
|
|
@ -10035,6 +10048,18 @@ zone, default - 2H (2 hours)")
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("zone name, 'domain name' for forward zone or 'net name' for \
|
|
|
|
|
reverse zone")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(20,),
|
|
|
|
|
'longOption':"ip",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("remove all A records from an existing zone \
|
|
|
|
|
(used with option --name)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(20,),
|
|
|
|
|
'longOption':"mx",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("remove all MX records from an existing zone \
|
|
|
|
|
(used with option --name)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(21,),
|
|
|
|
|
'shortOption':"n",
|
|
|
|
@ -10050,6 +10075,26 @@ reverse zone")
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("master autoritative DNS server for zone (hostname server)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(21,),
|
|
|
|
|
'longOption':"ip",
|
|
|
|
|
'optVal':"IP_ZONE",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("new ip address")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(21,),
|
|
|
|
|
'longOption':"mx",
|
|
|
|
|
'optVal':"MAIL_SERVERS",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("new hostnames mail servers for mail exchanger (comma \
|
|
|
|
|
delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(21,),
|
|
|
|
|
'longOption':"mxhost",
|
|
|
|
|
'optVal':"MAIL_SERVERS",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("rename old hostname mail server to new hostname mail server \
|
|
|
|
|
for mail exchanger (comma delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(21,),
|
|
|
|
|
'longOption':"email",
|
|
|
|
|
'optVal':"email",
|
|
|
|
@ -12570,6 +12615,7 @@ class cl_info(cl_utils2.cl_smartcon):
|
|
|
|
|
if slaveZones:
|
|
|
|
|
# Получаем данные для подчиненной зоны
|
|
|
|
|
slaveIPs = []
|
|
|
|
|
slaveZones.sort()
|
|
|
|
|
for slZone in slaveZones:
|
|
|
|
|
flagAddIPs = False
|
|
|
|
|
xmlArea = objTxtZone.getXMLZoneToName(slZone)[0]
|
|
|
|
@ -12584,7 +12630,6 @@ class cl_info(cl_utils2.cl_smartcon):
|
|
|
|
|
slaveIPs.append(",".join(ips))
|
|
|
|
|
if not flagAddIPs:
|
|
|
|
|
slaveIPs.append("")
|
|
|
|
|
slaveZones.sort()
|
|
|
|
|
reverseZones = filter(lambda x: '.in-addr.arpa' in x,\
|
|
|
|
|
slaveZones)
|
|
|
|
|
# Прямые зоны
|
|
|
|
@ -12606,12 +12651,11 @@ class cl_info(cl_utils2.cl_smartcon):
|
|
|
|
|
if not zoneName:
|
|
|
|
|
self.printERROR(_('Incorrect zone name'))
|
|
|
|
|
return False
|
|
|
|
|
net = zoneName
|
|
|
|
|
# Проверка на прямую зону
|
|
|
|
|
forwardZone = servDnsObj.isForwardName(zoneName)
|
|
|
|
|
# Обратная зона
|
|
|
|
|
if not forwardZone:
|
|
|
|
|
network, spl, netmask = net.rpartition("/")
|
|
|
|
|
network, spl, netmask = zoneName.rpartition("/")
|
|
|
|
|
if not netmask == "24" or \
|
|
|
|
|
not servDnsObj.isCorrectStringNet(net):
|
|
|
|
|
self.printERROR(_('Incorrect network %s for reverse zone')\
|
|
|
|
@ -12676,14 +12720,19 @@ for %s DNS zone")%zoneName)
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
soaRecord = zoneData[0][0][1]['sOARecord'][0]
|
|
|
|
|
# Все авторитативные сервера зоны
|
|
|
|
|
nSRecords = zoneData[0][0][1]['nSRecord']
|
|
|
|
|
mXRecords = []
|
|
|
|
|
if zoneData[0][0][1].has_key('mXRecord'):
|
|
|
|
|
mXRecords = zoneData[0][0][1]['mXRecord']
|
|
|
|
|
aRecords = []
|
|
|
|
|
if zoneData[0][0][1].has_key('aRecord'):
|
|
|
|
|
aRecords = zoneData[0][0][1]['aRecord']
|
|
|
|
|
soaData = map(lambda x: delDot(x), soaRecord.split(" "))
|
|
|
|
|
if len(soaData)!=7:
|
|
|
|
|
self.printERROR(_("Incorrect SOA Record in DNS zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Все авторитативные сервера зоны, в случае slаve зоны
|
|
|
|
|
namesServers = map(lambda x: delDot(x), nSRecords)
|
|
|
|
|
# Авторитативный сервер
|
|
|
|
|
nameServer = soaData[0]
|
|
|
|
|
# Почтовый адрес администратора зоны
|
|
|
|
@ -12704,13 +12753,21 @@ for %s DNS zone")%zoneName)
|
|
|
|
|
headerList = [_("Field"), _("Value")]
|
|
|
|
|
dataList = [[_("Zone name"), zoneName],
|
|
|
|
|
[_("Master autoritative server"), nameServer],
|
|
|
|
|
[_("Autoritative servers"), ",".join(namesServers)],
|
|
|
|
|
[_("Email administrator"), email],
|
|
|
|
|
[_("Serial number"), serialNumber],
|
|
|
|
|
[_("Refresh"), refresh],
|
|
|
|
|
[_("Update"), update],
|
|
|
|
|
[_("Expiry"), expiry],
|
|
|
|
|
[_("Minimum"), minimum]]
|
|
|
|
|
if mXRecords:
|
|
|
|
|
map(lambda x:dataList.insert(2,["",x]) ,reversed(mXRecords[1:]))
|
|
|
|
|
dataList.insert(2,[_("MX record"), mXRecords[0]])
|
|
|
|
|
if aRecords:
|
|
|
|
|
map(lambda x:dataList.insert(2,["",x]) ,reversed(aRecords[1:]))
|
|
|
|
|
dataList.insert(2,[_("A record"), aRecords[0]])
|
|
|
|
|
if nSRecords:
|
|
|
|
|
map(lambda x:dataList.insert(2,["",x]), reversed(nSRecords[1:]))
|
|
|
|
|
dataList.insert(2,[_("NS record"), nSRecords[0]])
|
|
|
|
|
repObj = report(title, headerList, dataList)
|
|
|
|
|
repObj.printReport()
|
|
|
|
|
recordsSearch = servDnsObj.searchAllRecordInZone(zoneName)
|
|
|
|
@ -14777,7 +14834,10 @@ class servDns(shareLdap):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def isForwardZone(self, zoneName):
|
|
|
|
|
"""Прямая зона - True, обратная False"""
|
|
|
|
|
"""Прямая зона - True, обратная False
|
|
|
|
|
|
|
|
|
|
Проверка на .in-addr.arpa
|
|
|
|
|
"""
|
|
|
|
|
return self._getRelZoneBaseDN(zoneName, "isFwdZone")
|
|
|
|
|
|
|
|
|
|
def getRelZonesDN(self, zoneName):
|
|
|
|
@ -14932,7 +14992,8 @@ class servDns(shareLdap):
|
|
|
|
|
refresh=zoneRefresh,
|
|
|
|
|
updateRetry=zoneUpdateRetry,
|
|
|
|
|
expiry=zoneExpiry,
|
|
|
|
|
minimum=zoneMinimum):
|
|
|
|
|
minimum=zoneMinimum,
|
|
|
|
|
ip="", mxList=[]):
|
|
|
|
|
"""Создание первичной DNS зоны в конфигурационном файле и в LDAP
|
|
|
|
|
Параметры:
|
|
|
|
|
nameServer - имя первичного мастер сервера DNS зоны
|
|
|
|
@ -14950,6 +15011,8 @@ class servDns(shareLdap):
|
|
|
|
|
Количество записей типа NS должно точно
|
|
|
|
|
соответствовать количеству DNS-серверов, обслуживающих
|
|
|
|
|
домен и включать все DNS-серверы, указанные в домене
|
|
|
|
|
ip - адрес зоны
|
|
|
|
|
mx - MX записи для зоны
|
|
|
|
|
"""
|
|
|
|
|
# Добавление зоны в конфигурационный файл
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
@ -14973,7 +15036,7 @@ class servDns(shareLdap):
|
|
|
|
|
# Создание зоны в LDAP (создается объект переменных и соединение с LDAP)
|
|
|
|
|
if not self.createZoneInLDAP(zoneName, nameServer, emailAddr,
|
|
|
|
|
serialNumber, refresh, updateRetry,
|
|
|
|
|
expiry, minimum, namesServers):
|
|
|
|
|
expiry, minimum, namesServers, ip, mxList):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
if not self.startServices(['dns'],False):
|
|
|
|
@ -15020,7 +15083,8 @@ class servDns(shareLdap):
|
|
|
|
|
updateRetry,
|
|
|
|
|
expiry,
|
|
|
|
|
minimum,
|
|
|
|
|
namesServers):
|
|
|
|
|
namesServers,
|
|
|
|
|
ip, mxList):
|
|
|
|
|
"""Создание DNS зоны в LDAP
|
|
|
|
|
Параметры:
|
|
|
|
|
nameServer - имя первичного мастер сервера DNS зоны
|
|
|
|
@ -15038,6 +15102,8 @@ class servDns(shareLdap):
|
|
|
|
|
Количество записей типа NS должно точно
|
|
|
|
|
соответствовать количеству DNS-серверов, обслуживающих
|
|
|
|
|
домен и включать все DNS-серверы, указанные в домене
|
|
|
|
|
ip - адрес зоны
|
|
|
|
|
mx - MX записи для зоны
|
|
|
|
|
"""
|
|
|
|
|
if not nameServer:
|
|
|
|
|
self.printERROR(_("Empty name server in sOA Record in zone %s")\
|
|
|
|
@ -15079,6 +15145,15 @@ class servDns(shareLdap):
|
|
|
|
|
return False
|
|
|
|
|
baseDN = self.clVars.Get("ld_dns_dn")
|
|
|
|
|
if ".in-addr.arpa" in zoneName:
|
|
|
|
|
if ip:
|
|
|
|
|
self.printERROR(_("Can not add A record %s")%ip + " " +\
|
|
|
|
|
_("in reverse zone %s")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
if mxList:
|
|
|
|
|
self.printERROR(_("Can not add MX records %s")\
|
|
|
|
|
%", ".join(mxList) +\
|
|
|
|
|
" " + _("in reverse zone %s")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# реверсивная зона
|
|
|
|
|
zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, self.relRevDN,
|
|
|
|
|
baseDN)
|
|
|
|
@ -15099,7 +15174,13 @@ class servDns(shareLdap):
|
|
|
|
|
('zoneName',[zoneName]),
|
|
|
|
|
('sOARecord',[sOARecord]),
|
|
|
|
|
('nSRecord',namesServersDot)]
|
|
|
|
|
|
|
|
|
|
if ip:
|
|
|
|
|
zoneDomainEntry += [('aRecord',ip)]
|
|
|
|
|
if mxList:
|
|
|
|
|
mxListDot = map(lambda x: addDot(x), mxList)
|
|
|
|
|
mxValues = map(lambda x: "%s %s" %(x*10+10, mxListDot[x]),\
|
|
|
|
|
range(len(mxListDot)))
|
|
|
|
|
zoneDomainEntry += [('mXRecord', mxValues)]
|
|
|
|
|
if not self.addEntry(zoneDomainDN, zoneDomainEntry,
|
|
|
|
|
zoneDomainErrorMessage):
|
|
|
|
|
return False
|
|
|
|
@ -15268,12 +15349,11 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
self.printERROR(_('Incorrect zone name'))
|
|
|
|
|
self.printERROR(_('Error in command line options "-n"'))
|
|
|
|
|
return False
|
|
|
|
|
net = zoneName
|
|
|
|
|
# Проверка на прямую зону
|
|
|
|
|
forwardZone = self.isForwardName(zoneName)
|
|
|
|
|
# Обратная зона
|
|
|
|
|
if not forwardZone:
|
|
|
|
|
network, spl, netmask = net.rpartition("/")
|
|
|
|
|
network, spl, netmask = zoneName.rpartition("/")
|
|
|
|
|
if not netmask == "24" or \
|
|
|
|
|
not self.isCorrectStringNet(net):
|
|
|
|
|
self.printERROR(_('Incorrect network %s for reverse zone')\
|
|
|
|
@ -15290,7 +15370,52 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
if not zoneName:
|
|
|
|
|
self.printERROR(_("Not enough command line option %s")%"-n")
|
|
|
|
|
return False
|
|
|
|
|
return self.deleteZone(zoneName)
|
|
|
|
|
if options.has_key('ip') or options.has_key('mx'):
|
|
|
|
|
# Получение данных зоны из LDAP
|
|
|
|
|
zoneData = self.searchAllDomainNamesInLDAP("@.%s"%zoneName)
|
|
|
|
|
if not zoneData:
|
|
|
|
|
self.printERROR(_("Can not found SOA record in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Удаление A записи
|
|
|
|
|
if options.has_key('ip'):
|
|
|
|
|
if not zoneData[0][0][1].has_key('aRecord'):
|
|
|
|
|
self.printERROR(_("Can not found A records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
if not zoneData[0][0][1].has_key('mXRecord'):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not found MX records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
relZoneDN = self.getRelZoneDN(zoneName)
|
|
|
|
|
modAttrs =[(ldap.MOD_DELETE, 'aRecord', None)]
|
|
|
|
|
DN = self.addDN("relativeDomainName=@", relZoneDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not delete A records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Deleted A records in zone %s")%zoneName)
|
|
|
|
|
ret = True
|
|
|
|
|
# Удаление MX записей
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
if not zoneData[0][0][1].has_key('mXRecord'):
|
|
|
|
|
self.printERROR(_("Can not found MX records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем все MX записи в записи зоны
|
|
|
|
|
ret = self.modMXRecord("@", zoneName, zoneName,
|
|
|
|
|
True, [])
|
|
|
|
|
# Увеличиваем на 1 серийный номер зоны
|
|
|
|
|
if not self.incrementSerialNumberZone(zoneName):
|
|
|
|
|
return False
|
|
|
|
|
return ret
|
|
|
|
|
else:
|
|
|
|
|
# Удаляем зону
|
|
|
|
|
return self.deleteZone(zoneName)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def addZoneDnsServer(self, options):
|
|
|
|
|
"""Добавляет зону в DNS"""
|
|
|
|
@ -15330,43 +15455,74 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
delDot = lambda y: ".".join(filter(lambda x: x, y.split(".")))
|
|
|
|
|
# Имя зоны
|
|
|
|
|
zoneName = ""
|
|
|
|
|
forwardZone = True
|
|
|
|
|
if options.has_key('n'):
|
|
|
|
|
forwardZone = True
|
|
|
|
|
zoneName = delDot(options["n"].lower())
|
|
|
|
|
if not zoneName:
|
|
|
|
|
self.printERROR(_('Incorrect zone name'))
|
|
|
|
|
self.printERROR(_('Error in command line options "-n"'))
|
|
|
|
|
return False
|
|
|
|
|
net = zoneName
|
|
|
|
|
# Проверка на сеть
|
|
|
|
|
splNet = net.split(".")
|
|
|
|
|
for octet in splNet:
|
|
|
|
|
flagIntOctet = True
|
|
|
|
|
try:
|
|
|
|
|
int(octet)
|
|
|
|
|
except:
|
|
|
|
|
flagIntOctet = False
|
|
|
|
|
if flagIntOctet:
|
|
|
|
|
forwardZone = False
|
|
|
|
|
break
|
|
|
|
|
network, spl, netmask = net.rpartition("/")
|
|
|
|
|
if not netmask == "24" or \
|
|
|
|
|
not self.isCorrectStringNet(net):
|
|
|
|
|
if not forwardZone:
|
|
|
|
|
# Проверка на прямую зону
|
|
|
|
|
forwardZone = self.isForwardName(zoneName)
|
|
|
|
|
# Обратная зона
|
|
|
|
|
if forwardZone:
|
|
|
|
|
# Проверка на имя хоста в LDAP
|
|
|
|
|
if self.searchAllDomainNamesInLDAP(zoneName):
|
|
|
|
|
self.printERROR(_("Found record %s in LDAP")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Проверка на недопустимые ключи для обратной зоны
|
|
|
|
|
# ip зоны для обратной зоны недопустим
|
|
|
|
|
if options.has_key('ip'):
|
|
|
|
|
self.printERROR(_('Command line options "--ip" \
|
|
|
|
|
incompatible with reverse DNS zone %s')%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# MX записи для обратной зоны недопустимы
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
self.printERROR(_('Command line options "--mx" \
|
|
|
|
|
incompatible with reverse DNS zone %s')%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
network, spl, netmask = zoneName.rpartition("/")
|
|
|
|
|
if not netmask == "24" or \
|
|
|
|
|
not self.isCorrectStringNet(zoneName):
|
|
|
|
|
self.printERROR(_('Incorrect network %s for reverse zone')\
|
|
|
|
|
%zoneName)
|
|
|
|
|
self.printWARNING(_("Example network for reverse zone") +\
|
|
|
|
|
" :")
|
|
|
|
|
" :")
|
|
|
|
|
self.printWARNING(_('"-n 192.168.0.0/24"'))
|
|
|
|
|
return False
|
|
|
|
|
# Обратная зона
|
|
|
|
|
if not forwardZone:
|
|
|
|
|
netSpl = network.split(".")
|
|
|
|
|
netSpl.pop()
|
|
|
|
|
netSpl.reverse()
|
|
|
|
|
# Имя обратной зоны
|
|
|
|
|
zoneName = "%s.in-addr.arpa" %".".join(netSpl)
|
|
|
|
|
|
|
|
|
|
# Ищем зону
|
|
|
|
|
# Ишем зону в LDAP
|
|
|
|
|
if self.searchZoneInLDAP(zoneName):
|
|
|
|
|
self.printERROR(_("DNS zone %s exists in LDAP")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Ищем зону в тексте конфига
|
|
|
|
|
objTxtZone = dnsZoneTxt()
|
|
|
|
|
if zoneName in objTxtZone.getAllNamesZones():
|
|
|
|
|
self.printERROR(_("DNS zone %s exists in /etc/bind/named.conf")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# ip зоны
|
|
|
|
|
zoneIP = ""
|
|
|
|
|
if options.has_key('ip'):
|
|
|
|
|
zoneIP = options["ip"]
|
|
|
|
|
if "," in zoneIP or \
|
|
|
|
|
not self.isCorrectStringNet(zoneIP, False):
|
|
|
|
|
self.printERROR(_("IP address %s incorrectly")%zoneIP)
|
|
|
|
|
return False
|
|
|
|
|
# Почтовые серверы для зоны
|
|
|
|
|
zoneListMX = []
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
zoneListMX = map(lambda x: delDot(x.lower()),\
|
|
|
|
|
options['mx'].split(","))
|
|
|
|
|
zoneListMX = self._unicList(zoneListMX)
|
|
|
|
|
if not self.checkMXDomains(zoneListMX):
|
|
|
|
|
return False
|
|
|
|
|
# Все авторитативные сервера зоны, в случае slаve зоны
|
|
|
|
|
# ip авторитативных серверов хранения зоны
|
|
|
|
|
namesServers = []
|
|
|
|
@ -15397,6 +15553,8 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
|
|
|
|
|
# Мастер зона
|
|
|
|
|
if flagZoneMaster:
|
|
|
|
|
# Предупреждение о необходимости создания A записей для MX записей
|
|
|
|
|
warningsMX = []
|
|
|
|
|
# Авторитативный сервер
|
|
|
|
|
nameServer = ""
|
|
|
|
|
if options.has_key('server'):
|
|
|
|
@ -15420,7 +15578,8 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
nsHostName, spl, nsZoneName = nameServer.partition(".")
|
|
|
|
|
# ip авторитативного сервера
|
|
|
|
|
ipserver = ""
|
|
|
|
|
if nsZoneName == zoneName or (self.searchZoneInLDAP(nsZoneName) and\
|
|
|
|
|
if nameServer == zoneName or nsZoneName == zoneName or\
|
|
|
|
|
(self.searchZoneInLDAP(nsZoneName) and\
|
|
|
|
|
not self.searchDomainNameInLDAP(nameServer)):
|
|
|
|
|
if not options.has_key('ipserver'):
|
|
|
|
|
self.printERROR(_('Not found A-record for "%s" \
|
|
|
|
@ -15429,6 +15588,11 @@ incompatible with options "--ip" (PTR record)'))
|
|
|
|
|
"--ipserver"'))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if nameServer == zoneName and zoneIP:
|
|
|
|
|
self.printERROR(_("The same zone name and name of \
|
|
|
|
|
the primary authoritative server for the zone"))
|
|
|
|
|
self.printERROR(_('We do not need the option "--ip"'))
|
|
|
|
|
return False
|
|
|
|
|
ipserver = options["ipserver"]
|
|
|
|
|
if "," in ipserver or \
|
|
|
|
|
not self.isCorrectStringNet(ipserver, False):
|
|
|
|
@ -15469,21 +15633,40 @@ this DNS server')%nameServer)
|
|
|
|
|
_('Incorrect command line options "--%s')\
|
|
|
|
|
%nameOpt + " " + '%s"'%valueOpt)
|
|
|
|
|
return False
|
|
|
|
|
# создание основной зоны
|
|
|
|
|
if not self.createMasterZone(zoneName, nameServer, email,
|
|
|
|
|
namesServers, "1",
|
|
|
|
|
locals()['refresh'],
|
|
|
|
|
locals()['update'],
|
|
|
|
|
locals()['expiry'],
|
|
|
|
|
locals()['minimum']):
|
|
|
|
|
return False
|
|
|
|
|
# Добавление localhost.имя_зоны
|
|
|
|
|
if forwardZone:
|
|
|
|
|
if nameServer == zoneName and ipserver:
|
|
|
|
|
zoneIP = ipserver
|
|
|
|
|
# создание основной зоны (прямая зона)
|
|
|
|
|
if not self.createMasterZone(zoneName, nameServer, email,
|
|
|
|
|
namesServers, "1",
|
|
|
|
|
locals()['refresh'],
|
|
|
|
|
locals()['update'],
|
|
|
|
|
locals()['expiry'],
|
|
|
|
|
locals()['minimum'],
|
|
|
|
|
zoneIP, zoneListMX):
|
|
|
|
|
return False
|
|
|
|
|
# Добавление localhost.имя_зоны
|
|
|
|
|
optionsLocalhost = {"autoptr":"off","t":"a",
|
|
|
|
|
"host":"localhost.%s"%zoneName,
|
|
|
|
|
"ip":"127.0.0.1"}
|
|
|
|
|
if not self.addRecordDnsServer(optionsLocalhost):
|
|
|
|
|
return False
|
|
|
|
|
# Предупреждение о добавлении A записей для MX записей зоны
|
|
|
|
|
# Находим список хостов которые необходимо добавить
|
|
|
|
|
ARecordsForMX = self.getNotFoundRecords(zoneListMX)
|
|
|
|
|
if ARecordsForMX:
|
|
|
|
|
warningsMX=[_("For some MX records not found PTR records"),
|
|
|
|
|
_("Create A records for hostnames: %s")\
|
|
|
|
|
%", ".join(ARecordsForMX)]
|
|
|
|
|
else:
|
|
|
|
|
# создание основной зоны (обратная зона)
|
|
|
|
|
if not self.createMasterZone(zoneName, nameServer, email,
|
|
|
|
|
namesServers, "1",
|
|
|
|
|
locals()['refresh'],
|
|
|
|
|
locals()['update'],
|
|
|
|
|
locals()['expiry'],
|
|
|
|
|
locals()['minimum']):
|
|
|
|
|
return False
|
|
|
|
|
# Создание обратной зоны в случае необходимости
|
|
|
|
|
if ipserver:
|
|
|
|
|
dataIP = self.getDomainAndZoneFromIP(ipserver)
|
|
|
|
@ -15500,11 +15683,12 @@ this DNS server')%nameServer)
|
|
|
|
|
locals()['expiry'],
|
|
|
|
|
locals()['minimum']):
|
|
|
|
|
return False
|
|
|
|
|
# Добавление A записи для первичного DNS сервера
|
|
|
|
|
optionsR = {"autoptr":"off","t":"a","host":nameServer,
|
|
|
|
|
"ip":ipserver}
|
|
|
|
|
if not self.addRecordDnsServer(optionsR):
|
|
|
|
|
return False
|
|
|
|
|
if not nameServer == zoneName:
|
|
|
|
|
# Добавление A записи для первичного DNS сервера
|
|
|
|
|
optionsR = {"autoptr":"off","t":"a","host":nameServer,
|
|
|
|
|
"ip":ipserver}
|
|
|
|
|
if not self.addRecordDnsServer(optionsR):
|
|
|
|
|
return False
|
|
|
|
|
foundReverseDomain =self.searchDomainNameInLDAP(domainNamePTR)
|
|
|
|
|
if foundReverseDomain:
|
|
|
|
|
zoneName = foundReverseDomain[0][0][1]['zoneName'][0]
|
|
|
|
@ -15518,7 +15702,7 @@ this DNS server')%nameServer)
|
|
|
|
|
listOctRev = \
|
|
|
|
|
zoneName.rpartition(".in-addr.arpa")[0].split(".")
|
|
|
|
|
listOctRev.reverse()
|
|
|
|
|
reverseIp = ".".join(listOctRev)
|
|
|
|
|
reverseIp = ".".join(listOctRev +[relativeDomainName])
|
|
|
|
|
self.printWARNING(_("Can not add PTR record in LDAP"))
|
|
|
|
|
self.printWARNING(_("PTR record exists"))
|
|
|
|
|
self.printWARNING("%s --> %s"%(reverseIp,reverseHost))
|
|
|
|
@ -15528,8 +15712,20 @@ this DNS server')%nameServer)
|
|
|
|
|
optionsR = {"t":"ptr", "host":nameServer, "ip":ipserver}
|
|
|
|
|
if not self.addRecordDnsServer(optionsR):
|
|
|
|
|
return False
|
|
|
|
|
if warningsMX:
|
|
|
|
|
for warning in warningsMX:
|
|
|
|
|
self.printWARNING(warning)
|
|
|
|
|
# Slave зона
|
|
|
|
|
else:
|
|
|
|
|
# Не нужные ключи командной строки
|
|
|
|
|
notCmdKey = list(set(optKeys) - set(minKeys))
|
|
|
|
|
if notCmdKey:
|
|
|
|
|
# Добавляем кавычки и --
|
|
|
|
|
addQ = lambda y: map(lambda x:\
|
|
|
|
|
len(x)>1 and '"--%s"'%x or '"-%s"'%x, y)
|
|
|
|
|
self.printERROR(_("Incorrect command line options %s")\
|
|
|
|
|
%", ".join(addQ(notCmdKey)))
|
|
|
|
|
return False
|
|
|
|
|
if not self.createSlaveZone(zoneName, namesServers):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
@ -15563,25 +15759,45 @@ this DNS server')%nameServer)
|
|
|
|
|
i += 10
|
|
|
|
|
mxString = "%s %s" %(i, addDot(mxServer))
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'mXRecord', mxString))
|
|
|
|
|
DN = self.addDN("relativeDomainName=%s"\
|
|
|
|
|
%hostName, relZoneDN)
|
|
|
|
|
DN = self.addDN("relativeDomainName=%s"%hostName, relZoneDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printERROR(_("Can not modify MX hosts in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
if hostName == "@":
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printERROR(_("Can not modify MX hosts in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not delete all MX records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not delete all MX records in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printERROR(_("Can not modify MX hosts in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not delete all MX records in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
return False
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printSUCCESS(_("Modified MX hosts in A record %s")%domainName)
|
|
|
|
|
for mxServer in mxServers:
|
|
|
|
|
self.printSUCCESS("%s --> %s"%(domainName, mxServer))
|
|
|
|
|
self.printSUCCESS("")
|
|
|
|
|
if hostName == "@":
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printSUCCESS(_("Modified MX hosts in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
for mxServer in mxServers:
|
|
|
|
|
self.printSUCCESS("%s --> %s"%(domainName, mxServer))
|
|
|
|
|
self.printSUCCESS("")
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS(_("Deleted all MX records in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS(_("Deleted all MX records in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
if mxServers:
|
|
|
|
|
self.printSUCCESS(_("Modified MX hosts in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
for mxServer in mxServers:
|
|
|
|
|
self.printSUCCESS("%s --> %s"%(domainName, mxServer))
|
|
|
|
|
self.printSUCCESS("")
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS(_("Deleted all MX records in A record %s")\
|
|
|
|
|
%domainName)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modPTRRecord(self, ip, PTRHostName, PTRDomainName, PTRZoneName,
|
|
|
|
@ -15684,12 +15900,11 @@ this DNS server')%nameServer)
|
|
|
|
|
self.printERROR(_('Incorrect zone name'))
|
|
|
|
|
self.printERROR(_('Error in command line options "-n"'))
|
|
|
|
|
return False
|
|
|
|
|
net = zoneName
|
|
|
|
|
# Проверка на прямую зону
|
|
|
|
|
forwardZone = self.isForwardName(zoneName)
|
|
|
|
|
# Обратная зона
|
|
|
|
|
if not forwardZone:
|
|
|
|
|
network, spl, netmask = net.rpartition("/")
|
|
|
|
|
network, spl, netmask = zoneName.rpartition("/")
|
|
|
|
|
if not netmask == "24" or \
|
|
|
|
|
not self.isCorrectStringNet(net):
|
|
|
|
|
self.printERROR(_('Incorrect network %s for reverse zone')\
|
|
|
|
@ -15710,6 +15925,33 @@ this DNS server')%nameServer)
|
|
|
|
|
if not self.searchZoneInLDAP(zoneName):
|
|
|
|
|
self.printERROR(_("Can not found master zone %s in LDAP")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# MX серверы
|
|
|
|
|
mxServers = []
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
mxServers=map(lambda x: delDot(x.lower()),
|
|
|
|
|
options['mx'].split(","))
|
|
|
|
|
mxServers = self._unicList(mxServers)
|
|
|
|
|
# Переименование mx записи
|
|
|
|
|
# modMxServers[0] - cтарая запись
|
|
|
|
|
# modMxServers[1] - новая запись
|
|
|
|
|
modMxServers = []
|
|
|
|
|
if options.has_key('mxhost'):
|
|
|
|
|
modMxServers=map(lambda x: delDot(x.lower()),\
|
|
|
|
|
options['mxhost'].split(","))
|
|
|
|
|
modMxServers = self._unicList(modMxServers)
|
|
|
|
|
if len(modMxServers)!=2:
|
|
|
|
|
self.printERROR(_('Incorrect command line options "--mxhost"'))
|
|
|
|
|
self.printWARNING(_("Example") + ":")
|
|
|
|
|
self.printWARNING("--mxhost old.mail.host,new.mail.host")
|
|
|
|
|
return False
|
|
|
|
|
# ip зоны
|
|
|
|
|
zoneIP = ""
|
|
|
|
|
if options.has_key('ip'):
|
|
|
|
|
zoneIP = options["ip"]
|
|
|
|
|
if "," in zoneIP or \
|
|
|
|
|
not self.isCorrectStringNet(zoneIP, False):
|
|
|
|
|
self.printERROR(_("IP address %s incorrectly")%zoneIP)
|
|
|
|
|
return False
|
|
|
|
|
# Получение данных зоны из LDAP
|
|
|
|
|
zoneData = self.searchAllDomainNamesInLDAP("@.%s"%zoneName)
|
|
|
|
|
if not zoneData:
|
|
|
|
@ -15724,6 +15966,70 @@ this DNS server')%nameServer)
|
|
|
|
|
# Все авторитативные сервера зоны, в случае slаve зоны
|
|
|
|
|
namesServers = map(lambda x: delDot(x), nSRecords)
|
|
|
|
|
oldNamesServers = map(lambda x: delDot(x), nSRecords)
|
|
|
|
|
# Изменяем ip зоны
|
|
|
|
|
if zoneIP:
|
|
|
|
|
addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x
|
|
|
|
|
relZoneDN = self.getRelZoneDN(zoneName)
|
|
|
|
|
modAttrs = []
|
|
|
|
|
if zoneData[0][0][1].has_key('aRecord'):
|
|
|
|
|
modAttrs =[(ldap.MOD_DELETE, 'aRecord', None)]
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'aRecord', zoneIP))
|
|
|
|
|
DN = self.addDN("relativeDomainName=@", relZoneDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
self.printERROR(_("Can not modify A record in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Modified A record in zone %s")%zoneName)
|
|
|
|
|
self.printSUCCESS("%s --> %s"%(zoneName, zoneIP))
|
|
|
|
|
self.printSUCCESS("")
|
|
|
|
|
# Изменяем MX записи
|
|
|
|
|
if mxServers or modMxServers:
|
|
|
|
|
flagFoundMX = False
|
|
|
|
|
if zoneData[0][0][1].has_key('mXRecord'):
|
|
|
|
|
flagFoundMX = True
|
|
|
|
|
# Изменяем почтовый хост на другой почтовый хост
|
|
|
|
|
if modMxServers:
|
|
|
|
|
if not flagFoundMX:
|
|
|
|
|
self.printERROR(_("Can not found MX record in zone %s")\
|
|
|
|
|
%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Находим нужную запись
|
|
|
|
|
foundMxServers = map(lambda x: len(x.split(" "))==1\
|
|
|
|
|
and delDot(x) or delDot(x.split(" ")[1]),\
|
|
|
|
|
zoneData[0][0][1]['mXRecord'])
|
|
|
|
|
oldMxHost = modMxServers[0]
|
|
|
|
|
newMxHost = modMxServers[1]
|
|
|
|
|
if not oldMxHost in foundMxServers:
|
|
|
|
|
self.printERROR(_("Can not found MX host %s")\
|
|
|
|
|
%oldMxHost +" " + _("in zone %s")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Проверка наличия новой MX записи в A записи
|
|
|
|
|
if newMxHost in foundMxServers:
|
|
|
|
|
self.printERROR(_("MX host %s exists")\
|
|
|
|
|
%newMxHost +" " + _("in zone %s")%zoneName)
|
|
|
|
|
return False
|
|
|
|
|
# Проверка существования A записи для MX хоста
|
|
|
|
|
if not self.checkMXDomains([newMxHost]):
|
|
|
|
|
return False
|
|
|
|
|
# Добавляемые MX хосты
|
|
|
|
|
addMxServers = []
|
|
|
|
|
for foundMxServer in foundMxServers:
|
|
|
|
|
if foundMxServer == oldMxHost:
|
|
|
|
|
# Замена имени хоста
|
|
|
|
|
addMxServers.append(newMxHost)
|
|
|
|
|
else:
|
|
|
|
|
addMxServers.append(foundMxServer)
|
|
|
|
|
if not self.modMXRecord("@", zoneName, zoneName,
|
|
|
|
|
flagFoundMX, addMxServers):
|
|
|
|
|
return False
|
|
|
|
|
# Заменяем почтовые хосты
|
|
|
|
|
if mxServers:
|
|
|
|
|
# Проверка существования A записей для MX хостов
|
|
|
|
|
if not self.checkMXDomains(mxServers):
|
|
|
|
|
return False
|
|
|
|
|
if not self.modMXRecord("@", zoneName, zoneName,
|
|
|
|
|
flagFoundMX, mxServers):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('servers'):
|
|
|
|
|
namesServers = options['servers'].split(",")
|
|
|
|
|
flagErrorNs = False
|
|
|
|
@ -15893,8 +16199,8 @@ incorrect, use "--automod on" or "--automod off"')%autoMod)
|
|
|
|
|
requiredOpt = ["mxhost"]
|
|
|
|
|
optionalOpt = {"t":["mx"]}
|
|
|
|
|
typeRec = "mx"
|
|
|
|
|
elif "mxhosts" in optKeys:
|
|
|
|
|
requiredOpt = ["mxhosts"]
|
|
|
|
|
elif "mx" in optKeys:
|
|
|
|
|
requiredOpt = ["mx"]
|
|
|
|
|
optionalOpt = {"t":["mx"]}
|
|
|
|
|
typeRec = "mx"
|
|
|
|
|
elif "host" in optKeys:
|
|
|
|
@ -15948,20 +16254,20 @@ incorrect, use "--automod on" or "--automod off"')%autoMod)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
mxServers = []
|
|
|
|
|
if options.has_key('mxhosts'):
|
|
|
|
|
if options.has_key('mx'):
|
|
|
|
|
# Оключаем модификацию обратной зоны
|
|
|
|
|
modOther = False
|
|
|
|
|
# Почтовые серверы для доменного имени
|
|
|
|
|
if typeRec == "ptr":
|
|
|
|
|
self.printERROR(_('Command line options "--mxhosts" \
|
|
|
|
|
self.printERROR(_('Command line options "--mx" \
|
|
|
|
|
incompatible with PTR record (options "-t")'))
|
|
|
|
|
return False
|
|
|
|
|
if typeRec == "cname":
|
|
|
|
|
self.printERROR(_('Command line options "--mxhosts" \
|
|
|
|
|
self.printERROR(_('Command line options "--mx" \
|
|
|
|
|
incompatible with CNAME record (options "-t")'))
|
|
|
|
|
return False
|
|
|
|
|
mxServers=map(lambda x: delDot(x.lower()),
|
|
|
|
|
options['mxhosts'].split(","))
|
|
|
|
|
options['mx'].split(","))
|
|
|
|
|
mxServers = self._unicList(mxServers)
|
|
|
|
|
# Переименование mx записи
|
|
|
|
|
# modMxServers[0] - cтарая запись
|
|
|
|
@ -16968,15 +17274,25 @@ with type DNS record PTR (options "-t")'))
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def checkMXDomains(self, namesMailServers):
|
|
|
|
|
"""Проверяет каким MX хостам необходимы A записи"""
|
|
|
|
|
# MX записи для которых нужны A записи
|
|
|
|
|
mailServersInZones = filter(lambda x:\
|
|
|
|
|
def getNotFoundRecords(self, namesServers):
|
|
|
|
|
"""Находит серверы из списка которые должны быть созданы
|
|
|
|
|
|
|
|
|
|
Результат состоит из доменных имен удовлетворяющим этому правилу
|
|
|
|
|
(зона для доменного имени существует, доменного имени в ней нет)
|
|
|
|
|
"""
|
|
|
|
|
# Имена серверов которые могут находится в существующих зонах
|
|
|
|
|
serversInZones = filter(lambda x:\
|
|
|
|
|
self.searchZoneInLDAP(x.partition(".")[2]),\
|
|
|
|
|
namesMailServers)
|
|
|
|
|
notFoundMailServers = filter(lambda x:\
|
|
|
|
|
namesServers)
|
|
|
|
|
notFoundServers = filter(lambda x:\
|
|
|
|
|
not self.searchDomainNameInLDAP(x),\
|
|
|
|
|
mailServersInZones)
|
|
|
|
|
serversInZones)
|
|
|
|
|
return notFoundServers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def checkMXDomains(self, namesMailServers):
|
|
|
|
|
"""Проверяет каким MX хостам необходимы A записи"""
|
|
|
|
|
notFoundMailServers = self.getNotFoundRecords(namesMailServers)
|
|
|
|
|
if notFoundMailServers:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not found A records for MX records - %s")\
|
|
|
|
@ -17015,7 +17331,7 @@ with type DNS record PTR (options "-t")'))
|
|
|
|
|
('dNSClass', ['IN']),
|
|
|
|
|
('zoneName',[zoneName]),
|
|
|
|
|
('aRecord',[ipAddrOrHost])]
|
|
|
|
|
mxValues =map(lambda x: "%s %s" %(x*10+10, namesMailServersDot[x]),\
|
|
|
|
|
mxValues=map(lambda x: "%s %s" %(x*10+10, namesMailServersDot[x]),\
|
|
|
|
|
range(len(namesMailServersDot)))
|
|
|
|
|
if mxValues:
|
|
|
|
|
# Добавляем MX записи
|
|
|
|
@ -17097,7 +17413,7 @@ in LDAP")%zoneName)
|
|
|
|
|
def getAllowNet(self):
|
|
|
|
|
"""Получаем от пользователя доверительные сети
|
|
|
|
|
|
|
|
|
|
и устанавливаем переменную профилей sr_dns_net_allow
|
|
|
|
|
и устанавливаем переменную проф<EFBFBD>лей sr_dns_net_allow
|
|
|
|
|
|
|
|
|
|
self.clVars должен быть определен
|
|
|
|
|
"""
|
|
|
|
|