📄 wrepl_apply_records.c
字号:
_GR_GA_SI<00> => REPLACE_GR_GA_DI<00> => REPLACE_GR_GT_SI<00> => REPLACE_GR_GT_DI<00> => REPLACE_GR_SA_SI<00> => NOT REPLACE_GR_SA_DI<00> => NOT REPLACE_GR_ST_SI<00> => NOT REPLACE_GR_ST_DI<00> => NOT REPLACE_GR_MA_SI<00> => NOT REPLACE_GR_MA_DI<00> => NOT REPLACE_GR_MT_SI<00> => NOT REPLACE_GR_MT_DI<00> => NOT REPLACE*/static enum _R_ACTION replace_group_owned_vs_X_replica(struct winsdb_record *r1, struct wrepl_name *r2){ if (R_IS_GROUP(r1) && R_IS_GROUP(r2)) { if (!R_IS_ACTIVE(r1) || R_IS_ACTIVE(r2)) { /* REPLACE */ return R_DO_REPLACE; } } /* NOT REPLACE, but PROPAGATE */ return R_DO_PROPAGATE;}/*active (not sgroup vs. sgroup yet!):_SA_UA_SI_U<1c> => NOT REPLACE_SA_UA_DI_U<1c> => NOT REPLACE_SA_UT_SI_U<1c> => NOT REPLACE_SA_UT_DI_U<1c> => NOT REPLACE_SA_GA_SI_U<1c> => NOT REPLACE_SA_GA_DI_U<1c> => NOT REPLACE_SA_GT_SI_U<1c> => NOT REPLACE_SA_GT_DI_U<1c> => NOT REPLACE_SA_MA_SI_U<1c> => NOT REPLACE_SA_MA_DI_U<1c> => NOT REPLACE_SA_MT_SI_U<1c> => NOT REPLACE_SA_MT_DI_U<1c> => NOT REPLACETest Replica vs. owned active: SGROUP vs. SGROUP tests_SA_SA_DI_U<1c> => SGROUP_MERGE_SA_SA_SI_U<1c> => SGROUP_MERGE_SA_SA_SP_U<1c> => SGROUP_MERGE_SA_SA_SB_U<1c> => SGROUP_MERGE_SA_ST_DI_U<1c> => NOT REPLACE_SA_ST_SI_U<1c> => NOT REPLACE_SA_ST_SP_U<1c> => NOT REPLACE_SA_ST_SB_U<1c> => NOT REPLACESGROUP,ACTIVE vs. SGROUP,* is not handled here!released:_SR_UA_SI<1c> => REPLACE_SR_UA_DI<1c> => REPLACE_SR_UT_SI<1c> => REPLACE_SR_UT_DI<1c> => REPLACE_SR_GA_SI<1c> => REPLACE_SR_GA_DI<1c> => REPLACE_SR_GT_SI<1c> => REPLACE_SR_GT_DI<1c> => REPLACE_SR_SA_SI<1c> => REPLACE_SR_SA_DI<1c> => REPLACE_SR_ST_SI<1c> => REPLACE_SR_ST_DI<1c> => REPLACE_SR_MA_SI<1c> => REPLACE_SR_MA_DI<1c> => REPLACE_SR_MT_SI<1c> => REPLACE_SR_MT_DI<1c> => REPLACE*/static enum _R_ACTION replace_sgroup_owned_vs_X_replica(struct winsdb_record *r1, struct wrepl_name *r2){ if (!R_IS_ACTIVE(r1)) { /* REPLACE */ return R_DO_REPLACE; } if (!R_IS_SGROUP(r2) || !R_IS_ACTIVE(r2)) { /* NOT REPLACE, but PROPAGATE */ return R_DO_PROPAGATE; } if (r_1_is_same_as_2_address_list(r1, r2, true)) { /* * as we're the old owner and the addresses and their * owners are identical */ return R_NOT_REPLACE; } /* not handled here: MERGE */ return R_DO_SGROUP_MERGE;}/*active:_MA_UA_SI_U<00> => REPLACE_MA_UA_DI_P<00> => NOT REPLACE_MA_UA_DI_O<00> => NOT REPLACE_MA_UA_DI_N<00> => REPLACE_MA_UT_SI_U<00> => NOT REPLACE_MA_UT_DI_U<00> => NOT REPLACE_MA_GA_SI_R<00> => REPLACE_MA_GA_DI_R<00> => REPLACE_MA_GT_SI_U<00> => NOT REPLACE_MA_GT_DI_U<00> => NOT REPLACE_MA_SA_SI_R<00> => REPLACE_MA_SA_DI_R<00> => REPLACE_MA_ST_SI_U<00> => NOT REPLACE_MA_ST_DI_U<00> => NOT REPLACE_MA_MA_SI_U<00> => REPLACE_MA_MA_SP_U<00> => REPLACE_MA_MA_DI_P<00> => NOT REPLACE_MA_MA_DI_O<00> => NOT REPLACE_MA_MA_DI_N<00> => REPLACE_MA_MT_SI_U<00> => NOT REPLACE_MA_MT_DI_U<00> => NOT REPLACETest Replica vs. owned active: some more MHOMED combinations_MA_MA_SP_U<00> => REPLACE_MA_MA_SM_U<00> => REPLACE_MA_MA_SB_P<00> => MHOMED_MERGE_MA_MA_SB_A<00> => MHOMED_MERGE_MA_MA_SB_PRA<00> => NOT REPLACE_MA_MA_SB_O<00> => NOT REPLACE_MA_MA_SB_N<00> => REPLACETest Replica vs. owned active: some more UNIQUE,MHOMED combinations_MA_UA_SB_P<00> => MHOMED_MERGEreleased:_MR_UA_SI<00> => REPLACE_MR_UA_DI<00> => REPLACE_MR_UT_SI<00> => REPLACE_MR_UT_DI<00> => REPLACE_MR_GA_SI<00> => REPLACE_MR_GA_DI<00> => REPLACE_MR_GT_SI<00> => REPLACE_MR_GT_DI<00> => REPLACE_MR_SA_SI<00> => REPLACE_MR_SA_DI<00> => REPLACE_MR_ST_SI<00> => REPLACE_MR_ST_DI<00> => REPLACE_MR_MA_SI<00> => REPLACE_MR_MA_DI<00> => REPLACE_MR_MT_SI<00> => REPLACE_MR_MT_DI<00> => REPLACE*/static enum _R_ACTION replace_mhomed_owned_vs_X_replica(struct winsdb_record *r1, struct wrepl_name *r2){ if (!R_IS_ACTIVE(r1)) { /* REPLACE */ return R_DO_REPLACE; } if (!R_IS_ACTIVE(r2)) { /* NOT REPLACE, but PROPAGATE */ return R_DO_PROPAGATE; } if (R_IS_GROUP(r2) || R_IS_SGROUP(r2)) { /* REPLACE and send a release demand to the old name owner */ return R_DO_RELEASE_DEMAND; } /* * here we only have mhomed,active,owned vs. * is unique,active,replica or mhomed,active,replica */ if (r_1_is_subset_of_2_address_list(r1, r2, false)) { /* * if r1 has a subset(or same) of the addresses of r2 * <=> * if r2 has a superset(or same) of the addresses of r1 * * then replace the record */ return R_DO_REPLACE; } /* * in any other case, we need to do * a name request to the old name holder * to see if it's still there... */ return R_DO_CHALLENGE;}static NTSTATUS r_do_add(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct wrepl_wins_owner *owner, struct wrepl_name *replica){ struct winsdb_record *rec; uint32_t i; uint8_t ret; rec = talloc(mem_ctx, struct winsdb_record); NT_STATUS_HAVE_NO_MEMORY(rec); rec->name = &replica->name; rec->type = replica->type; rec->state = replica->state; rec->node = replica->node; rec->is_static = replica->is_static; rec->expire_time= time(NULL) + partner->service->config.verify_interval; rec->version = replica->version_id; rec->wins_owner = replica->owner; rec->addresses = winsdb_addr_list_make(rec); NT_STATUS_HAVE_NO_MEMORY(rec->addresses); rec->registered_by = NULL; for (i=0; i < replica->num_addresses; i++) { /* TODO: find out if rec->expire_time is correct here */ rec->addresses = winsdb_addr_list_add(partner->service->wins_db, rec, rec->addresses, replica->addresses[i].address, replica->addresses[i].owner, rec->expire_time, false); NT_STATUS_HAVE_NO_MEMORY(rec->addresses); } ret = winsdb_add(partner->service->wins_db, rec, 0); if (ret != NBT_RCODE_OK) { DEBUG(0,("Failed to add record %s: %u\n", nbt_name_string(mem_ctx, &replica->name), ret)); return NT_STATUS_FOOBAR; } DEBUG(4,("added record %s\n", nbt_name_string(mem_ctx, &replica->name))); return NT_STATUS_OK;}static NTSTATUS r_do_replace(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct winsdb_record *rec, struct wrepl_wins_owner *owner, struct wrepl_name *replica){ uint32_t i; uint8_t ret; rec->name = &replica->name; rec->type = replica->type; rec->state = replica->state; rec->node = replica->node; rec->is_static = replica->is_static; rec->expire_time= time(NULL) + partner->service->config.verify_interval; rec->version = replica->version_id; rec->wins_owner = replica->owner; rec->addresses = winsdb_addr_list_make(rec); NT_STATUS_HAVE_NO_MEMORY(rec->addresses); rec->registered_by = NULL; for (i=0; i < replica->num_addresses; i++) { /* TODO: find out if rec->expire_time is correct here */ rec->addresses = winsdb_addr_list_add(partner->service->wins_db, rec, rec->addresses, replica->addresses[i].address, replica->addresses[i].owner, rec->expire_time, false); NT_STATUS_HAVE_NO_MEMORY(rec->addresses); } ret = winsdb_modify(partner->service->wins_db, rec, 0); if (ret != NBT_RCODE_OK) { DEBUG(0,("Failed to replace record %s: %u\n", nbt_name_string(mem_ctx, &replica->name), ret)); return NT_STATUS_FOOBAR; } DEBUG(4,("replaced record %s\n", nbt_name_string(mem_ctx, &replica->name))); return NT_STATUS_OK;}static NTSTATUS r_not_replace(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct winsdb_record *rec, struct wrepl_wins_owner *owner, struct wrepl_name *replica){ DEBUG(4,("not replace record %s\n", nbt_name_string(mem_ctx, &replica->name))); return NT_STATUS_OK;}static NTSTATUS r_do_propagate(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct winsdb_record *rec, struct wrepl_wins_owner *owner, struct wrepl_name *replica){ uint8_t ret; uint32_t modify_flags; /* * allocate a new version id for the record to that it'll be replicated */ modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP; ret = winsdb_modify(partner->service->wins_db, rec, modify_flags); if (ret != NBT_RCODE_OK) { DEBUG(0,("Failed to replace record %s: %u\n", nbt_name_string(mem_ctx, &replica->name), ret)); return NT_STATUS_FOOBAR; } DEBUG(4,("propagated record %s\n", nbt_name_string(mem_ctx, &replica->name))); return NT_STATUS_OK;}/* Test Replica vs. owned active: some more MHOMED combinations_MA_MA_SP_U<00>: C:MHOMED vs. B:ALL => B:ALL => REPLACE_MA_MA_SM_U<00>: C:MHOMED vs. B:MHOMED => B:MHOMED => REPLACE_MA_MA_SB_P<00>: C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE_MA_MA_SB_A<00>: C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED => MHOMED_MERGE_MA_MA_SB_PRA<00>: C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED => NOT REPLACE_MA_MA_SB_O<00>: C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED => NOT REPLACE_MA_MA_SB_N<00>: C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST => REPLACETest Replica vs. owned active: some more UNIQUE,MHOMED combinations_MA_UA_SB_P<00>: C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE_UA_UA_DI_PRA<00>: C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST => NOT REPLACE_UA_UA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE_UA_MA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE*/static NTSTATUS r_do_mhomed_merge(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct winsdb_record *rec, struct wrepl_wins_owner *owner, struct wrepl_name *replica){ struct winsdb_record *merge; uint32_t i,j; uint8_t ret; size_t len; merge = talloc(mem_ctx, struct winsdb_record); NT_STATUS_HAVE_NO_MEMORY(merge); merge->name = &replica->name; merge->type = WREPL_TYPE_MHOMED; merge->state = replica->state; merge->node = replica->node; merge->is_static = replica->is_static; merge->expire_time = time(NULL) + partner->service->config.verify_interval; merge->version = replica->version_id; merge->wins_owner = replica->owner; merge->addresses = winsdb_addr_list_make(merge); NT_STATUS_HAVE_NO_MEMORY(merge->addresses); merge->registered_by = NULL; for (i=0; i < replica->num_addresses; i++) { merge->addresses = winsdb_addr_list_add(partner->service->wins_db, merge, merge->addresses, replica->addresses[i].address, replica->addresses[i].owner, merge->expire_time, false); NT_STATUS_HAVE_NO_MEMORY(merge->addresses); } len = winsdb_addr_list_length(rec->addresses); for (i=0; i < len; i++) { bool found = false; for (j=0; j < replica->num_addresses; j++) { if (strcmp(replica->addresses[j].address, rec->addresses[i]->address) == 0) { found = true; break; } } if (found) continue; merge->addresses = winsdb_addr_list_add(partner->service->wins_db, merge, merge->addresses, rec->addresses[i]->address, rec->addresses[i]->wins_owner, rec->addresses[i]->expire_time, false); NT_STATUS_HAVE_NO_MEMORY(merge->addresses); } ret = winsdb_modify(partner->service->wins_db, merge, 0); if (ret != NBT_RCODE_OK) { DEBUG(0,("Failed to modify mhomed merge record %s: %u\n", nbt_name_string(mem_ctx, &replica->name), ret)); return NT_STATUS_FOOBAR; } DEBUG(4,("mhomed merge record %s\n", nbt_name_string(mem_ctx, &replica->name))); return NT_STATUS_OK;}struct r_do_challenge_state { struct messaging_context *msg_ctx; struct wreplsrv_partner *partner; struct winsdb_record *rec; struct wrepl_wins_owner owner; struct wrepl_name replica; struct nbtd_proxy_wins_challenge r;};static void r_do_late_release_demand_handler(struct irpc_request *ireq){ NTSTATUS status; struct r_do_challenge_state *state = talloc_get_type(ireq->async.private, struct r_do_challenge_state); status = irpc_call_recv(ireq); /* don't care about the result */ talloc_free(state);}static NTSTATUS r_do_late_release_demand(struct r_do_challenge_state *state){ struct irpc_request *ireq; struct server_id *nbt_servers; struct nbtd_proxy_wins_release_demand r; uint32_t i; DEBUG(4,("late release demand record %s\n", nbt_name_string(state, &state->replica.name))); nbt_servers = irpc_servers_byname(state->msg_ctx, state, "nbt_server"); if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) { return NT_STATUS_INTERNAL_ERROR; } r.in.name = state->replica.name; r.in.num_addrs = state->r.out.num_addrs; r.in.addrs = talloc_array(state, struct nbtd_proxy_wins_addr, r.in.num_addrs); NT_STATUS_HAVE_NO_MEMORY(r.in.addrs); /* TODO: fix pidl to handle inline ipv4address arrays */ for (i=0; i < r.in.num_addrs; i++) { r.in.addrs[i].addr = state->r.out.addrs[i].addr; } ireq = IRPC_CALL_SEND(state->msg_ctx, nbt_servers[0], irpc, NBTD_PROXY_WINS_RELEASE_DEMAND, &r, state); NT_STATUS_HAVE_NO_MEMORY(ireq); ireq->async.fn = r_do_late_release_demand_handler; ireq->async.private = state; return NT_STATUS_OK;}/* Test Replica vs. owned active: some more MHOMED combinations_MA_MA_SP_U<00>: C:MHOMED vs. B:ALL => B:ALL => REPLACE_MA_MA_SM_U<00>: C:MHOMED vs. B:MHOMED => B:MHOMED => REPLACE_MA_MA_SB_P<00>: C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE_MA_MA_SB_A<00>: C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED => MHOMED_MERGE_MA_MA_SB_PRA<00>: C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED => NOT REPLACE_MA_MA_SB_O<00>: C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED => NOT REPLACE_MA_MA_SB_N<00>: C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST => REPLACETest Replica vs. owned active: some more UNIQUE,MHOMED combinations_MA_UA_SB_P<00>: C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE_UA_UA_DI_PRA<00>: C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST => NOT REPLACE_UA_UA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE_UA_MA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE*/static void r_do_challenge_handler(struct irpc_request *ireq){ NTSTATUS status; struct r_do_challenge_state *state = talloc_get_type(ireq->async.private,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -