[SCM] Samba Shared Repository - branch master updated
Andrew Tridgell
tridge at samba.org
Wed Dec 7 19:24:03 MST 2011
The branch, master has been updated
via 86338ab dbcheck: cope with objects disappearing during checking
via 819f112 samba_kcc NTDSConnection translation
via 0a4746a Invocation of samba_kcc from KCC task
via 0a18121 Add subreq and status to kcc_service struct
via b58cb7e Add DRSUAPI_DRS_UPDATE_(x) flags
via bc03cba Add NTDSConnection schedule attr blob
via a3613b0 Add samba_kcc load parameter
from fbfd155 Add version attribute for pytevent.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 86338ab551baf7c5dc4f63a1a103880e886acf69
Author: Andrew Tridgell <tridge at samba.org>
Date: Thu Dec 8 11:47:59 2011 +1100
dbcheck: cope with objects disappearing during checking
Autobuild-User: Andrew Tridgell <tridge at samba.org>
Autobuild-Date: Thu Dec 8 03:23:49 CET 2011 on sn-devel-104
commit 819f11285d12041f2a22a6c92ebabb8a559886c5
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 11:08:56 2011 -0600
samba_kcc NTDSConnection translation
This is an advancement of samba_kcc to compute and
commit the modification of a repsFrom on an NC Replica.
The repsFrom is computed according to the MS tech spec
for implied replicas of NTDSConnections. Proper maintenance
of (DRS options, schedules, etc) from a NTDSConnection are now
all present. New classes for inter-site transports, sites,
and repsFrom) are now present in kcc_utils.py. Substantively
this gets intra-site topology generation functional by committing
the repsFrom that were computed from the DSA graph implemented in
prior drops of samba_kcc
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit 0a4746a20085a21bd8f28faf13bc5168f3ad5afb
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 11:06:47 2011 -0600
Invocation of samba_kcc from KCC task
Modification to periodic and explicit invocation
paths of the KCC topology generation code. Managed
via samba_runcmd_send() API. The samba_kcc script
is invoked if (kccsrv:samba_kcc = true) appears in smb.conf
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit 0a181217bdf7e59a7e1f5506c8e050f67537f7f1
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 11:04:49 2011 -0600
Add subreq and status to kcc_service struct
The subreq and status fields in the kcc_service struct
are added for execution management of the external samba_kcc
python script.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit b58cb7ea932068982233e49c6e03be6a631f80da
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 11:01:54 2011 -0600
Add DRSUAPI_DRS_UPDATE_(x) flags
DRSUAPI_DRS_UPDATE flags are used in
DRS_MSG_REPMOD_V1 message structure when repsFrom
is modified via RPC. The RPCs are currently uncoded but
samba_kcc maintains the flags (and uses them to identify
what repsFrom changes are to be executed). These are currently
helpful to samba_kcc and are intended to ultimately be used in
RPCs.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit bc03cba552b512ef436ff7da3bd0820c6341d783
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 11:00:31 2011 -0600
Add NTDSConnection schedule attr blob
Add schedule blob to drsblobs to allow
NDR unpacking into a python class.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit a3613b05339ea305edfdc54a02ca65506f48c356
Author: Dave Craft <wimberosa at gmail.com>
Date: Sun Dec 4 10:58:16 2011 -0600
Add samba_kcc load parameter
Configures parameter to enumerate name of python KCC
topology generator for subsequent use by samba_runcmd_send()
invocation from kcc task
Signed-off-by: Andrew Tridgell <tridge at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/param/loadparm.c | 11 +
librpc/idl/drsblobs.idl | 20 +
librpc/idl/drsuapi.idl | 7 +
source4/dsdb/kcc/kcc_periodic.c | 72 ++-
source4/dsdb/kcc/kcc_service.c | 36 +-
source4/dsdb/kcc/kcc_service.h | 11 +-
source4/dsdb/wscript_build | 2 +-
source4/scripting/bin/samba_kcc | 720 +++++++++++++++++---
source4/scripting/python/samba/dbchecker.py | 20 +-
source4/scripting/python/samba/kcc_utils.py | 790 +++++++++++++++++++---
source4/scripting/python/samba/netcmd/dbcheck.py | 2 +-
11 files changed, 1444 insertions(+), 247 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 9abd11f..48b5221 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -1208,6 +1208,14 @@ static struct parm_struct parm_table[] = {
.enum_list = NULL
},
{
+ .label = "samba kcc command",
+ .type = P_CMDLIST,
+ .p_class = P_GLOBAL,
+ .offset = GLOBAL_VAR(szSambaKCCCommand),
+ .special = NULL,
+ .enum_list = NULL
+ },
+ {
.label = "nsupdate command",
.type = P_CMDLIST,
.p_class = P_GLOBAL,
@@ -1439,6 +1447,7 @@ FN_GLOBAL_STRING(piddir, szPidDir)
FN_GLOBAL_LIST(rndc_command, szRNDCCommand)
FN_GLOBAL_LIST(dns_update_command, szDNSUpdateCommand)
FN_GLOBAL_LIST(spn_update_command, szSPNUpdateCommand)
+FN_GLOBAL_LIST(samba_kcc_command, szSambaKCCCommand)
FN_GLOBAL_LIST(nsupdate_command, szNSUpdateCommand)
FN_GLOBAL_LIST(dcerpc_endpoint_servers, dcerpc_ep_servers)
FN_GLOBAL_LIST(server_services, server_services)
@@ -3325,6 +3334,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
+ lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
+ "%s/samba_kcc", dyn_SCRIPTSBINDIR);
#endif
lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
diff --git a/librpc/idl/drsblobs.idl b/librpc/idl/drsblobs.idl
index 064f6ea..1960716 100644
--- a/librpc/idl/drsblobs.idl
+++ b/librpc/idl/drsblobs.idl
@@ -151,6 +151,26 @@ interface drsblobs {
[in] repsFromToBlob blob
);
+ /* Replication schedule structures as defined in MS-ADTS 7.1.4.5
+ * Appears as attribute of NTDSConnection object
+ */
+ typedef [public] struct {
+ [value(0)] uint32 type; /* always 0 */
+ uint32 offset;
+ } scheduleHeader;
+
+ typedef [public] struct {
+ uint8 slots[168];
+ } scheduleSlots;
+
+ typedef [public] struct {
+ uint32 size;
+ [value(0)] uint32 bandwidth; /* ignored */
+ [value(1)] uint32 numberOfSchedules; /* always 1 */
+ scheduleHeader headerArray[numberOfSchedules];
+ scheduleSlots dataArray[numberOfSchedules];
+ } schedule;
+
/*
* partialAttributeSet
* w2k uses version 1
diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
index f0c8490..af7e3ed 100644
--- a/librpc/idl/drsuapi.idl
+++ b/librpc/idl/drsuapi.idl
@@ -58,6 +58,13 @@ interface drsuapi
DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000
} drsuapi_DrsOptions;
+ /* see DRS_MSG_REPMOD_V1 */
+ typedef [public,bitmap32bit] bitmap {
+ DRSUAPI_DRS_UPDATE_FLAGS = 0x00000001,
+ DRSUAPI_DRS_UPDATE_ADDRESS = 0x00000002,
+ DRSUAPI_DRS_UPDATE_SCHEDULE = 0x00000004
+ } drsuapi_DrsUpdate;
+
/*****************/
/* Function 0x00 */
typedef [bitmap32bit] bitmap {
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c
index d9a716f..f4374d2 100644
--- a/source4/dsdb/kcc/kcc_periodic.c
+++ b/source4/dsdb/kcc/kcc_periodic.c
@@ -588,12 +588,17 @@ static void kccsrv_periodic_run(struct kccsrv_service *service)
TALLOC_CTX *mem_ctx;
NTSTATUS status;
- DEBUG(4,("kccsrv_periodic_run(): simple update\n"));
+ DEBUG(4,("kccsrv_periodic_run(): update\n"));
mem_ctx = talloc_new(service);
- status = kccsrv_simple_update(service, mem_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status)));
+
+ if (service->samba_kcc_code)
+ status = kccsrv_samba_kcc(service, mem_ctx);
+ else {
+ status = kccsrv_simple_update(service, mem_ctx);
+ if (!NT_STATUS_IS_OK(status))
+ DEBUG(0,("kccsrv_simple_update failed - %s\n",
+ nt_errstr(status)));
}
status = kccsrv_check_deleted(service, mem_ctx);
@@ -602,3 +607,62 @@ static void kccsrv_periodic_run(struct kccsrv_service *service)
}
talloc_free(mem_ctx);
}
+
+/* Called when samba_kcc script has finished
+ */
+static void samba_kcc_done(struct tevent_req *subreq)
+{
+ struct kccsrv_service *service =
+ tevent_req_callback_data(subreq, struct kccsrv_service);
+ int rc;
+ int sys_errno;
+
+ service->periodic.subreq = NULL;
+
+ rc = samba_runcmd_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+
+ if (rc != 0)
+ service->periodic.status =
+ map_nt_error_from_unix_common(sys_errno);
+ else
+ service->periodic.status = NT_STATUS_OK;
+
+ if (!NT_STATUS_IS_OK(service->periodic.status))
+ DEBUG(0,(__location__ ": Failed samba_kcc - %s\n",
+ nt_errstr(service->periodic.status)));
+ else
+ DEBUG(3,("Completed samba_kcc OK\n"));
+}
+
+/* Invocation of the samba_kcc python script for replication
+ * topology generation.
+ */
+NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service,
+ TALLOC_CTX *ctxp)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ const char * const *samba_kcc_command =
+ lpcfg_samba_kcc_command(service->task->lp_ctx);
+
+ /* kill any existing child */
+ TALLOC_FREE(service->periodic.subreq);
+
+ DEBUG(0,("Calling samba_kcc script\n"));
+ service->periodic.subreq = samba_runcmd_send(service,
+ service->task->event_ctx,
+ timeval_current_ofs(40, 0),
+ 2, 0, samba_kcc_command, NULL);
+
+ if (service->periodic.subreq == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto xerror;
+ }
+ tevent_req_set_callback(service->periodic.subreq,
+ samba_kcc_done, service);
+
+xerror:
+ if (!NT_STATUS_IS_OK(status))
+ DEBUG(0,(__location__ ": failed - %s\n", nt_errstr(status)));
+ return status;
+}
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index 5f7b537..ac19522 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -144,16 +144,18 @@ static WERROR kccsrv_load_partitions(struct kccsrv_service *s)
static NTSTATUS kccsrv_execute_kcc(struct irpc_message *msg, struct drsuapi_DsExecuteKCC *r)
{
TALLOC_CTX *mem_ctx;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
struct kccsrv_service *service = talloc_get_type(msg->private_data, struct kccsrv_service);
mem_ctx = talloc_new(service);
- status = kccsrv_simple_update(service, mem_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status)));
- talloc_free(mem_ctx);
- return status;
+ if (service->samba_kcc_code)
+ status = kccsrv_samba_kcc(service, mem_ctx);
+ else {
+ status = kccsrv_simple_update(service, mem_ctx);
+ if (!NT_STATUS_IS_OK(status))
+ DEBUG(0,("kccsrv_execute_kcc failed - %s\n",
+ nt_errstr(status)));
}
talloc_free(mem_ctx);
@@ -222,10 +224,18 @@ static void kccsrv_task_init(struct task_server *task)
return;
}
- periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
- "periodic_startup_interval", 15); /* in seconds */
- service->periodic.interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
- "periodic_interval", 300); /* in seconds */
+ periodic_startup_interval =
+ lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
+ "periodic_startup_interval", 15); /* in seconds */
+ service->periodic.interval =
+ lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv",
+ "periodic_interval", 300); /* in seconds */
+
+ /* (kccsrv:samba_kcc=true) will run newer samba_kcc replication
+ * topology generation code.
+ */
+ service->samba_kcc_code = lpcfg_parm_bool(task->lp_ctx, NULL,
+ "kccsrv", "samba_kcc", false);
status = kccsrv_periodic_schedule(service, periodic_startup_interval);
if (!W_ERROR_IS_OK(status)) {
@@ -235,12 +245,6 @@ static void kccsrv_task_init(struct task_server *task)
return;
}
- /* (kccsrv:intrasite=true) will run newer intrasite replication
- * topology code.
- */
- service->intrasite_code = lpcfg_parm_bool(task->lp_ctx, NULL, "kccsrv",
- "intrasite", false);
-
irpc_add_name(task->msg_ctx, "kccsrv");
IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service);
diff --git a/source4/dsdb/kcc/kcc_service.h b/source4/dsdb/kcc/kcc_service.h
index 1404a9a..1e6d35e 100644
--- a/source4/dsdb/kcc/kcc_service.h
+++ b/source4/dsdb/kcc/kcc_service.h
@@ -77,14 +77,21 @@ struct kccsrv_service {
/* here we have a reference to the timed event the schedules the periodic stuff */
struct tevent_timer *te;
+
+ /* samba_runcmd_send service for samba_kcc */
+ struct tevent_req *subreq;
+
+ /* return status of samba_kcc */
+ NTSTATUS status;
+
} periodic;
time_t last_deleted_check;
bool am_rodc;
- /* run new intra-site topology code */
- bool intrasite_code;
+ /* run new samba_kcc topology generator code */
+ bool samba_kcc_code;
};
struct kcc_connection_list;
diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build
index 7645ae7..0eb4eeb 100644
--- a/source4/dsdb/wscript_build
+++ b/source4/dsdb/wscript_build
@@ -43,7 +43,7 @@ bld.SAMBA_MODULE('service_kcc',
autoproto='kcc/kcc_service_proto.h',
subsystem='service',
init_function='server_service_kcc_init',
- deps='samdb process_model RPC_NDR_IRPC RPC_NDR_DRSUAPI',
+ deps='samdb process_model RPC_NDR_IRPC RPC_NDR_DRSUAPI UTIL_RUNCMD',
internal_module=False,
)
diff --git a/source4/scripting/bin/samba_kcc b/source4/scripting/bin/samba_kcc
index c024cd4..c17439e 100755
--- a/source4/scripting/bin/samba_kcc
+++ b/source4/scripting/bin/samba_kcc
@@ -20,6 +20,7 @@
import os
import sys
import random
+import copy
# ensure we get messages out immediately, so they get in the samba logs,
# and don't get swallowed by a timeout
@@ -41,6 +42,7 @@ import logging
from samba import getopt as options
from samba.auth import system_session
from samba.samdb import SamDB
+from samba.dcerpc import drsuapi
from samba.kcc_utils import *
class KCC:
@@ -55,12 +57,47 @@ class KCC:
our local DCs partitions or all the partitions in
the forest
"""
- self.dsa_table = {} # dsa objects
- self.part_table = {} # partition objects
- self.site_table = {}
+ self.part_table = {} # partition objects
+ self.site_table = {}
+ self.transport_table = {}
+
self.my_dsa_dnstr = None # My dsa DN
+ self.my_dsa = None # My dsa object
+
self.my_site_dnstr = None
+ self.my_site = None
+
self.samdb = samdb
+ return
+
+ def load_all_transports(self):
+ """Loads the inter-site transport objects for Sites
+ Raises an Exception on error
+ """
+ try:
+ res = samdb.search("CN=Inter-Site Transports,CN=Sites,%s" % \
+ samdb.get_config_basedn(),
+ scope=ldb.SCOPE_SUBTREE,
+ expression="(objectClass=interSiteTransport)")
+ except ldb.LdbError, (enum, estr):
+ raise Exception("Unable to find inter-site transports - (%s)" % estr)
+
+ for msg in res:
+ dnstr = str(msg.dn)
+
+ # already loaded
+ if dnstr in self.transport_table.keys():
+ continue
+
+ transport = Transport(dnstr)
+
+ transport.load_transport(samdb)
+
+ # Assign this transport to table
+ # and index by dn
+ self.transport_table[dnstr] = transport
+
+ return
def load_my_site(self):
"""Loads the Site class for the local DSA
@@ -69,14 +106,14 @@ class KCC:
self.my_site_dnstr = "CN=%s,CN=Sites,%s" % (samdb.server_site_name(),
samdb.get_config_basedn())
site = Site(self.my_site_dnstr)
-
site.load_site(samdb)
+
self.site_table[self.my_site_dnstr] = site
+ self.my_site = site
+ return
def load_my_dsa(self):
- """Discover my nTDSDSA thru the rootDSE entry and
- instantiate and load the DSA. The dsa is inserted
- into the dsa_table by dn string
+ """Discover my nTDSDSA dn thru the rootDSE entry
Raises an Exception on error.
"""
dn = ldb.Dn(self.samdb, "")
@@ -86,49 +123,10 @@ class KCC:
except ldb.LdbError, (enum, estr):
raise Exception("Unable to find my nTDSDSA - (%s)" % estr)
- dnstr = res[0]["dsServiceName"][0]
-
- # already loaded
- if dnstr in self.dsa_table.keys():
- return
-
- self.my_dsa_dnstr = dnstr
- dsa = DirectoryServiceAgent(dnstr)
-
- dsa.load_dsa(samdb)
-
- # Assign this dsa to my dsa table
- # and index by dsa dn
- self.dsa_table[dnstr] = dsa
-
- def load_all_dsa(self):
- """Discover all nTDSDSA thru the sites entry and
- instantiate and load the DSAs. Each dsa is inserted
- into the dsa_table by dn string.
- Raises an Exception on error.
- """
- try:
- res = self.samdb.search("CN=Sites,%s" %
- self.samdb.get_config_basedn(),
- scope=ldb.SCOPE_SUBTREE,
- expression="(objectClass=nTDSDSA)")
- except ldb.LdbError, (enum, estr):
- raise Exception("Unable to find nTDSDSAs - (%s)" % estr)
+ self.my_dsa_dnstr = res[0]["dsServiceName"][0]
+ self.my_dsa = self.my_site.get_dsa(self.my_dsa_dnstr)
- for msg in res:
- dnstr = str(msg.dn)
-
- # already loaded
- if dnstr in self.dsa_table.keys():
- continue
-
- dsa = DirectoryServiceAgent(dnstr)
-
- dsa.load_dsa(self.samdb)
-
- # Assign this dsa to my dsa table
- # and index by dsa dn
- self.dsa_table[dnstr] = dsa
+ return
def load_all_partitions(self):
"""Discover all NCs thru the Partitions dn and
@@ -158,16 +156,15 @@ class KCC:
self.part_table[partstr] = part
def should_be_present_test(self):
- """Enumerate all loaded partitions and DSAs and test
- if NC should be present as replica
+ """Enumerate all loaded partitions and DSAs in local
+ site and test if NC should be present as replica
"""
for partdn, part in self.part_table.items():
-
- for dsadn, dsa in self.dsa_table.items():
+ for dsadn, dsa in self.my_site.dsa_table.items():
needed, ro, partial = part.should_be_present(dsa)
-
logger.info("dsadn:%s\nncdn:%s\nneeded=%s:ro=%s:partial=%s\n" % \
- (dsa.dsa_dnstr, part.nc_dnstr, needed, ro, partial))
+ (dsadn, part.nc_dnstr, needed, ro, partial))
+ return
def refresh_failed_links_connections(self):
# XXX - not implemented yet
@@ -186,12 +183,500 @@ class KCC:
# XXX - not implemented yet
return
- def remove_unneeded_ntds_connections(self):
+ def remove_unneeded_ntdsconn(self):
# XXX - not implemented yet
return
- def translate_connections(self):
- # XXX - not implemented yet
+ def get_dsa_by_guidstr(self, guidstr):
+ """Given a DSA guid string, consule all sites looking
+ for the corresponding DSA and return it.
+ """
+ for site in self.site_table.values():
+ dsa = site.get_dsa_by_guidstr(guidstr)
+ if dsa is not None:
+ return dsa
+ return None
+
+ def get_dsa(self, dnstr):
+ """Given a DSA dn string, consule all sites looking
+ for the corresponding DSA and return it.
+ """
+ for site in self.site_table.values():
+ dsa = site.get_dsa(dnstr)
+ if dsa is not None:
+ return dsa
+ return None
+
+ def modify_repsFrom(self, n_rep, t_repsFrom, s_rep, s_dsa, cn_conn):
+ """Update t_repsFrom if necessary to satisfy requirements. Such
+ updates are typically required when the IDL_DRSGetNCChanges
+ server has moved from one site to another--for example, to
+ enable compression when the server is moved from the
+ client's site to another site.
+ :param n_rep: NC replica we need
+ :param t_repsFrom: repsFrom tuple to modify
+ :param s_rep: NC replica at source DSA
+ :param s_dsa: source DSA
+ :param cn_conn: Local DSA NTDSConnection child
+ Returns (update) bit field containing which portion of the
+ repsFrom was modified. This bit field is suitable as input
+ to IDL_DRSReplicaModify ulModifyFields element, as it consists
+ of these bits:
+ drsuapi.DRSUAPI_DRS_UPDATE_SCHEDULE
+ drsuapi.DRSUAPI_DRS_UPDATE_FLAGS
+ drsuapi.DRSUAPI_DRS_UPDATE_ADDRESS
+ """
+ s_dnstr = s_dsa.dsa_dnstr
+ update = 0x0
+
+ if self.my_site.get_dsa(s_dnstr) is s_dsa:
+ same_site = True
--
Samba Shared Repository
More information about the samba-cvs
mailing list