Changeset 740 for vendor/current/source4/dsdb/kcc
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source4/dsdb/kcc
- Files:
-
- 5 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/dsdb/kcc/kcc_periodic.c
r414 r740 27 27 #include "smbd/service.h" 28 28 #include "lib/messaging/irpc.h" 29 #include "dsdb/kcc/kcc_connection.h" 29 30 #include "dsdb/kcc/kcc_service.h" 30 #include "lib/ldb/include/ldb_errors.h"31 #include <ldb_errors.h> 31 32 #include "../lib/util/dlinklist.h" 32 33 #include "librpc/gen_ndr/ndr_misc.h" 33 34 #include "librpc/gen_ndr/ndr_drsuapi.h" 34 35 #include "librpc/gen_ndr/ndr_drsblobs.h" 36 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 37 #include "param/param.h" 38 39 /* 40 * see if two repsFromToBlob blobs are for the same source DSA 41 */ 42 static bool kccsrv_same_source_dsa(struct repsFromToBlob *r1, struct repsFromToBlob *r2) 43 { 44 return GUID_compare(&r1->ctr.ctr1.source_dsa_obj_guid, 45 &r2->ctr.ctr1.source_dsa_obj_guid) == 0; 46 } 36 47 37 48 /* … … 40 51 static bool reps_in_list(struct repsFromToBlob *r, struct repsFromToBlob *reps, uint32_t count) 41 52 { 42 int i;53 uint32_t i; 43 54 for (i=0; i<count; i++) { 44 if (strcmp(r->ctr.ctr1.other_info->dns_name, 45 reps[i].ctr.ctr1.other_info->dns_name) == 0 && 46 GUID_compare(&r->ctr.ctr1.source_dsa_obj_guid, 47 &reps[i].ctr.ctr1.source_dsa_obj_guid) == 0) { 55 if (kccsrv_same_source_dsa(r, &reps[i])) { 48 56 return true; 49 57 } … … 52 60 } 53 61 62 /* 63 make sure we only add repsFrom entries for DCs who are masters for 64 the partition 65 */ 66 static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r, 67 struct ldb_result *res) 68 { 69 struct repsFromTo1 *r1 = &r->ctr.ctr1; 70 struct GUID invocation_id = r1->source_dsa_invocation_id; 71 unsigned int i, j; 72 73 /* we are expecting only version 1 */ 74 SMB_ASSERT(r->version == 1); 75 76 for (i=0; i<res->count; i++) { 77 struct ldb_message *msg = res->msgs[i]; 78 struct ldb_message_element *el; 79 struct ldb_dn *dn; 80 81 struct GUID id2 = samdb_result_guid(msg, "invocationID"); 82 if (GUID_all_zero(&id2) || 83 !GUID_equal(&invocation_id, &id2)) { 84 continue; 85 } 86 87 el = ldb_msg_find_element(msg, "msDS-hasMasterNCs"); 88 if (!el || el->num_values == 0) { 89 el = ldb_msg_find_element(msg, "hasMasterNCs"); 90 if (!el || el->num_values == 0) { 91 continue; 92 } 93 } 94 for (j=0; j<el->num_values; j++) { 95 dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]); 96 if (!ldb_dn_validate(dn)) { 97 talloc_free(dn); 98 continue; 99 } 100 if (ldb_dn_compare(dn, p->dn) == 0) { 101 talloc_free(dn); 102 DEBUG(5,("%s %s match on %s in %s\n", 103 r1->other_info->dns_name, 104 el->name, 105 ldb_dn_get_linearized(dn), 106 ldb_dn_get_linearized(msg->dn))); 107 return true; 108 } 109 talloc_free(dn); 110 } 111 } 112 return false; 113 } 114 115 struct kccsrv_notify_drepl_server_state { 116 struct dreplsrv_refresh r; 117 }; 118 119 static void kccsrv_notify_drepl_server_done(struct tevent_req *subreq); 120 121 /** 122 * Force dreplsrv to update its state as topology is changed 123 */ 124 static void kccsrv_notify_drepl_server(struct kccsrv_service *s, 125 TALLOC_CTX *mem_ctx) 126 { 127 struct kccsrv_notify_drepl_server_state *state; 128 struct dcerpc_binding_handle *irpc_handle; 129 struct tevent_req *subreq; 130 131 state = talloc_zero(s, struct kccsrv_notify_drepl_server_state); 132 if (state == NULL) { 133 return; 134 } 135 136 irpc_handle = irpc_binding_handle_by_name(state, s->task->msg_ctx, 137 "dreplsrv", &ndr_table_irpc); 138 if (irpc_handle == NULL) { 139 /* dreplsrv is not running yet */ 140 TALLOC_FREE(state); 141 return; 142 } 143 144 subreq = dcerpc_dreplsrv_refresh_r_send(state, s->task->event_ctx, 145 irpc_handle, &state->r); 146 if (subreq == NULL) { 147 TALLOC_FREE(state); 148 return; 149 } 150 tevent_req_set_callback(subreq, kccsrv_notify_drepl_server_done, state); 151 } 152 153 static void kccsrv_notify_drepl_server_done(struct tevent_req *subreq) 154 { 155 struct kccsrv_notify_drepl_server_state *state = 156 tevent_req_callback_data(subreq, 157 struct kccsrv_notify_drepl_server_state); 158 NTSTATUS status; 159 160 status = dcerpc_dreplsrv_refresh_r_recv(subreq, state); 161 TALLOC_FREE(subreq); 162 163 /* we don't care about errors */ 164 TALLOC_FREE(state); 165 } 166 167 static uint32_t kccsrv_replica_flags(struct kccsrv_service *s) 168 { 169 if (s->am_rodc) { 170 return DRSUAPI_DRS_INIT_SYNC | 171 DRSUAPI_DRS_PER_SYNC | 172 DRSUAPI_DRS_ADD_REF | 173 DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING | 174 DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP | 175 DRSUAPI_DRS_NONGC_RO_REP; 176 } 177 return DRSUAPI_DRS_INIT_SYNC | 178 DRSUAPI_DRS_PER_SYNC | 179 DRSUAPI_DRS_ADD_REF | 180 DRSUAPI_DRS_WRIT_REP; 181 } 54 182 55 183 /* … … 57 185 */ 58 186 static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx, 59 struct repsFromToBlob *reps, uint32_t count) 187 struct repsFromToBlob *reps, uint32_t count, 188 struct ldb_result *res) 60 189 { 61 190 struct kccsrv_partition *p; 191 bool notify_dreplsrv = false; 192 uint32_t replica_flags = kccsrv_replica_flags(s); 62 193 63 194 /* update the repsFrom on all partitions */ 64 195 for (p=s->partitions; p; p=p->next) { 65 struct repsFromToBlob *o ld_reps;66 uint32_t o ld_count;196 struct repsFromToBlob *our_reps; 197 uint32_t our_count; 67 198 WERROR werr; 68 int i;199 uint32_t i, j; 69 200 bool modified = false; 70 201 71 werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsFrom", &o ld_reps, &old_count);202 werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsFrom", &our_reps, &our_count); 72 203 if (!W_ERROR_IS_OK(werr)) { 73 204 DEBUG(0,(__location__ ": Failed to load repsFrom from %s - %s\n", … … 76 207 } 77 208 78 /* add any new ones */209 /* see if the entry already exists */ 79 210 for (i=0; i<count; i++) { 80 if (!reps_in_list(&reps[i], old_reps, old_count)) { 81 old_reps = talloc_realloc(mem_ctx, old_reps, struct repsFromToBlob, old_count+1); 82 NT_STATUS_HAVE_NO_MEMORY(old_reps); 83 old_reps[old_count] = reps[i]; 84 old_count++; 211 for (j=0; j<our_count; j++) { 212 if (kccsrv_same_source_dsa(&reps[i], &our_reps[j])) { 213 /* we already have this one - 214 check the replica_flags are right */ 215 if (replica_flags != our_reps[j].ctr.ctr1.replica_flags) { 216 /* we need to update the old one with 217 * the new flags 218 */ 219 our_reps[j].ctr.ctr1.replica_flags = replica_flags; 220 modified = true; 221 } 222 break; 223 } 224 } 225 if (j == our_count) { 226 /* we don't have the new one - add it 227 * if it is a master 228 */ 229 if (!check_MasterNC(p, &reps[i], res)) { 230 /* its not a master, we don't 231 want to pull from it */ 232 continue; 233 } 234 /* we need to add it to our repsFrom */ 235 our_reps = talloc_realloc(mem_ctx, our_reps, struct repsFromToBlob, our_count+1); 236 NT_STATUS_HAVE_NO_MEMORY(our_reps); 237 our_reps[our_count] = reps[i]; 238 our_reps[our_count].ctr.ctr1.replica_flags = replica_flags; 239 our_count++; 85 240 modified = true; 241 DEBUG(4,(__location__ ": Added repsFrom for %s\n", 242 reps[i].ctr.ctr1.other_info->dns_name)); 86 243 } 87 244 } 88 245 89 246 /* remove any stale ones */ 90 for (i=0; i<old_count; i++) { 91 if (!reps_in_list(&old_reps[i], reps, count)) { 92 memmove(&old_reps[i], &old_reps[i+1], (old_count-(i+1))*sizeof(old_reps[0])); 93 old_count--; 247 for (i=0; i<our_count; i++) { 248 if (!reps_in_list(&our_reps[i], reps, count) || 249 !check_MasterNC(p, &our_reps[i], res)) { 250 DEBUG(4,(__location__ ": Removed repsFrom for %s\n", 251 our_reps[i].ctr.ctr1.other_info->dns_name)); 252 memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0])); 253 our_count--; 94 254 i--; 95 255 modified = true; 96 256 } 97 257 } 98 258 99 259 if (modified) { 100 werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsFrom", o ld_reps, old_count);260 werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsFrom", our_reps, our_count); 101 261 if (!W_ERROR_IS_OK(werr)) { 102 262 DEBUG(0,(__location__ ": Failed to save repsFrom to %s - %s\n", … … 104 264 return NT_STATUS_INTERNAL_DB_CORRUPTION; 105 265 } 106 } 266 /* dreplsrv should refresh its state */ 267 notify_dreplsrv = true; 268 } 269 270 /* remove stale repsTo entries */ 271 modified = false; 272 werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsTo", &our_reps, &our_count); 273 if (!W_ERROR_IS_OK(werr)) { 274 DEBUG(0,(__location__ ": Failed to load repsTo from %s - %s\n", 275 ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb))); 276 return NT_STATUS_INTERNAL_DB_CORRUPTION; 277 } 278 279 /* remove any stale ones */ 280 for (i=0; i<our_count; i++) { 281 if (!reps_in_list(&our_reps[i], reps, count)) { 282 DEBUG(4,(__location__ ": Removed repsTo for %s\n", 283 our_reps[i].ctr.ctr1.other_info->dns_name)); 284 memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0])); 285 our_count--; 286 i--; 287 modified = true; 288 } 289 } 290 291 if (modified) { 292 werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsTo", our_reps, our_count); 293 if (!W_ERROR_IS_OK(werr)) { 294 DEBUG(0,(__location__ ": Failed to save repsTo to %s - %s\n", 295 ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb))); 296 return NT_STATUS_INTERNAL_DB_CORRUPTION; 297 } 298 /* dreplsrv should refresh its state */ 299 notify_dreplsrv = true; 300 } 301 } 302 303 /* notify dreplsrv toplogy has changed */ 304 if (notify_dreplsrv) { 305 kccsrv_notify_drepl_server(s, mem_ctx); 107 306 } 108 307 … … 116 315 objects, except for ourselves 117 316 */ 118 staticNTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)317 NTSTATUS kccsrv_simple_update(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) 119 318 { 120 319 struct ldb_result *res; 121 int ret, i; 122 const char *attrs[] = { "objectGUID", "invocationID", NULL }; 320 unsigned int i; 321 int ret; 322 const char *attrs[] = { "objectGUID", "invocationID", "msDS-hasMasterNCs", "hasMasterNCs", NULL }; 123 323 struct repsFromToBlob *reps = NULL; 124 324 uint32_t count = 0; 325 struct kcc_connection_list *ntds_conn, *dsa_conn; 125 326 126 327 ret = ldb_search(s->samdb, mem_ctx, &res, s->config_dn, LDB_SCOPE_SUBTREE, … … 131 332 } 132 333 334 /* get the current list of connections */ 335 ntds_conn = kccsrv_find_connections(s, mem_ctx); 336 337 dsa_conn = talloc_zero(mem_ctx, struct kcc_connection_list); 338 133 339 for (i=0; i<res->count; i++) { 134 340 struct repsFromTo1 *r1; … … 153 359 r1->other_info->dns_name = talloc_asprintf(r1->other_info, "%s._msdcs.%s", 154 360 GUID_string(mem_ctx, &ntds_guid), 155 lp _realm(s->task->lp_ctx));361 lpcfg_dnsdomain(s->task->lp_ctx)); 156 362 r1->source_dsa_obj_guid = ntds_guid; 157 363 r1->source_dsa_invocation_id = invocation_id; 158 r1->replica_flags = 159 DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE | 160 DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP | 161 DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS; 364 r1->replica_flags = kccsrv_replica_flags(s); 162 365 memset(r1->schedule, 0x11, sizeof(r1->schedule)); 366 367 dsa_conn->servers = talloc_realloc(dsa_conn, dsa_conn->servers, 368 struct kcc_connection, 369 dsa_conn->count + 1); 370 NT_STATUS_HAVE_NO_MEMORY(dsa_conn->servers); 371 dsa_conn->servers[dsa_conn->count].dsa_guid = r1->source_dsa_obj_guid; 372 dsa_conn->count++; 373 163 374 count++; 164 375 } 165 376 166 return kccsrv_add_repsFrom(s, mem_ctx, reps, count); 377 kccsrv_apply_connections(s, ntds_conn, dsa_conn); 378 379 return kccsrv_add_repsFrom(s, mem_ctx, reps, count, res); 167 380 } 168 381 … … 217 430 218 431 tmp_mem = talloc_new(service); 219 DEBUG( 2,("kccsrv_periodic_schedule(%u) %sscheduled for: %s\n",432 DEBUG(4,("kccsrv_periodic_schedule(%u) %sscheduled for: %s\n", 220 433 next_interval, 221 434 (service->periodic.te?"re":""), … … 234 447 NTSTATUS status; 235 448 236 DEBUG( 2,("kccsrv_periodic_run(): simple update\n"));449 DEBUG(4,("kccsrv_periodic_run(): simple update\n")); 237 450 238 451 mem_ctx = talloc_new(service); … … 241 454 DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status))); 242 455 } 456 457 status = kccsrv_check_deleted(service, mem_ctx); 458 if (!NT_STATUS_IS_OK(status)) { 459 DEBUG(0,("kccsrv_check_deleted failed - %s\n", nt_errstr(status))); 460 } 243 461 talloc_free(mem_ctx); 244 462 } -
vendor/current/source4/dsdb/kcc/kcc_service.c
r414 r740 29 29 #include "lib/messaging/irpc.h" 30 30 #include "dsdb/kcc/kcc_service.h" 31 #include "lib/ldb/include/ldb_errors.h"31 #include <ldb_errors.h> 32 32 #include "../lib/util/dlinklist.h" 33 33 #include "librpc/gen_ndr/ndr_misc.h" … … 41 41 static WERROR kccsrv_init_creds(struct kccsrv_service *service) 42 42 { 43 NTSTATUS status; 44 45 status = auth_system_session_info(service, service->task->lp_ctx, 46 &service->system_session_info); 47 if (!NT_STATUS_IS_OK(status)) { 48 return ntstatus_to_werror(status); 43 service->system_session_info = system_session(service->task->lp_ctx); 44 if (!service->system_session_info) { 45 return WERR_NOMEM; 49 46 } 50 47 … … 59 56 const struct GUID *ntds_guid; 60 57 61 service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info );58 service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info, 0); 62 59 if (!service->samdb) { 63 60 return WERR_DS_UNAVAILABLE; … … 70 67 71 68 service->ntds_guid = *ntds_guid; 69 70 if (samdb_rodc(service->samdb, &service->am_rodc) != LDB_SUCCESS) { 71 DEBUG(0,(__location__ ": Failed to determine RODC status\n")); 72 return WERR_DS_UNAVAILABLE; 73 } 72 74 73 75 return WERR_OK; … … 84 86 struct ldb_message_element *el; 85 87 static const char *attrs[] = { "namingContexts", "configurationNamingContext", NULL }; 86 u int32_t i;88 unsigned int i; 87 89 int ret; 88 90 … … 105 107 } 106 108 107 for (i=0; el &&i < el->num_values; i++) {109 for (i=0; i < el->num_values; i++) { 108 110 const char *v = (const char *)el->values[i].data; 109 111 struct ldb_dn *pdn; … … 140 142 } 141 143 144 static NTSTATUS kccsrv_execute_kcc(struct irpc_message *msg, struct drsuapi_DsExecuteKCC *r) 145 { 146 TALLOC_CTX *mem_ctx; 147 NTSTATUS status; 148 struct kccsrv_service *service = talloc_get_type(msg->private_data, struct kccsrv_service); 149 150 mem_ctx = talloc_new(service); 151 status = kccsrv_simple_update(service, mem_ctx); 152 153 if (!NT_STATUS_IS_OK(status)) { 154 DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status))); 155 talloc_free(mem_ctx); 156 return status; 157 } 158 159 talloc_free(mem_ctx); 160 return NT_STATUS_OK; 161 } 162 163 static NTSTATUS kccsrv_replica_get_info(struct irpc_message *msg, struct drsuapi_DsReplicaGetInfo *r) 164 { 165 return kccdrs_replica_get_info(msg, r); 166 } 142 167 143 168 /* … … 150 175 uint32_t periodic_startup_interval; 151 176 152 switch (lp _server_role(task->lp_ctx)) {177 switch (lpcfg_server_role(task->lp_ctx)) { 153 178 case ROLE_STANDALONE: 154 179 task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false); … … 198 223 } 199 224 200 periodic_startup_interval = lp _parm_int(task->lp_ctx, NULL, "kccsrv",225 periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", 201 226 "periodic_startup_interval", 15); /* in seconds */ 202 service->periodic.interval = lp _parm_int(task->lp_ctx, NULL, "kccsrv",227 service->periodic.interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", 203 228 "periodic_interval", 300); /* in seconds */ 204 229 … … 212 237 213 238 irpc_add_name(task->msg_ctx, "kccsrv"); 239 240 IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service); 241 IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAGETINFO, kccsrv_replica_get_info, service); 214 242 } 215 243 -
vendor/current/source4/dsdb/kcc/kcc_service.h
r414 r740 79 79 struct tevent_timer *te; 80 80 } periodic; 81 82 time_t last_deleted_check; 83 84 bool am_rodc; 81 85 }; 86 87 struct kcc_connection_list; 82 88 83 89 #include "dsdb/kcc/kcc_service_proto.h"
Note:
See TracChangeset
for help on using the changeset viewer.