summaryrefslogtreecommitdiff
path: root/source4/scripting/python/samba/drs_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'source4/scripting/python/samba/drs_utils.py')
-rw-r--r--source4/scripting/python/samba/drs_utils.py110
1 files changed, 96 insertions, 14 deletions
diff --git a/source4/scripting/python/samba/drs_utils.py b/source4/scripting/python/samba/drs_utils.py
index 77f415ed17..481eec2920 100644
--- a/source4/scripting/python/samba/drs_utils.py
+++ b/source4/scripting/python/samba/drs_utils.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# DRS utility code
#
# Copyright Andrew Tridgell 2010
@@ -24,6 +22,90 @@ from samba.net import Net
import samba, ldb
+class drsException(Exception):
+ """Base element for drs errors"""
+
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return "drsException: " + self.value
+
+
+def drsuapi_connect(server, lp, creds):
+ """Make a DRSUAPI connection to the server.
+
+ :param server: the name of the server to connect to
+ :param lp: a samba line parameter object
+ :param creds: credential used for the connection
+ :return: A tuple with the drsuapi bind object, the drsuapi handle
+ and the supported extensions.
+ :raise drsException: if the connection fails
+ """
+
+ binding_options = "seal"
+ if int(lp.get("log level")) >= 5:
+ binding_options += ",print"
+ binding_string = "ncacn_ip_tcp:%s[%s]" % (server, binding_options)
+ try:
+ drsuapiBind = drsuapi.drsuapi(binding_string, lp, creds)
+ (drsuapiHandle, bindSupportedExtensions) = drs_DsBind(drsuapiBind)
+ except Exception, e:
+ raise drsException("DRS connection to %s failed: %s" % (server, e))
+
+ return (drsuapiBind, drsuapiHandle, bindSupportedExtensions)
+
+
+def sendDsReplicaSync(drsuapiBind, drsuapi_handle, source_dsa_guid,
+ naming_context, req_option):
+ """Send DS replica sync request.
+
+ :param drsuapiBind: a drsuapi Bind object
+ :param drsuapi_handle: a drsuapi hanle on the drsuapi connection
+ :param source_dsa_guid: the guid of the source dsa for the replication
+ :param naming_context: the DN of the naming context to replicate
+ :param req_options: replication options for the DsReplicaSync call
+ :raise drsException: if any error occur while sending and receiving the
+ reply for the dsReplicaSync
+ """
+
+ nc = drsuapi.DsReplicaObjectIdentifier()
+ nc.dn = naming_context
+
+ req1 = drsuapi.DsReplicaSyncRequest1()
+ req1.naming_context = nc;
+ req1.options = req_option
+ req1.source_dsa_guid = misc.GUID(source_dsa_guid)
+
+ try:
+ drsuapiBind.DsReplicaSync(drsuapi_handle, 1, req1)
+ except Exception, estr:
+ raise drsException("DsReplicaSync failed %s" % estr)
+
+
+def sendRemoveDsServer(drsuapiBind, drsuapi_handle, server_dsa_dn, domain):
+ """Send RemoveDSServer request.
+
+ :param drsuapiBind: a drsuapi Bind object
+ :param drsuapi_handle: a drsuapi hanle on the drsuapi connection
+ :param server_dsa_dn: a DN object of the server's dsa that we want to
+ demote
+ :param domain: a DN object of the server's domain
+ :raise drsException: if any error occur while sending and receiving the
+ reply for the DsRemoveDSServer
+ """
+
+ try:
+ req1 = drsuapi.DsRemoveDSServerRequest1()
+ req1.server_dn = str(server_dsa_dn)
+ req1.domain_dn = str(domain)
+ req1.commit = 1
+
+ drsuapiBind.DsRemoveDSServer(drsuapi_handle, 1, req1)
+ except Exception, estr:
+ raise drsException("DsRemoveDSServer failed %s" % estr)
+
+
def drs_DsBind(drs):
'''make a DsBind call, returning the binding handle'''
bind_info = drsuapi.DsBindInfoCtr()
@@ -62,7 +144,7 @@ def drs_DsBind(drs):
return (handle, info.info.supported_extensions)
-class drs_Replicate:
+class drs_Replicate(object):
'''DRS replication calls'''
def __init__(self, binding_string, lp, creds, samdb):
@@ -139,14 +221,14 @@ class drs_Replicate:
req8.replica_flags |= drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING
else:
req8.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP
- req8.max_object_count = 402
- req8.max_ndr_size = 402116
- req8.extended_op = exop
- req8.fsmo_info = 0
- req8.partial_attribute_set = None
- req8.partial_attribute_set_ex = None
- req8.mapping_ctr.num_mappings = 0
- req8.mapping_ctr.mappings = None
+ req8.max_object_count = 402
+ req8.max_ndr_size = 402116
+ req8.extended_op = exop
+ req8.fsmo_info = 0
+ req8.partial_attribute_set = None
+ req8.partial_attribute_set_ex = None
+ req8.mapping_ctr.num_mappings = 0
+ req8.mapping_ctr.mappings = None
if not schema and rodc:
req8.partial_attribute_set = self.drs_get_rodc_partial_attribute_set()
@@ -162,12 +244,12 @@ class drs_Replicate:
setattr(req5, a, getattr(req8, a))
req = req5
-
while True:
(level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level, req)
- if ctr.first_object == None and ctr.object_count != 0:
+ if ctr.first_object is None and ctr.object_count != 0:
raise RuntimeError("DsGetNCChanges: NULL first_object with object_count=%u" % (ctr.object_count))
- self.net.replicate_chunk(self.replication_state, level, ctr, schema=schema)
+ self.net.replicate_chunk(self.replication_state, level, ctr,
+ schema=schema, req_level=req_level, req=req)
if ctr.more_data == 0:
break
req.highwatermark.tmp_highest_usn = ctr.new_highwatermark.tmp_highest_usn