The branch, master has been updated via 1cf4802... s4-drs: add deletion of old connections via bed9efa... s4-ldb: changed ldb_msg_add_dn() to ldb_msg_add_linearized_dn() via 7ca2ceb... s4-drs: Create connection obejct (nTDSConnection) from 8331b4c... s4-ldb: check for -ve value for page size
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1cf48022afab79e1fc462b18032d0e497ed15ecf Author: CrÃstian Deives <cristiandei...@gmail.com> Date: Mon Nov 30 20:12:24 2009 +1100 s4-drs: add deletion of old connections the nTDSConnection objects that are not needed anymore will be deleted. the function kccsrv_delete_connection wasn't tested yet. Signed-off-by: Andrew Tridgell <tri...@samba.org> commit bed9efa6cda17ecca91bdf71227ec656b94dcf94 Author: CrÃstian Deives <cristiandei...@gmail.com> Date: Mon Nov 23 15:47:51 2009 -0200 s4-ldb: changed ldb_msg_add_dn() to ldb_msg_add_linearized_dn() this makes the usage clearer Signed-off-by: Andrew Tridgell <tri...@samba.org> commit 7ca2ceb333de6c4daad10890b3e3022e1930235c Author: CrÃstian Deives <cristiandei...@gmail.com> Date: Mon Nov 30 20:11:27 2009 +1100 s4-drs: Create connection obejct (nTDSConnection) create nTDSConnection objects to match the list of servers Signed-off-by: Andrew Tridgell <tri...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/dsdb/config.mk | 1 + source4/dsdb/kcc/kcc_connection.c | 227 ++++++++++++++++++++++ source4/dsdb/kcc/kcc_connection.h | 38 ++++ source4/dsdb/kcc/kcc_periodic.c | 17 ++ source4/dsdb/samdb/ldb_modules/extended_dn_out.c | 6 +- source4/lib/ldb/common/ldb_msg.c | 7 +- source4/lib/ldb/include/ldb.h | 4 +- source4/lib/ldb/ldb_map/ldb_map_inbound.c | 9 +- 8 files changed, 298 insertions(+), 11 deletions(-) create mode 100644 source4/dsdb/kcc/kcc_connection.c create mode 100644 source4/dsdb/kcc/kcc_connection.h Changeset truncated at 500 lines: diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index ac4096d..dfc5def 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -82,6 +82,7 @@ PRIVATE_DEPENDENCIES = \ KCC_SRV_OBJ_FILES = $(addprefix $(dsdbsrcdir)/kcc/, \ kcc_service.o \ + kcc_connection.o \ kcc_periodic.o) $(eval $(call proto_header_template,$(dsdbsrcdir)/kcc/kcc_service_proto.h,$(KCC_SRV_OBJ_FILES:.o=.c))) diff --git a/source4/dsdb/kcc/kcc_connection.c b/source4/dsdb/kcc/kcc_connection.c new file mode 100644 index 0000000..ee9a05a --- /dev/null +++ b/source4/dsdb/kcc/kcc_connection.c @@ -0,0 +1,227 @@ +/* + Unix SMB/CIFS implementation. + KCC service periodic handling + + Copyright (C) CrÃstian Deives + + 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/>. + +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "dsdb/samdb/samdb.h" +#include "auth/auth.h" +#include "smbd/service.h" +#include "lib/messaging/irpc.h" +#include "dsdb/kcc/kcc_connection.h" +#include "dsdb/kcc/kcc_service.h" +#include "lib/ldb/include/ldb_errors.h" +#include "../lib/util/dlinklist.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_drsuapi.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "param/param.h" + +static int kccsrv_add_connection(struct kccsrv_service *s, + struct kcc_connection *conn) +{ + struct ldb_message *msg; + TALLOC_CTX *tmp_ctx; + struct ldb_dn *new_dn, *server_dn; + struct GUID guid; + /* struct ldb_val schedule_val; */ + int ret; + bool ok; + + tmp_ctx = talloc_new(s); + new_dn = samdb_ntds_settings_dn(s->samdb); + if (!new_dn) { + DEBUG(0, ("failed to find NTDS settings\n")); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + new_dn = ldb_dn_copy(tmp_ctx, new_dn); + if (!new_dn) { + DEBUG(0, ("failed to copy NTDS settings\n")); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + guid = GUID_random(); + ok = ldb_dn_add_child_fmt(new_dn, "CN=%s", GUID_string(tmp_ctx, &guid)); + if (!ok) { + DEBUG(0, ("failed to create nTDSConnection DN\n")); + ret = LDB_ERR_INVALID_DN_SYNTAX; + goto done; + } + ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, GUID_string(tmp_ctx, + &conn->dsa_guid), &server_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("failed to find fromServer DN '%s'\n", + GUID_string(tmp_ctx, &conn->dsa_guid))); + goto done; + } + /*schedule_val = data_blob_const(r1->schedule, sizeof(r1->schedule));*/ + + msg = ldb_msg_new(tmp_ctx); + msg->dn = new_dn; + ldb_msg_add_string(msg, "objectClass", "nTDSConnection"); + ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE"); + ldb_msg_add_string(msg, "enabledConnection", "TRUE"); + ldb_msg_add_linearized_dn(msg, "fromServer", server_dn); + /* ldb_msg_add_value(msg, "schedule", &schedule_val, NULL); */ + ldb_msg_add_string(msg, "options", "1"); + + ret = ldb_add(s->samdb, msg); + if (ret == LDB_SUCCESS) { + DEBUG(2, ("added nTDSConnection object '%s'\n", + ldb_dn_get_linearized(new_dn))); + } else { + DEBUG(0, ("failed to add an nTDSConnection object: %s\n", + ldb_strerror(ret))); + } + +done: + talloc_free(tmp_ctx); + return ret; +} + +static int kccsrv_delete_connection(struct kccsrv_service *s, + struct kcc_connection *conn) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *dn; + int ret; + + tmp_ctx = talloc_new(s); + ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, + GUID_string(tmp_ctx, &conn->obj_guid), &dn); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("failed to find nTDSConnection's DN: %s\n", + ldb_strerror(ret))); + goto done; + } + + ret = ldb_delete(s->samdb, dn); + if (ret == LDB_SUCCESS) { + DEBUG(2, ("deleted nTDSConnection object '%s'\n", + ldb_dn_get_linearized(dn))); + } else { + DEBUG(0, ("failed to delete an nTDSConnection object: %s\n", + ldb_strerror(ret))); + } + +done: + talloc_free(tmp_ctx); + return ret; +} + +void kccsrv_apply_connections(struct kccsrv_service *s, + struct kcc_connection_list *ntds_list, + struct kcc_connection_list *dsa_list) +{ + int i, j, deleted = 0, added = 0, ret; + + for (i = 0; i < ntds_list->count; i++) { + struct kcc_connection *ntds = &ntds_list->servers[i]; + for (j = 0; j < dsa_list->count; j++) { + struct kcc_connection *dsa = &dsa_list->servers[j]; + if (GUID_equal(&ntds->dsa_guid, &dsa->dsa_guid)) { + break; + } + } + if (j == dsa_list->count) { + ret = kccsrv_delete_connection(s, ntds); + if (ret == LDB_SUCCESS) { + deleted++; + } + } + } + DEBUG(4, ("%d connections have been deleted\n", deleted)); + + for (i = 0; i < dsa_list->count; i++) { + struct kcc_connection *dsa = &dsa_list->servers[i]; + for (j = 0; j < ntds_list->count; j++) { + struct kcc_connection *ntds = &ntds_list->servers[j]; + if (GUID_equal(&dsa->dsa_guid, &ntds->dsa_guid)) { + break; + } + } + if (j == ntds_list->count) { + ret = kccsrv_add_connection(s, dsa); + if (ret == LDB_SUCCESS) { + added++; + } + } + } + DEBUG(4, ("%d connections have been added\n", added)); +} + +struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s, + TALLOC_CTX *mem_ctx) +{ + int ret, i; + struct ldb_dn *base_dn; + struct ldb_result *res; + const char *attrs[] = { "objectGUID", "fromServer", NULL }; + struct kcc_connection_list *list; + + base_dn = samdb_ntds_settings_dn(s->samdb); + if (!base_dn) { + DEBUG(0, ("failed to find our own NTDS settings DN\n")); + return NULL; + } + + ret = ldb_search(s->samdb, mem_ctx, &res, base_dn, LDB_SCOPE_ONELEVEL, + attrs, "objectClass=nTDSConnection"); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("failed nTDSConnection search: %s\n", + ldb_strerror(ret))); + return NULL; + } + + list = talloc(mem_ctx, struct kcc_connection_list); + if (!list) { + DEBUG(0, ("out of memory")); + return NULL; + } + list->servers = talloc_array(mem_ctx, struct kcc_connection, + res->count); + if (!list->servers) { + DEBUG(0, ("out of memory")); + return NULL; + } + list->count = 0; + + for (i = 0; i < res->count; i++) { + struct ldb_dn *server_dn; + + list->servers[i].obj_guid = samdb_result_guid(res->msgs[i], + "objectGUID"); + server_dn = samdb_result_dn(s->samdb, mem_ctx, res->msgs[i], + "fromServer", NULL); + ret = dsdb_find_guid_by_dn(s->samdb, server_dn, + &list->servers[i].dsa_guid); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("failed to find connection server's GUID" + "by DN=%s: %s\n", + ldb_dn_get_linearized(server_dn), + ldb_strerror(ret))); + continue; + } + list->count++; + } + DEBUG(4, ("found %d existing nTDSConnection objects\n", list->count)); + return list; +} diff --git a/source4/dsdb/kcc/kcc_connection.h b/source4/dsdb/kcc/kcc_connection.h new file mode 100644 index 0000000..8dcd0b2 --- /dev/null +++ b/source4/dsdb/kcc/kcc_connection.h @@ -0,0 +1,38 @@ +/* + Unix SMB/CIFS mplementation. + + KCC service + + Copyright (C) CrÃstian Deives 2009 + based on drepl service code + + 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/>. + +*/ + +#ifndef _DSDB_REPL_KCC_CONNECTION_H_ +#define _DSDB_REPL_KCC_CONNECTION_H_ + +struct kcc_connection { + struct GUID obj_guid; + struct GUID dsa_guid; + uint8_t schedule[84]; +}; + +struct kcc_connection_list { + unsigned count; + struct kcc_connection *servers; +}; + +#endif /* _DSDB_REPL_KCC_CONNECTION_H_ */ diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c index 097fff4..d24e5e9 100644 --- a/source4/dsdb/kcc/kcc_periodic.c +++ b/source4/dsdb/kcc/kcc_periodic.c @@ -26,6 +26,7 @@ #include "auth/auth.h" #include "smbd/service.h" #include "lib/messaging/irpc.h" +#include "dsdb/kcc/kcc_connection.h" #include "dsdb/kcc/kcc_service.h" #include "lib/ldb/include/ldb_errors.h" #include "../lib/util/dlinklist.h" @@ -122,6 +123,7 @@ NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) const char *attrs[] = { "objectGUID", "invocationID", NULL }; struct repsFromToBlob *reps = NULL; uint32_t count = 0; + struct kcc_connection_list *ntds_conn, *dsa_conn; ret = ldb_search(s->samdb, mem_ctx, &res, s->config_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=nTDSDSA"); @@ -130,6 +132,11 @@ NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* get the current list of connections */ + ntds_conn = kccsrv_find_connections(s, mem_ctx); + + dsa_conn = talloc_zero(mem_ctx, struct kcc_connection_list); + for (i=0; i<res->count; i++) { struct repsFromTo1 *r1; struct GUID ntds_guid, invocation_id; @@ -160,9 +167,19 @@ NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS; memset(r1->schedule, 0x11, sizeof(r1->schedule)); + + dsa_conn->servers = talloc_realloc(dsa_conn, dsa_conn->servers, + struct kcc_connection, + dsa_conn->count + 1); + NT_STATUS_HAVE_NO_MEMORY(dsa_conn->servers); + dsa_conn->servers[dsa_conn->count].dsa_guid = r1->source_dsa_obj_guid; + dsa_conn->count++; + count++; } + kccsrv_apply_connections(s, ntds_conn, dsa_conn); + return kccsrv_add_repsFrom(s, mem_ctx, reps, count); } diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index c52953c..1463e19 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -377,9 +377,9 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, ret = ldb_msg_add_steal_string(ares->message, "distinguishedName", ldb_dn_get_extended_linearized(ares->message, ares->message->dn, ac->extended_type)); } else { - ret = ldb_msg_add_dn(ares->message, - "distinguishedName", - ares->message->dn); + ret = ldb_msg_add_linearized_dn(ares->message, + "distinguishedName", + ares->message->dn); } if (ret != LDB_SUCCESS) { ldb_oom(ldb); diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index f1dd6f3..fbf49fb 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -263,10 +263,11 @@ int ldb_msg_add_steal_string(struct ldb_message *msg, WARNING: this uses the linearized string from the dn, and does not copy the string. */ -int ldb_msg_add_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn) +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn) { - return ldb_msg_add_string(msg, attr_name, ldb_dn_get_linearized(dn)); + return ldb_msg_add_steal_string(msg, attr_name, + ldb_dn_alloc_linearized(msg, dn)); } /* diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index f2b4a48..88ac29d 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -1776,8 +1776,8 @@ int ldb_msg_add_steal_string(struct ldb_message *msg, const char *attr_name, char *str); int ldb_msg_add_string(struct ldb_message *msg, const char *attr_name, const char *str); -int ldb_msg_add_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn); +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn); int ldb_msg_add_fmt(struct ldb_message *msg, const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index 11ec9d2..5a948cf 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -425,7 +425,9 @@ int map_add(struct ldb_module *module, struct ldb_request *req) /* Store remote DN in 'IS_MAPPED' */ /* TODO: use GUIDs here instead */ - if (ldb_msg_add_dn(ac->local_msg, IS_MAPPED, remote_msg->dn) != 0) { + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + remote_msg->dn); + if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } @@ -555,8 +557,9 @@ static int map_modify_do_local(struct map_context *ac) LDB_FLAG_MOD_ADD, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } - if (ldb_msg_add_dn(ac->local_msg, IS_MAPPED, - ac->remote_req->op.mod.message->dn) != 0) { + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + ac->remote_req->op.mod.message->dn); + if (ret != 0) { return LDB_ERR_OPERATIONS_ERROR; } -- Samba Shared Repository