[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Thu Feb 23 14:31:02 UTC 2017
The branch, master has been updated
via 646917e repl_meta_data: Clarify that replmd_private->la_list is only for DRS for replication
via 7ed6111 samba-tool drs replicate: Add --single-object
via e2ba17d python: Move partial replication logic into drs_utils.py
via 4aaae03 python: Move dnsserver helper functions into samba.dnsserver
from f0196b2 coverity: Add modeling file for Coverity scan
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 646917ec078de25bcc9d68f7dc966eefed44353f
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Feb 23 11:02:07 2017 +1300
repl_meta_data: Clarify that replmd_private->la_list is only for DRS for replication
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Thu Feb 23 15:30:35 CET 2017 on sn-devel-144
commit 7ed611143f281ecf15f69d260fd9042c443e10da
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Feb 23 13:00:19 2017 +1300
samba-tool drs replicate: Add --single-object
This may help when an object has been incorrectly locally removed from the NC
or there is an urgent need to replicate a specific object (say when full
replication is inoperable).
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit e2ba17d26af42974e5d389a3706a45fd00185875
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Feb 17 18:22:19 2017 +1300
python: Move partial replication logic into drs_utils.py
This allows us to use this easily from join.py soon
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit 4aaae038b7b41459e369700bd2196ed40dbbc4c7
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Feb 17 18:21:33 2017 +1300
python: Move dnsserver helper functions into samba.dnsserver
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
python/samba/dnsserver.py | 181 ++++++++++++++++++++++++
python/samba/drs_utils.py | 48 +++++--
python/samba/netcmd/dns.py | 162 +--------------------
python/samba/netcmd/drs.py | 47 ++----
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 +-
source4/libnet/libnet_vampire.c | 6 +-
6 files changed, 240 insertions(+), 212 deletions(-)
create mode 100644 python/samba/dnsserver.py
Changeset truncated at 500 lines:
diff --git a/python/samba/dnsserver.py b/python/samba/dnsserver.py
new file mode 100644
index 0000000..1c9f3bc
--- /dev/null
+++ b/python/samba/dnsserver.py
@@ -0,0 +1,181 @@
+# helper for DNS management tool
+#
+# Copyright (C) Amitay Isaacs 2011-2012
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+from samba.dcerpc import dnsserver, dnsp
+
+#
+# Always create a copy of strings when creating DNS_RPC_RECORDs
+# to overcome the bug in pidl generated python bindings.
+#
+
+class ARecord(dnsserver.DNS_RPC_RECORD):
+ def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(ARecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_A
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._ip_addr = ip_addr[:]
+ self.data = self._ip_addr
+
+
+class AAAARecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, ip6_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(AAAARecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_AAAA
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._ip6_addr = ip6_addr[:]
+ self.data = self._ip6_addr
+
+
+class PTRRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, ptr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(PTRRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_PTR
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._ptr = ptr[:]
+ ptr_name = dnsserver.DNS_RPC_NAME()
+ ptr_name.str = self._ptr
+ ptr_name.len = len(ptr)
+ self.data = ptr_name
+
+
+class CNameRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, cname, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(CNameRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_CNAME
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._cname = cname[:]
+ cname_name = dnsserver.DNS_RPC_NAME()
+ cname_name.str = self._cname
+ cname_name.len = len(cname)
+ self.data = cname_name
+
+
+class NSRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, dns_server, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(NSRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_NS
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._dns_server = dns_server[:]
+ ns = dnsserver.DNS_RPC_NAME()
+ ns.str = self._dns_server
+ ns.len = len(dns_server)
+ self.data = ns
+
+
+class MXRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, mail_server, preference, serial=1, ttl=900,
+ rank=dnsp.DNS_RANK_ZONE, node_flag=0):
+ super(MXRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_MX
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._mail_server = mail_server[:]
+ mx = dnsserver.DNS_RPC_RECORD_NAME_PREFERENCE()
+ mx.wPreference = preference
+ mx.nameExchange.str = self._mail_server
+ mx.nameExchange.len = len(mail_server)
+ self.data = mx
+
+
+class SOARecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, mname, rname, serial=1, refresh=900, retry=600,
+ expire=86400, minimum=3600, ttl=3600, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=dnsp.DNS_RPC_FLAG_AUTH_ZONE_ROOT):
+ super(SOARecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_SOA
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._mname = mname[:]
+ self._rname = rname[:]
+ soa = dnsserver.DNS_RPC_RECORD_SOA()
+ soa.dwSerialNo = serial
+ soa.dwRefresh = refresh
+ soa.dwRetry = retry
+ soa.dwExpire = expire
+ soa.dwMinimumTtl = minimum
+ soa.NamePrimaryServer.str = self._mname
+ soa.NamePrimaryServer.len = len(mname)
+ soa.ZoneAdministratorEmail.str = self._rname
+ soa.ZoneAdministratorEmail.len = len(rname)
+ self.data = soa
+
+
+class SRVRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, target, port, priority=0, weight=100, serial=1, ttl=900,
+ rank=dnsp.DNS_RANK_ZONE, node_flag=0):
+ super(SRVRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_SRV
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._target = target[:]
+ srv = dnsserver.DNS_RPC_RECORD_SRV()
+ srv.wPriority = priority
+ srv.wWeight = weight
+ srv.wPort = port
+ srv.nameTarget.str = self._target
+ srv.nameTarget.len = len(target)
+ self.data = srv
+
+
+class TXTRecord(dnsserver.DNS_RPC_RECORD):
+
+ def __init__(self, slist, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
+ node_flag=0):
+ super(TXTRecord, self).__init__()
+ self.wType = dnsp.DNS_TYPE_TXT
+ self.dwFlags = rank | node_flag
+ self.dwSerial = serial
+ self.dwTtlSeconds = ttl
+ self._slist = []
+ for s in slist:
+ self._slist.append(s[:])
+ names = []
+ for s in self._slist:
+ name = dnsserver.DNS_RPC_NAME()
+ name.str = s
+ name.len = len(s)
+ names.append(name)
+ txt = dnsserver.DNS_RPC_RECORD_STRING()
+ txt.count = len(slist)
+ txt.str = names
+ self.data = txt
diff --git a/python/samba/drs_utils.py b/python/samba/drs_utils.py
index e91a20b..8624f3f 100644
--- a/python/samba/drs_utils.py
+++ b/python/samba/drs_utils.py
@@ -17,8 +17,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-from samba.dcerpc import drsuapi, misc
+from samba.dcerpc import drsuapi, misc, drsblobs
from samba.net import Net
+from samba.ndr import ndr_unpack
+from samba import dsdb
import samba, ldb
@@ -198,7 +200,7 @@ class drs_Replicate(object):
def replicate(self, dn, source_dsa_invocation_id, destination_dsa_guid,
schema=False, exop=drsuapi.DRSUAPI_EXOP_NONE, rodc=False,
- replica_flags=None, highwatermark=None, udv=None):
+ replica_flags=None, full_sync=True):
'''replicate a single DN'''
# setup for a GetNCChanges call
@@ -209,14 +211,40 @@ class drs_Replicate(object):
req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
req8.naming_context.dn = dn
- if highwatermark is not None:
- req8.highwatermark = highwatermark
- else:
- req8.highwatermark = drsuapi.DsReplicaHighWaterMark()
- req8.highwatermark.tmp_highest_usn = 0
- req8.highwatermark.reserved_usn = 0
- req8.highwatermark.highest_usn = 0
-
+ udv = None
+ if not full_sync:
+ res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE,
+ attrs=["repsFrom"])
+ if "repsFrom" in res[0]:
+ for reps_from_packed in res[0]["repsFrom"]:
+ reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob, reps_from_packed)
+ if reps_from_obj.ctr.source_dsa_invocation_id == source_dsa_invocation_id:
+ hwm = reps_from_obj.ctr.highwatermark
+
+ udv = drsuapi.DsReplicaCursorCtrEx()
+ udv.version = 1
+ udv.reserved1 = 0
+ udv.reserved2 = 0
+
+ cursors_v1 = []
+ cursors_v2 = dsdb._dsdb_load_udv_v2(self.samdb,
+ self.samdb.get_default_basedn())
+ for cursor_v2 in cursors_v2:
+ cursor_v1 = drsuapi.DsReplicaCursor()
+ cursor_v1.source_dsa_invocation_id = cursor_v2.source_dsa_invocation_id
+ cursor_v1.highest_usn = cursor_v2.highest_usn
+ cursors_v1.append(cursor_v1)
+
+ udv.cursors = cursors_v1
+ udv.count = len(cursors_v1)
+
+ # If we can't find an upToDateVector, or where told not to, replicate fully
+ hwm = drsuapi.DsReplicaHighWaterMark()
+ hwm.tmp_highest_usn = 0
+ hwm.reserved_usn = 0
+ hwm.highest_usn = 0
+
+ req8.highwatermark = hwm
req8.uptodateness_vector = udv
if replica_flags is not None:
diff --git a/python/samba/netcmd/dns.py b/python/samba/netcmd/dns.py
index caacb0a..6f88817 100644
--- a/python/samba/netcmd/dns.py
+++ b/python/samba/netcmd/dns.py
@@ -34,6 +34,7 @@ from samba.netcmd import (
)
from samba.dcerpc import dnsp, dnsserver
+from samba.dnsserver import ARecord, AAAARecord, PTRRecord, CNameRecord, NSRecord, MXRecord, SOARecord, SRVRecord, TXTRecord
def dns_connect(server, lp, creds):
if server.lower() == 'localhost':
@@ -396,167 +397,6 @@ def print_dnsrecords(outf, records):
print_dns_record(outf, dns_rec)
-#
-# Always create a copy of strings when creating DNS_RPC_RECORDs
-# to overcome the bug in pidl generated python bindings.
-#
-
-class ARecord(dnsserver.DNS_RPC_RECORD):
- def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(ARecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_A
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._ip_addr = ip_addr[:]
- self.data = self._ip_addr
-
-
-class AAAARecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, ip6_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(AAAARecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_AAAA
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._ip6_addr = ip6_addr[:]
- self.data = self._ip6_addr
-
-
-class PTRRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, ptr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(PTRRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_PTR
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._ptr = ptr[:]
- ptr_name = dnsserver.DNS_RPC_NAME()
- ptr_name.str = self._ptr
- ptr_name.len = len(ptr)
- self.data = ptr_name
-
-
-class CNameRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, cname, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(CNameRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_CNAME
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._cname = cname[:]
- cname_name = dnsserver.DNS_RPC_NAME()
- cname_name.str = self._cname
- cname_name.len = len(cname)
- self.data = cname_name
-
-
-class NSRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, dns_server, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(NSRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_NS
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._dns_server = dns_server[:]
- ns = dnsserver.DNS_RPC_NAME()
- ns.str = self._dns_server
- ns.len = len(dns_server)
- self.data = ns
-
-
-class MXRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, mail_server, preference, serial=1, ttl=900,
- rank=dnsp.DNS_RANK_ZONE, node_flag=0):
- super(MXRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_MX
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._mail_server = mail_server[:]
- mx = dnsserver.DNS_RPC_RECORD_NAME_PREFERENCE()
- mx.wPreference = preference
- mx.nameExchange.str = self._mail_server
- mx.nameExchange.len = len(mail_server)
- self.data = mx
-
-
-class SOARecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, mname, rname, serial=1, refresh=900, retry=600,
- expire=86400, minimum=3600, ttl=3600, rank=dnsp.DNS_RANK_ZONE,
- node_flag=dnsp.DNS_RPC_FLAG_AUTH_ZONE_ROOT):
- super(SOARecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_SOA
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._mname = mname[:]
- self._rname = rname[:]
- soa = dnsserver.DNS_RPC_RECORD_SOA()
- soa.dwSerialNo = serial
- soa.dwRefresh = refresh
- soa.dwRetry = retry
- soa.dwExpire = expire
- soa.dwMinimumTtl = minimum
- soa.NamePrimaryServer.str = self._mname
- soa.NamePrimaryServer.len = len(mname)
- soa.ZoneAdministratorEmail.str = self._rname
- soa.ZoneAdministratorEmail.len = len(rname)
- self.data = soa
-
-
-class SRVRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, target, port, priority=0, weight=100, serial=1, ttl=900,
- rank=dnsp.DNS_RANK_ZONE, node_flag=0):
- super(SRVRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_SRV
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._target = target[:]
- srv = dnsserver.DNS_RPC_RECORD_SRV()
- srv.wPriority = priority
- srv.wWeight = weight
- srv.wPort = port
- srv.nameTarget.str = self._target
- srv.nameTarget.len = len(target)
- self.data = srv
-
-
-class TXTRecord(dnsserver.DNS_RPC_RECORD):
-
- def __init__(self, slist, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
- node_flag=0):
- super(TXTRecord, self).__init__()
- self.wType = dnsp.DNS_TYPE_TXT
- self.dwFlags = rank | node_flag
- self.dwSerial = serial
- self.dwTtlSeconds = ttl
- self._slist = []
- for s in slist:
- self._slist.append(s[:])
- names = []
- for s in self._slist:
- name = dnsserver.DNS_RPC_NAME()
- name.str = s
- name.len = len(s)
- names.append(name)
- txt = dnsserver.DNS_RPC_RECORD_STRING()
- txt.count = len(slist)
- txt.str = names
- self.data = txt
# Convert data into a dns record
diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py
index bf6829e..b9b876a 100644
--- a/python/samba/netcmd/drs.py
+++ b/python/samba/netcmd/drs.py
@@ -241,7 +241,7 @@ class cmd_drs_kcc(Command):
-def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
+def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False, single_object=False):
'''replicate from a source DC to the local SAM'''
self.server = SOURCE_DC
@@ -267,38 +267,11 @@ def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
dest_dsa_invocation_id = misc.GUID(self.local_samdb.get_invocation_id())
destination_dsa_guid = self.ntds_guid
- # If we can't find an upToDateVector, replicate fully
- hwm = drsuapi.DsReplicaHighWaterMark()
- hwm.tmp_highest_usn = 0
- hwm.reserved_usn = 0
- hwm.highest_usn = 0
-
- udv = None
- if not full_sync:
- res = self.local_samdb.search(base=NC, scope=ldb.SCOPE_BASE,
- attrs=["repsFrom"])
- if "repsFrom" in res[0]:
- for reps_from_packed in res[0]["repsFrom"]:
- reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob, reps_from_packed)
- if reps_from_obj.ctr.source_dsa_invocation_id == source_dsa_invocation_id:
- hwm = reps_from_obj.ctr.highwatermark
-
- udv = drsuapi.DsReplicaCursorCtrEx()
- udv.version = 1
- udv.reserved1 = 0
- udv.reserved2 = 0
-
- cursors_v1 = []
- cursors_v2 = dsdb._dsdb_load_udv_v2(self.local_samdb,
- self.local_samdb.get_default_basedn())
- for cursor_v2 in cursors_v2:
- cursor_v1 = drsuapi.DsReplicaCursor()
- cursor_v1.source_dsa_invocation_id = cursor_v2.source_dsa_invocation_id
- cursor_v1.highest_usn = cursor_v2.highest_usn
- cursors_v1.append(cursor_v1)
-
- udv.cursors = cursors_v1
- udv.count = len(cursors_v1)
+ exop = drsuapi.DRSUAPI_EXOP_NONE
+
+ if single_object:
+ exop = drsuapi.DRSUAPI_EXOP_REPL_OBJ
+ full_sync = True
self.samdb.transaction_start()
repl = drs_utils.drs_Replicate("ncacn_ip_tcp:%s[seal]" % self.server, self.lp,
@@ -310,7 +283,8 @@ def drs_local_replicate(self, SOURCE_DC, NC, full_sync=False):
try:
--
Samba Shared Repository
More information about the samba-cvs
mailing list