예제 #1
0
    def run(self, DEST_DC, SOURCE_DC, NC,
            add_ref=False, sync_forced=False, sync_all=False, full_sync=False,
            local=False, local_online=False, async_op=False, single_object=False,
            sambaopts=None, credopts=None, versionopts=None):

        self.server = DEST_DC
        self.lp = sambaopts.get_loadparm()

        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        if local:
            self.drs_local_replicate(SOURCE_DC, NC, full_sync=full_sync,
                                     single_object=single_object,
                                     sync_forced=sync_forced)
            return

        if local_online:
            server_bind = drsuapi.drsuapi("irpc:dreplsrv", lp_ctx=self.lp)
            server_bind_handle = misc.policy_handle()
        else:
            drsuapi_connect(self)
            server_bind = self.drsuapi
            server_bind_handle = self.drsuapi_handle

        if not async_op:
            # Give the sync replication 5 minutes time
            server_bind.request_timeout = 5 * 60

        samdb_connect(self)

        # we need to find the NTDS GUID of the source DC
        msg = self.samdb.search(base=self.samdb.get_config_basedn(),
                                expression="(&(objectCategory=server)(|(name=%s)(dNSHostName=%s)))" % (
            ldb.binary_encode(SOURCE_DC),
            ldb.binary_encode(SOURCE_DC)),
                                attrs=[])
        if len(msg) == 0:
            raise CommandError("Failed to find source DC %s" % SOURCE_DC)
        server_dn = msg[0]['dn']

        msg = self.samdb.search(base=server_dn, scope=ldb.SCOPE_ONELEVEL,
                                expression="(|(objectCategory=nTDSDSA)(objectCategory=nTDSDSARO))",
                                attrs=['objectGUID', 'options'])
        if len(msg) == 0:
            raise CommandError("Failed to find source NTDS DN %s" % SOURCE_DC)
        source_dsa_guid = msg[0]['objectGUID'][0]
        dsa_options = int(attr_default(msg, 'options', 0))


        req_options = 0
        if not (dsa_options & dsdb.DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL):
            req_options |= drsuapi.DRSUAPI_DRS_WRIT_REP
        if add_ref:
            req_options |= drsuapi.DRSUAPI_DRS_ADD_REF
        if sync_forced:
            req_options |= drsuapi.DRSUAPI_DRS_SYNC_FORCED
        if sync_all:
            req_options |= drsuapi.DRSUAPI_DRS_SYNC_ALL
        if full_sync:
            req_options |= drsuapi.DRSUAPI_DRS_FULL_SYNC_NOW
        if async_op:
            req_options |= drsuapi.DRSUAPI_DRS_ASYNC_OP

        try:
            drs_utils.sendDsReplicaSync(server_bind, server_bind_handle, source_dsa_guid, NC, req_options)
        except drs_utils.drsException as estr:
            raise CommandError("DsReplicaSync failed", estr)
        if async_op:
            self.message("Replicate from %s to %s was started." % (SOURCE_DC, DEST_DC))
        else:
            self.message("Replicate from %s to %s was successful." % (SOURCE_DC, DEST_DC))
예제 #2
0
파일: domain.py 프로젝트: sprymak/samba
    def run(self, sambaopts=None, credopts=None,
            versionopts=None, server=None, targetdir=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        net = Net(creds, lp, server=credopts.ipaddress)

        netbios_name = lp.get("netbios name")
        samdb = SamDB(session_info=system_session(), credentials=creds, lp=lp)
        if not server:
            res = samdb.search(expression='(&(objectClass=computer)(serverReferenceBL=*))', attrs=["dnsHostName", "name"])
            if (len(res) == 0):
                raise CommandError("Unable to search for servers")

            if (len(res) == 1):
                raise CommandError("You are the latest server in the domain")

            server = None
            for e in res:
                if str(e["name"]).lower() != netbios_name.lower():
                    server = e["dnsHostName"]
                    break

        ntds_guid = samdb.get_ntds_GUID()
        msg = samdb.search(base=str(samdb.get_config_basedn()), scope=ldb.SCOPE_SUBTREE,
                                expression="(objectGUID=%s)" % ntds_guid,
                                attrs=['options'])
        if len(msg) == 0 or "options" not in msg[0]:
            raise CommandError("Failed to find options on %s" % ntds_guid)

        ntds_dn = msg[0].dn
        dsa_options = int(str(msg[0]['options']))

        res = samdb.search(expression="(fSMORoleOwner=%s)" % str(ntds_dn),
                            controls=["search_options:1:2"])

        if len(res) != 0:
            raise CommandError("Current DC is still the owner of %d role(s), use the role command to transfer roles to another DC" % len(res))

        print "Using %s as partner server for the demotion" % server
        (drsuapiBind, drsuapi_handle, supportedExtensions) = drsuapi_connect(server, lp, creds)

        print "Desactivating inbound replication"

        nmsg = ldb.Message()
        nmsg.dn = msg[0].dn

        dsa_options |= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
        nmsg["options"] = ldb.MessageElement(str(dsa_options), ldb.FLAG_MOD_REPLACE, "options")
        samdb.modify(nmsg)

        if not (dsa_options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) and not samdb.am_rodc():

            print "Asking partner server %s to synchronize from us" % server
            for part in (samdb.get_schema_basedn(),
                            samdb.get_config_basedn(),
                            samdb.get_root_basedn()):
                try:
                    sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid, str(part), drsuapi.DRSUAPI_DRS_WRIT_REP)
                except drsException, e:
                    print "Error while demoting, re-enabling inbound replication"
                    dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
                    nmsg["options"] = ldb.MessageElement(str(dsa_options), ldb.FLAG_MOD_REPLACE, "options")
                    samdb.modify(nmsg)
                    raise CommandError("Error while sending a DsReplicaSync for partion %s" % str(part), e)
예제 #3
0
파일: domain.py 프로젝트: cpatulea/samba
    def run(self,
            sambaopts=None,
            credopts=None,
            versionopts=None,
            server=None,
            targetdir=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        net = Net(creds, lp, server=credopts.ipaddress)

        netbios_name = lp.get("netbios name")
        samdb = SamDB(session_info=system_session(), credentials=creds, lp=lp)
        if not server:
            res = samdb.search(
                expression='(&(objectClass=computer)(serverReferenceBL=*))',
                attrs=["dnsHostName", "name"])
            if (len(res) == 0):
                raise CommandError("Unable to search for servers")

            if (len(res) == 1):
                raise CommandError("You are the latest server in the domain")

            server = None
            for e in res:
                if str(e["name"]).lower() != netbios_name.lower():
                    server = e["dnsHostName"]
                    break

        ntds_guid = samdb.get_ntds_GUID()
        msg = samdb.search(base=str(samdb.get_config_basedn()),
                           scope=ldb.SCOPE_SUBTREE,
                           expression="(objectGUID=%s)" % ntds_guid,
                           attrs=['options'])
        if len(msg) == 0 or "options" not in msg[0]:
            raise CommandError("Failed to find options on %s" % ntds_guid)

        ntds_dn = msg[0].dn
        dsa_options = int(str(msg[0]['options']))

        res = samdb.search(expression="(fSMORoleOwner=%s)" % str(ntds_dn),
                           controls=["search_options:1:2"])

        if len(res) != 0:
            raise CommandError(
                "Current DC is still the owner of %d role(s), use the role command to transfer roles to another DC"
            )

        print "Using %s as partner server for the demotion" % server
        (drsuapiBind, drsuapi_handle,
         supportedExtensions) = drsuapi_connect(server, lp, creds)

        print "Desactivating inbound replication"

        nmsg = ldb.Message()
        nmsg.dn = msg[0].dn

        dsa_options |= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
        nmsg["options"] = ldb.MessageElement(str(dsa_options),
                                             ldb.FLAG_MOD_REPLACE, "options")
        samdb.modify(nmsg)

        if not (dsa_options &
                DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) and not samdb.am_rodc():

            print "Asking partner server %s to synchronize from us" % server
            for part in (samdb.get_schema_basedn(), samdb.get_config_basedn(),
                         samdb.get_root_basedn()):
                try:
                    sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid,
                                      str(part), drsuapi.DRSUAPI_DRS_WRIT_REP)
                except drsException, e:
                    print "Error while demoting, re-enabling inbound replication"
                    dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
                    nmsg["options"] = ldb.MessageElement(
                        str(dsa_options), ldb.FLAG_MOD_REPLACE, "options")
                    samdb.modify(nmsg)
                    raise CommandError(
                        "Error while sending a DsReplicaSync for partion %s" %
                        str(part), e)