From b2da403af9963b9242f0a61ce0ed1d005acf2bd7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:38:07 +0000 Subject: r11007: r10109@SERNOX: metze | 2005-09-09 12:29:12 +0200 - move structs to a seperate header file - move the code for the wreplsrv_in_call handling to a seperate file metze (This used to be commit c9a8544446312d96ecadcf370af76d9dc5b2531a) --- source4/wrepl_server/wrepl_in_call.c | 109 +++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 source4/wrepl_server/wrepl_in_call.c (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c new file mode 100644 index 0000000000..444fda544b --- /dev/null +++ b/source4/wrepl_server/wrepl_in_call.c @@ -0,0 +1,109 @@ +/* + Unix SMB/CIFS implementation. + + WINS Replication server + + Copyright (C) Stefan Metzmacher 2005 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "dlinklist.h" +#include "lib/events/events.h" +#include "lib/socket/socket.h" +#include "smbd/service_task.h" +#include "smbd/service_stream.h" +#include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_winsrepl.h" +#include "wrepl_server/wrepl_server.h" + +static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) +{ + struct wrepl_stop *stop; + + call->rep_packet.opcode = WREPL_OPCODE_BITS; + call->rep_packet.assoc_ctx = 0; + call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; + stop = &call->rep_packet.message.stop; + stop->reason = 4; + + return NT_STATUS_OK; +} + +static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) +{ + struct wrepl_replication *repl_in = &call->req_packet.message.replication; + struct wrepl_stop *stop_out; + + switch (repl_in->command) { + case WREPL_REPL_TABLE_QUERY: + break; + case WREPL_REPL_TABLE_REPLY: + break; + case WREPL_REPL_SEND_REQUEST: + break; + case WREPL_REPL_SEND_REPLY: + break; + case WREPL_REPL_UPDATE: + break; + case WREPL_REPL_5: + break; + case WREPL_REPL_INFORM: + break; + case WREPL_REPL_9: + break; + } + + call->rep_packet.opcode = WREPL_OPCODE_BITS; + call->rep_packet.assoc_ctx = 0; + call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; + stop_out = &call->rep_packet.message.stop; + stop_out->reason = 4; + + return NT_STATUS_OK; +} + +NTSTATUS wreplsrv_in_call(struct wreplsrv_in_call *call) +{ + struct wrepl_stop *stop_out; + + /* TODO: check opcode and assoc_ctx */ + + switch (call->req_packet.mess_type) { + case WREPL_START_ASSOCIATION: + return wreplsrv_in_start_association(call); + + case WREPL_START_ASSOCIATION_REPLY: + /* this is not valid here */ + break; + case WREPL_STOP_ASSOCIATION: + /* this is not valid here */ + break; + + case WREPL_REPLICATION: + return wreplsrv_in_replication(call); + } + + call->rep_packet.opcode = WREPL_OPCODE_BITS; + call->rep_packet.assoc_ctx = 0; + call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; + call->rep_packet.padding = data_blob(NULL, 0); + stop_out = &call->rep_packet.message.stop; + stop_out->reason = 4; + + return NT_STATUS_OK; +} + -- cgit From d49e67f06f55054f23dbef609b4debb11c157ffa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:44:47 +0000 Subject: r11014: r10139@SERNOX: metze | 2005-09-10 10:32:36 +0200 - w2k just ignores invalid packets, so we do now - w2k only checks the assoc_ctx when the opcode has the sepcific obcode bit's set - terminate the connection, when getting a WREPL_STOP_ASSOCIATION packet - some more special error handling proper torture test for all this cases are following later metze (This used to be commit 42b69461aad3942dde361d61b950445dd39882aa) --- source4/wrepl_server/wrepl_in_call.c | 150 ++++++++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 27 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 444fda544b..9158b1a741 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -32,21 +32,96 @@ static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { - struct wrepl_stop *stop; + struct wrepl_start *start = &call->req_packet.message.start; + struct wrepl_start *start_reply = &call->rep_packet.message.start_reply; + + if (call->req_packet.opcode & WREPL_OPCODE_BITS) { + /* + *if the assoc_ctx doesn't match ignore the packet + */ + if ((call->req_packet.assoc_ctx != call->wreplconn->assoc_ctx.our_ctx) + && (call->req_packet.assoc_ctx != 0)) { + return ERROR_INVALID_PARAMETER; + } + } else { + call->wreplconn->assoc_ctx.our_ctx = WREPLSRV_INVALID_ASSOC_CTX; + return NT_STATUS_OK; + } - call->rep_packet.opcode = WREPL_OPCODE_BITS; - call->rep_packet.assoc_ctx = 0; - call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; - stop = &call->rep_packet.message.stop; - stop->reason = 4; + if (start->minor_version != 2 || start->major_version != 5) { + /* w2k terminate the connection if the versions doesn't match */ + return NT_STATUS_UNKNOWN_REVISION; + } + + call->wreplconn->assoc_ctx.stopped = False; + call->wreplconn->assoc_ctx.our_ctx = WREPLSRV_VALID_ASSOC_CTX; + call->wreplconn->assoc_ctx.peer_ctx = start->assoc_ctx; + + call->rep_packet.mess_type = WREPL_START_ASSOCIATION_REPLY; + start_reply->assoc_ctx = call->wreplconn->assoc_ctx.our_ctx; + start_reply->minor_version = 2; + start_reply->major_version = 5; return NT_STATUS_OK; } +static NTSTATUS wreplsrv_in_stop_assoc_ctx(struct wreplsrv_in_call *call) +{ + struct wrepl_stop *stop_out = &call->rep_packet.message.stop; + + call->wreplconn->assoc_ctx.stopped = True; + + call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; + stop_out->reason = 4; + + return NT_STATUS_OK; +} + +static NTSTATUS wreplsrv_in_stop_association(struct wreplsrv_in_call *call) +{ + /* + * w2k only check the assoc_ctx if the opcode has the 0x00007800 bits are set + */ + if (call->req_packet.opcode & WREPL_OPCODE_BITS) { + /* + *if the assoc_ctx doesn't match ignore the packet + */ + if (call->req_packet.assoc_ctx != call->wreplconn->assoc_ctx.our_ctx) { + return ERROR_INVALID_PARAMETER; + } + /* when the opcode bits are set the connection should be directly terminated */ + return NT_STATUS_CONNECTION_RESET; + } + + if (call->wreplconn->assoc_ctx.stopped) { + /* this causes the connection to be directly terminated */ + return NT_STATUS_CONNECTION_RESET; + } + + /* this will cause to not receive packets anymore and terminate the connection if the reply is send */ + call->wreplconn->terminate = True; + return wreplsrv_in_stop_assoc_ctx(call); +} + static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) { struct wrepl_replication *repl_in = &call->req_packet.message.replication; - struct wrepl_stop *stop_out; + + /* + * w2k only check the assoc_ctx if the opcode has the 0x00007800 bits are set + */ + if (call->req_packet.opcode & WREPL_OPCODE_BITS) { + /* + *if the assoc_ctx doesn't match ignore the packet + */ + if (call->req_packet.assoc_ctx != call->wreplconn->assoc_ctx.our_ctx) { + return ERROR_INVALID_PARAMETER; + } + } + + if (!call->wreplconn->partner) { + return wreplsrv_in_stop_assoc_ctx(call); + } switch (repl_in->command) { case WREPL_REPL_TABLE_QUERY: @@ -67,43 +142,64 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) break; } - call->rep_packet.opcode = WREPL_OPCODE_BITS; + return ERROR_INVALID_PARAMETER; +} + +static NTSTATUS wreplsrv_in_invalid_assoc_ctx(struct wreplsrv_in_call *call) +{ + struct wrepl_start *start = &call->rep_packet.message.start; + + call->rep_packet.opcode = 0x00008583; call->rep_packet.assoc_ctx = 0; - call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; - stop_out = &call->rep_packet.message.stop; - stop_out->reason = 4; + call->rep_packet.mess_type = WREPL_START_ASSOCIATION; + + start->assoc_ctx = 0x0000000a; + start->minor_version = 0x0001; + start->major_version = 0x0000; + + call->rep_packet.padding = data_blob_talloc(call, NULL, 4); + memset(call->rep_packet.padding.data, '\0', call->rep_packet.padding.length); return NT_STATUS_OK; } NTSTATUS wreplsrv_in_call(struct wreplsrv_in_call *call) { - struct wrepl_stop *stop_out; + NTSTATUS status; - /* TODO: check opcode and assoc_ctx */ + if (!(call->req_packet.opcode & WREPL_OPCODE_BITS) + && (call->wreplconn->assoc_ctx.our_ctx == WREPLSRV_INVALID_ASSOC_CTX)) { + return wreplsrv_in_invalid_assoc_ctx(call); + } switch (call->req_packet.mess_type) { case WREPL_START_ASSOCIATION: - return wreplsrv_in_start_association(call); - - case WREPL_START_ASSOCIATION_REPLY: - /* this is not valid here */ + status = wreplsrv_in_start_association(call); break; + case WREPL_START_ASSOCIATION_REPLY: + /* this is not valid here, so we ignore it */ + return ERROR_INVALID_PARAMETER; + case WREPL_STOP_ASSOCIATION: - /* this is not valid here */ + status = wreplsrv_in_stop_association(call); break; case WREPL_REPLICATION: - return wreplsrv_in_replication(call); + status = wreplsrv_in_replication(call); + break; + default: + /* everythingelse is also not valid here, so we ignore it */ + return ERROR_INVALID_PARAMETER; } - call->rep_packet.opcode = WREPL_OPCODE_BITS; - call->rep_packet.assoc_ctx = 0; - call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; - call->rep_packet.padding = data_blob(NULL, 0); - stop_out = &call->rep_packet.message.stop; - stop_out->reason = 4; + if (call->wreplconn->assoc_ctx.our_ctx == WREPLSRV_INVALID_ASSOC_CTX) { + return wreplsrv_in_invalid_assoc_ctx(call); + } - return NT_STATUS_OK; -} + if (NT_STATUS_IS_OK(status)) { + call->rep_packet.opcode = WREPL_OPCODE_BITS; + call->rep_packet.assoc_ctx = call->wreplconn->assoc_ctx.peer_ctx; + } + return status; +} -- cgit From 8bb5bcb6745661692f1116da67368a58910ce111 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:52:51 +0000 Subject: r11033: r10343@SERNOX: metze | 2005-09-20 11:03:20 +0200 - reply to table_queries - reply to a send_request with an empty send_reply metze (This used to be commit a25279f05243fc89c2cc9267d59974bc17eaf47c) --- source4/wrepl_server/wrepl_in_call.c | 88 +++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 7 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 9158b1a741..a67f20a480 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -29,6 +29,7 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_winsrepl.h" #include "wrepl_server/wrepl_server.h" +#include "nbt_server/wins/winsdb.h" static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { @@ -103,9 +104,66 @@ static NTSTATUS wreplsrv_in_stop_association(struct wreplsrv_in_call *call) return wreplsrv_in_stop_assoc_ctx(call); } +static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) +{ + struct wreplsrv_service *service = call->wreplconn->service; + struct wrepl_replication *repl_out = &call->rep_packet.message.replication; + struct wrepl_table *table_out = &call->rep_packet.message.replication.info.table; + struct wreplsrv_owner *cur; + uint64_t local_max_version; + uint32_t i = 0; + + repl_out->command = WREPL_REPL_TABLE_REPLY; + + table_out->partner_count = 0; + table_out->partners = NULL; + table_out->initiator = WINSDB_OWNER_LOCAL; + + local_max_version = wreplsrv_local_max_version(service); + if (local_max_version > 0) { + table_out->partner_count++; + } + + for (cur = service->table; cur; cur = cur->next) { + table_out->partner_count++; + } + + table_out->partners = talloc_array(call, struct wrepl_wins_owner, table_out->partner_count); + NT_STATUS_HAVE_NO_MEMORY(table_out->partners); + + if (local_max_version > 0) { + table_out->partners[i].address = call->wreplconn->our_ip; + table_out->partners[i].min_version = 0; + table_out->partners[i].max_version = local_max_version; + table_out->partners[i].type = 1; + i++; + } + + for (cur = service->table; cur; cur = cur->next) { + table_out->partners[i] = cur->owner; + i++; + } + + return NT_STATUS_OK; +} + +static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) +{ + struct wrepl_replication *repl_out = &call->rep_packet.message.replication; + struct wrepl_send_reply *reply_out = &call->rep_packet.message.replication.info.reply; + + repl_out->command = WREPL_REPL_SEND_REPLY; + + reply_out->num_names = 0; + reply_out->names = NULL; + + return NT_STATUS_OK; +} + static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) { struct wrepl_replication *repl_in = &call->req_packet.message.replication; + NTSTATUS status; /* * w2k only check the assoc_ctx if the opcode has the 0x00007800 bits are set @@ -125,24 +183,40 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) switch (repl_in->command) { case WREPL_REPL_TABLE_QUERY: + status = wreplsrv_in_table_query(call); break; + case WREPL_REPL_TABLE_REPLY: - break; + return ERROR_INVALID_PARAMETER; + case WREPL_REPL_SEND_REQUEST: + status = wreplsrv_in_send_request(call); break; + case WREPL_REPL_SEND_REPLY: - break; + return ERROR_INVALID_PARAMETER; + case WREPL_REPL_UPDATE: - break; + return ERROR_INVALID_PARAMETER; + case WREPL_REPL_5: - break; + return ERROR_INVALID_PARAMETER; + case WREPL_REPL_INFORM: - break; + return ERROR_INVALID_PARAMETER; + case WREPL_REPL_9: - break; + return ERROR_INVALID_PARAMETER; + + default: + return ERROR_INVALID_PARAMETER; } - return ERROR_INVALID_PARAMETER; + if (NT_STATUS_IS_OK(status)) { + call->rep_packet.mess_type = WREPL_REPLICATION; + } + + return status; } static NTSTATUS wreplsrv_in_invalid_assoc_ctx(struct wreplsrv_in_call *call) -- cgit From 2f54bab9514bf9af898a12173d0871684c94fa2e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:54:26 +0000 Subject: r11036: r10349@SERNOX: metze | 2005-09-20 15:38:31 +0200 we know answer send_requests correctly metze (This used to be commit aecc9ca1cc78ce5ea766954629c03ea866c36bc1) --- source4/wrepl_server/wrepl_in_call.c | 138 ++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 2 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index a67f20a480..6dd1c0fe47 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -28,8 +28,10 @@ #include "smbd/service_stream.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_winsrepl.h" +#include "librpc/gen_ndr/ndr_nbt.h" #include "wrepl_server/wrepl_server.h" #include "nbt_server/wins/winsdb.h" +#include "lib/ldb/include/ldb.h" static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { @@ -147,16 +149,148 @@ static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) return NT_STATUS_OK; } +static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, + struct wrepl_wins_name *n2) +{ + if (n1->id < n2->id) return -1; + if (n1->id > n2->id) return 1; + return 0; +} + +static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, struct wrepl_wins_name *name, struct winsdb_record *rec) +{ + uint8_t *namebuf; + uint32_t namebuf_len; + uint32_t name_len; + + name_len = strlen(rec->name->name); + if (name_len > 15) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + namebuf = (uint8_t *)talloc_asprintf(mem_ctx, "%-15s%c%s", + rec->name->name, rec->name->type, + (rec->name->scope?rec->name->scope:"")); + NT_STATUS_HAVE_NO_MEMORY(namebuf); + namebuf_len = strlen((char *)namebuf) + 1; + + /* oh wow, what a nasty bug in windows ... */ + if (namebuf[15] == 0x1b && namebuf_len >= 16) { + namebuf[15] = namebuf[0]; + namebuf[0] = 0x1b; + } + + name->name_len = namebuf_len; + name->name = namebuf; + name->id = rec->version; + name->unknown = WINSDB_GROUP_ADDRESS; + + name->flags = rec->nb_flags; + name->group_flag = 0; + + switch (name->flags & 2) { + case 0: + name->addresses.ip = rec->addresses[0]->address; + talloc_steal(mem_ctx, rec->addresses[0]->address); + break; + case 2: + name->addresses.addresses.num_ips = 0; + name->addresses.addresses.ips = NULL; + break; + } + + return NT_STATUS_OK; +} + static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) { + struct wreplsrv_service *service = call->wreplconn->service; + struct wrepl_wins_owner *owner_in = &call->req_packet.message.replication.info.owner; struct wrepl_replication *repl_out = &call->rep_packet.message.replication; struct wrepl_send_reply *reply_out = &call->rep_packet.message.replication.info.reply; + struct wreplsrv_owner local_owner; + struct wreplsrv_owner *owner; + const char *filter; + struct ldb_message **res = NULL; + int ret; + struct wrepl_wins_name *names; + struct winsdb_record *rec; + NTSTATUS status; + uint32_t i; + + if (strcmp(call->wreplconn->our_ip, owner_in->address) == 0) { + ZERO_STRUCT(local_owner); + local_owner.owner.address = WINSDB_OWNER_LOCAL; + local_owner.owner.min_version = 0; + local_owner.owner.max_version = wreplsrv_local_max_version(service); + local_owner.owner.type = 1; + owner = &local_owner; + } else { + owner = wreplsrv_find_owner(service->table, owner_in->address); + } - repl_out->command = WREPL_REPL_SEND_REPLY; - + repl_out->command = WREPL_REPL_SEND_REPLY; reply_out->num_names = 0; reply_out->names = NULL; + /* + * if we didn't know this owner, must be a bug in the partners client code... + * return an empty list. + */ + if (!owner) { + return NT_STATUS_OK; + } + + /* + * if the partner ask for nothing, or give invalid ranges, + * return an empty list. + */ + if (owner_in->min_version >= owner_in->max_version) { + return NT_STATUS_OK; + } + + /* + * if the partner has already all records for nothing, or give invalid ranges, + * return an empty list. + */ + if (owner_in->min_version >= owner->owner.max_version) { + return NT_STATUS_OK; + } + + filter = talloc_asprintf(call, "(&(winsOwner=%s)(objectClass=wins)(active=1)(version>=%llu)(version<=%llu))", + owner->owner.address, owner_in->min_version, owner_in->max_version); + NT_STATUS_HAVE_NO_MEMORY(filter); + ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); + if (res != NULL) { + talloc_steal(call, res); + } + if (ret < 0) return NT_STATUS_INTERNAL_DB_CORRUPTION; + if (ret == 0) return NT_STATUS_OK; + + names = talloc_array(call, struct wrepl_wins_name, ret); + NT_STATUS_HAVE_NO_MEMORY(names); + + for (i=0; i < ret; i++) { + rec = winsdb_record(res[i], call); + NT_STATUS_HAVE_NO_MEMORY(rec); + + rec->name = winsdb_nbt_name(names, res[i]->dn); + if (!rec->name) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = wreplsrv_record2wins_name(names, &names[i], rec); + NT_STATUS_NOT_OK_RETURN(status); + talloc_free(rec); + talloc_free(res[i]); + } + + /* sort the names before we send them */ + qsort(names, ret, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); + + reply_out->num_names = ret; + reply_out->names = names; + return NT_STATUS_OK; } -- cgit From b3d0ac41db7638bdd3539391c65e6e7bf9fdf7a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:55:27 +0000 Subject: r11038: r10351@SERNOX: metze | 2005-09-20 16:11:17 +0200 fix namebuf_len, when type is 0x00 metze (This used to be commit 1b2effa01bf16f9575e7e43e037a0797f98426b8) --- source4/wrepl_server/wrepl_in_call.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 6dd1c0fe47..ab86aa209f 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -169,13 +169,19 @@ static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, struct wrepl_wins } namebuf = (uint8_t *)talloc_asprintf(mem_ctx, "%-15s%c%s", - rec->name->name, rec->name->type, + rec->name->name, 'X', (rec->name->scope?rec->name->scope:"")); NT_STATUS_HAVE_NO_MEMORY(namebuf); namebuf_len = strlen((char *)namebuf) + 1; + /* + * we need to set the type here, and use a place-holder in the talloc_asprintf() + * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results + */ + namebuf[15] = rec->name->type; + /* oh wow, what a nasty bug in windows ... */ - if (namebuf[15] == 0x1b && namebuf_len >= 16) { + if (rec->name->type == 0x1b) { namebuf[15] = namebuf[0]; namebuf[0] = 0x1b; } -- cgit From 676b220f3e8c975824bfdae407e9f7938d79118c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:55:59 +0000 Subject: r11040: r10357@SERNOX: metze | 2005-09-20 21:28:11 +0200 - as the old records are broken sinse the last winsdb_dn() changes, (the dn components order was reversed) we can use nicer attribute and objectClass names... - use much more verbose error handling for winsdb_* - print a debug message when we found a corrupted record metze (This used to be commit 82bad3f3efec5b706a65e65054787f1486d7c875) --- source4/wrepl_server/wrepl_in_call.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index ab86aa209f..4472a0fede 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -263,8 +263,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) return NT_STATUS_OK; } - filter = talloc_asprintf(call, "(&(winsOwner=%s)(objectClass=wins)(active=1)(version>=%llu)(version<=%llu))", - owner->owner.address, owner_in->min_version, owner_in->max_version); + filter = talloc_asprintf(call, "(&(winsOwner=%s)(objectClass=winsRecord)(state>=%u)(versionID>=%llu)(versionID<=%llu))", + owner->owner.address, WINS_REC_ACTIVE, owner_in->min_version, owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); if (res != NULL) { @@ -277,13 +277,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) NT_STATUS_HAVE_NO_MEMORY(names); for (i=0; i < ret; i++) { - rec = winsdb_record(res[i], call); - NT_STATUS_HAVE_NO_MEMORY(rec); - - rec->name = winsdb_nbt_name(names, res[i]->dn); - if (!rec->name) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + status = winsdb_record(res[i], NULL, call, &rec); + NT_STATUS_NOT_OK_RETURN(status); status = wreplsrv_record2wins_name(names, &names[i], rec); NT_STATUS_NOT_OK_RETURN(status); -- cgit From cffd522b5c806508dfacfb10234e4c0a115c0a98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 14:02:47 +0000 Subject: r11052: bring samba4 uptodate with the samba4-winsrepl branch, before the bad merge metze (This used to be commit 471c0ca4abb17fb5f73c0efed195c67628c1c06e) --- source4/wrepl_server/wrepl_in_call.c | 258 ++++++++++++++++++++++++----------- 1 file changed, 180 insertions(+), 78 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 4472a0fede..7ccb52cc20 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -29,7 +29,10 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_winsrepl.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "libcli/wrepl/winsrepl.h" #include "wrepl_server/wrepl_server.h" +#include "wrepl_server/wrepl_out_helpers.h" +#include "libcli/composite/composite.h" #include "nbt_server/wins/winsdb.h" #include "lib/ldb/include/ldb.h" @@ -111,42 +114,12 @@ static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) struct wreplsrv_service *service = call->wreplconn->service; struct wrepl_replication *repl_out = &call->rep_packet.message.replication; struct wrepl_table *table_out = &call->rep_packet.message.replication.info.table; - struct wreplsrv_owner *cur; - uint64_t local_max_version; - uint32_t i = 0; + const char *our_ip = call->wreplconn->our_ip; repl_out->command = WREPL_REPL_TABLE_REPLY; - table_out->partner_count = 0; - table_out->partners = NULL; - table_out->initiator = WINSDB_OWNER_LOCAL; - - local_max_version = wreplsrv_local_max_version(service); - if (local_max_version > 0) { - table_out->partner_count++; - } - - for (cur = service->table; cur; cur = cur->next) { - table_out->partner_count++; - } - - table_out->partners = talloc_array(call, struct wrepl_wins_owner, table_out->partner_count); - NT_STATUS_HAVE_NO_MEMORY(table_out->partners); - - if (local_max_version > 0) { - table_out->partners[i].address = call->wreplconn->our_ip; - table_out->partners[i].min_version = 0; - table_out->partners[i].max_version = local_max_version; - table_out->partners[i].type = 1; - i++; - } - - for (cur = service->table; cur; cur = cur->next) { - table_out->partners[i] = cur->owner; - i++; - } - - return NT_STATUS_OK; + return wreplsrv_fill_wrepl_table(service, call, table_out, + our_ip, our_ip, True); } static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, @@ -157,42 +130,21 @@ static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, return 0; } -static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, struct wrepl_wins_name *name, struct winsdb_record *rec) +static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, + const char *our_address, + struct wrepl_wins_name *name, + struct winsdb_record *rec) { - uint8_t *namebuf; - uint32_t namebuf_len; - uint32_t name_len; - - name_len = strlen(rec->name->name); - if (name_len > 15) { - return NT_STATUS_INVALID_PARAMETER_MIX; - } - - namebuf = (uint8_t *)talloc_asprintf(mem_ctx, "%-15s%c%s", - rec->name->name, 'X', - (rec->name->scope?rec->name->scope:"")); - NT_STATUS_HAVE_NO_MEMORY(namebuf); - namebuf_len = strlen((char *)namebuf) + 1; - - /* - * we need to set the type here, and use a place-holder in the talloc_asprintf() - * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results - */ - namebuf[15] = rec->name->type; + uint32_t num_ips, i; + struct wrepl_ip *ips; - /* oh wow, what a nasty bug in windows ... */ - if (rec->name->type == 0x1b) { - namebuf[15] = namebuf[0]; - namebuf[0] = 0x1b; - } + name->name = rec->name; + talloc_steal(mem_ctx, rec->name); - name->name_len = namebuf_len; - name->name = namebuf; name->id = rec->version; name->unknown = WINSDB_GROUP_ADDRESS; - name->flags = rec->nb_flags; - name->group_flag = 0; + name->flags = WREPL_NAME_FLAGS(rec->type, rec->state, rec->node, rec->is_static); switch (name->flags & 2) { case 0: @@ -200,8 +152,24 @@ static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, struct wrepl_wins talloc_steal(mem_ctx, rec->addresses[0]->address); break; case 2: - name->addresses.addresses.num_ips = 0; - name->addresses.addresses.ips = NULL; + num_ips = winsdb_addr_list_length(rec->addresses); + ips = talloc_array(mem_ctx, struct wrepl_ip, num_ips); + NT_STATUS_HAVE_NO_MEMORY(ips); + + for (i = 0; i < num_ips; i++) { + if (strcasecmp(WINSDB_OWNER_LOCAL, rec->addresses[i]->wins_owner) == 0) { + ips[i].owner = talloc_strdup(ips, our_address); + NT_STATUS_HAVE_NO_MEMORY(ips[i].owner); + } else { + ips[i].owner = rec->addresses[i]->wins_owner; + talloc_steal(ips, rec->addresses[i]->wins_owner); + } + ips[i].ip = rec->addresses[i]->address; + talloc_steal(ips, rec->addresses[i]->address); + } + + name->addresses.addresses.num_ips = num_ips; + name->addresses.addresses.ips = ips; break; } @@ -251,7 +219,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) * if the partner ask for nothing, or give invalid ranges, * return an empty list. */ - if (owner_in->min_version >= owner_in->max_version) { + if (owner_in->min_version > owner_in->max_version) { return NT_STATUS_OK; } @@ -259,19 +227,29 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) * if the partner has already all records for nothing, or give invalid ranges, * return an empty list. */ - if (owner_in->min_version >= owner->owner.max_version) { + if (owner_in->min_version > owner->owner.max_version) { return NT_STATUS_OK; } - filter = talloc_asprintf(call, "(&(winsOwner=%s)(objectClass=winsRecord)(state>=%u)(versionID>=%llu)(versionID<=%llu))", - owner->owner.address, WINS_REC_ACTIVE, owner_in->min_version, owner_in->max_version); + filter = talloc_asprintf(call, + "(&(winsOwner=%s)(objectClass=winsRecord)" + "(|(recordState=%u)(recordState=%u))" + "(versionID>=%llu)(versionID<=%llu))", + owner->owner.address, + WREPL_STATE_ACTIVE, WREPL_STATE_TOMBSTONE, + owner_in->min_version, owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); if (res != NULL) { talloc_steal(call, res); } if (ret < 0) return NT_STATUS_INTERNAL_DB_CORRUPTION; - if (ret == 0) return NT_STATUS_OK; + if (ret == 0) { + DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", + ret, owner_in->address, owner_in->min_version, owner_in->max_version, + call->wreplconn->partner->address)); + return NT_STATUS_OK; + } names = talloc_array(call, struct wrepl_wins_name, ret); NT_STATUS_HAVE_NO_MEMORY(names); @@ -280,7 +258,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) status = winsdb_record(res[i], NULL, call, &rec); NT_STATUS_NOT_OK_RETURN(status); - status = wreplsrv_record2wins_name(names, &names[i], rec); + status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); NT_STATUS_NOT_OK_RETURN(status); talloc_free(rec); talloc_free(res[i]); @@ -289,12 +267,113 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) /* sort the names before we send them */ qsort(names, ret, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); + DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", + ret, owner_in->address, owner_in->min_version, owner_in->max_version, + call->wreplconn->partner->address)); + reply_out->num_names = ret; reply_out->names = names; return NT_STATUS_OK; } +struct wreplsrv_in_update_state { + struct wreplsrv_in_connection *wrepl_in; + struct wreplsrv_out_connection *wrepl_out; + struct composite_context *creq; + struct wreplsrv_pull_cycle_io cycle_io; +}; + +static void wreplsrv_in_update_handler(struct composite_context *creq) +{ + struct wreplsrv_in_update_state *update_state = talloc_get_type(creq->async.private_data, + struct wreplsrv_in_update_state); + NTSTATUS status; + + status = wreplsrv_pull_cycle_recv(creq); + + talloc_free(update_state->wrepl_out); + + wreplsrv_terminate_in_connection(update_state->wrepl_in, nt_errstr(status)); +} + +static NTSTATUS wreplsrv_in_update(struct wreplsrv_in_call *call) +{ + struct wreplsrv_in_connection *wrepl_in = call->wreplconn; + struct wreplsrv_out_connection *wrepl_out; + struct wrepl_table *update_in = &call->req_packet.message.replication.info.table; + struct wreplsrv_in_update_state *update_state; + + DEBUG(2,("WREPL_REPL_UPDATE: partner[%s] initiator[%s] num_owners[%u]\n", + call->wreplconn->partner->address, + update_in->initiator, update_in->partner_count)); + + /* + * we need to flip the connection into a client connection + * and do a WREPL_REPL_SEND_REQUEST's on the that connection + * and then stop this connection + */ + talloc_free(wrepl_in->conn->event.fde); + wrepl_in->conn->event.fde = NULL; + + update_state = talloc(wrepl_in, struct wreplsrv_in_update_state); + NT_STATUS_HAVE_NO_MEMORY(update_state); + + wrepl_out = talloc(update_state, struct wreplsrv_out_connection); + NT_STATUS_HAVE_NO_MEMORY(wrepl_out); + wrepl_out->service = wrepl_in->service; + wrepl_out->partner = wrepl_in->partner; + wrepl_out->assoc_ctx.our_ctx = wrepl_in->assoc_ctx.our_ctx; + wrepl_out->assoc_ctx.peer_ctx = wrepl_in->assoc_ctx.peer_ctx; + wrepl_out->sock = wrepl_socket_merge(wrepl_out, + wrepl_in->conn->event.ctx, + wrepl_in->conn->socket); + NT_STATUS_HAVE_NO_MEMORY(wrepl_out->sock); + + update_state->wrepl_in = wrepl_in; + update_state->wrepl_out = wrepl_out; + update_state->cycle_io.in.partner = wrepl_out->partner; + update_state->cycle_io.in.num_owners = update_in->partner_count; + update_state->cycle_io.in.owners = update_in->partners; + talloc_steal(update_state, update_in->partners); + update_state->cycle_io.in.wreplconn = wrepl_out; + update_state->creq = wreplsrv_pull_cycle_send(update_state, &update_state->cycle_io); + if (!update_state->creq) { + return NT_STATUS_INTERNAL_ERROR; + } + + update_state->creq->async.fn = wreplsrv_in_update_handler; + update_state->creq->async.private_data = update_state; + + return ERROR_INVALID_PARAMETER; +} + +static NTSTATUS wreplsrv_in_update2(struct wreplsrv_in_call *call) +{ + return wreplsrv_in_update(call); +} + +static NTSTATUS wreplsrv_in_inform(struct wreplsrv_in_call *call) +{ + struct wrepl_table *inform_in = &call->req_packet.message.replication.info.table; + NTSTATUS status; + + DEBUG(2,("WREPL_REPL_INFORM: partner[%s] initiator[%s] num_owners[%u]\n", + call->wreplconn->partner->address, + inform_in->initiator, inform_in->partner_count)); + + status = wreplsrv_sched_inform_action(call->wreplconn->partner, inform_in); + NT_STATUS_NOT_OK_RETURN(status); + + /* we don't reply to WREPL_REPL_INFORM messages */ + return ERROR_INVALID_PARAMETER; +} + +static NTSTATUS wreplsrv_in_inform2(struct wreplsrv_in_call *call) +{ + return wreplsrv_in_inform(call); +} + static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) { struct wrepl_replication *repl_in = &call->req_packet.message.replication; @@ -318,6 +397,9 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) switch (repl_in->command) { case WREPL_REPL_TABLE_QUERY: + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) { + return wreplsrv_in_stop_assoc_ctx(call); + } status = wreplsrv_in_table_query(call); break; @@ -325,6 +407,9 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) return ERROR_INVALID_PARAMETER; case WREPL_REPL_SEND_REQUEST: + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) { + return wreplsrv_in_stop_assoc_ctx(call); + } status = wreplsrv_in_send_request(call); break; @@ -332,16 +417,32 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) return ERROR_INVALID_PARAMETER; case WREPL_REPL_UPDATE: - return ERROR_INVALID_PARAMETER; + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + return wreplsrv_in_stop_assoc_ctx(call); + } + status = wreplsrv_in_update(call); + break; - case WREPL_REPL_5: - return ERROR_INVALID_PARAMETER; + case WREPL_REPL_UPDATE2: + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + return wreplsrv_in_stop_assoc_ctx(call); + } + status = wreplsrv_in_update2(call); + break; case WREPL_REPL_INFORM: - return ERROR_INVALID_PARAMETER; + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + return wreplsrv_in_stop_assoc_ctx(call); + } + status = wreplsrv_in_inform(call); + break; - case WREPL_REPL_9: - return ERROR_INVALID_PARAMETER; + case WREPL_REPL_INFORM2: + if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + return wreplsrv_in_stop_assoc_ctx(call); + } + status = wreplsrv_in_inform2(call); + break; default: return ERROR_INVALID_PARAMETER; @@ -406,7 +507,8 @@ NTSTATUS wreplsrv_in_call(struct wreplsrv_in_call *call) } if (NT_STATUS_IS_OK(status)) { - call->rep_packet.opcode = WREPL_OPCODE_BITS; + /* let the backend to set some of the opcode bits, but always add the standards */ + call->rep_packet.opcode |= WREPL_OPCODE_BITS; call->rep_packet.assoc_ctx = call->wreplconn->assoc_ctx.peer_ctx; } -- cgit From 5c9590587197dcb95007fdc54318187d5716c7c6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Nov 2005 00:11:45 +0000 Subject: r11567: Ldb API change patch. This patch changes the way lsb_search is called and the meaning of the returned integer. The last argument of ldb_search is changed from struct ldb_message to struct ldb_result which contains a pointer to a struct ldb_message list and a count of the number of messages. The return is not the count of messages anymore but instead it is an ldb error value. I tryed to keep the patch as tiny as possible bu as you can guess I had to change a good amount of places. I also tried to double check all my changes being sure that the calling functions would still behave as before. But this patch is big enough that I fear some bug may have been introduced anyway even if it passes the test suite. So if you are currently working on any file being touched please give it a deep look and blame me for any error. Simo. (This used to be commit 22c8c97e6fb466b41859e090e959d7f1134be780) --- source4/wrepl_server/wrepl_in_call.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 7ccb52cc20..38d0b72405 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -35,6 +35,7 @@ #include "libcli/composite/composite.h" #include "nbt_server/wins/winsdb.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { @@ -185,7 +186,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) struct wreplsrv_owner local_owner; struct wreplsrv_owner *owner; const char *filter; - struct ldb_message **res = NULL; + struct ldb_result *res = NULL; int ret; struct wrepl_wins_name *names; struct winsdb_record *rec; @@ -240,28 +241,26 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) owner_in->min_version, owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); - if (res != NULL) { - talloc_steal(call, res); - } - if (ret < 0) return NT_STATUS_INTERNAL_DB_CORRUPTION; - if (ret == 0) { + if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION; + talloc_steal(call, res); + if (res->count == 0) { DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - ret, owner_in->address, owner_in->min_version, owner_in->max_version, + res->count, owner_in->address, owner_in->min_version, owner_in->max_version, call->wreplconn->partner->address)); return NT_STATUS_OK; } - names = talloc_array(call, struct wrepl_wins_name, ret); + names = talloc_array(call, struct wrepl_wins_name, res->count); NT_STATUS_HAVE_NO_MEMORY(names); - for (i=0; i < ret; i++) { - status = winsdb_record(res[i], NULL, call, &rec); + for (i = 0; i < res->count; i++) { + status = winsdb_record(res->msgs[i], NULL, call, &rec); NT_STATUS_NOT_OK_RETURN(status); status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); NT_STATUS_NOT_OK_RETURN(status); talloc_free(rec); - talloc_free(res[i]); + talloc_free(res->msgs[i]); } /* sort the names before we send them */ -- cgit From c222cef1781b88c2f9cb465dc4294629293cdbd2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Nov 2005 12:19:38 +0000 Subject: r11879: some fixes for the new ldb api metze (This used to be commit f5b672edc07586afcd6ab5eebeb8ae1247a2b4ed) --- source4/wrepl_server/wrepl_in_call.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 38d0b72405..b3406c96ba 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -264,13 +264,13 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) } /* sort the names before we send them */ - qsort(names, ret, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); + qsort(names, res->count, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - ret, owner_in->address, owner_in->min_version, owner_in->max_version, + res->count, owner_in->address, owner_in->min_version, owner_in->max_version, call->wreplconn->partner->address)); - reply_out->num_names = ret; + reply_out->num_names = res->count; reply_out->names = names; return NT_STATUS_OK; -- cgit From 329c5e0a5fb545afcb353ac5a0be261240db053f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Nov 2005 10:08:31 +0000 Subject: r11896: max_version of 0 means unlimited metze (This used to be commit 9872348ac81c6907ae1c76f909df13d5fd772b5a) --- source4/wrepl_server/wrepl_in_call.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index b3406c96ba..6b1bc4500e 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -216,6 +216,14 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) return NT_STATUS_OK; } + /* + * the client sends a max_version of 0, interpret it as + * (uint64_t)-1 + */ + if (owner_in->max_version == 0) { + owner_in->max_version = (uint64_t)-1; + } + /* * if the partner ask for nothing, or give invalid ranges, * return an empty list. -- cgit From 03d301ead5f702872b8cb948b8cd01b0fa0db5f7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Nov 2005 02:08:15 +0000 Subject: r11967: Fix more 64-bit warnings. (This used to be commit 9c4436a124f874ae240feaf590141d48c33a635f) --- source4/wrepl_server/wrepl_in_call.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 6b1bc4500e..0dd8095dd2 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -246,14 +246,17 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) "(versionID>=%llu)(versionID<=%llu))", owner->owner.address, WREPL_STATE_ACTIVE, WREPL_STATE_TOMBSTONE, - owner_in->min_version, owner_in->max_version); + (long long)owner_in->min_version, + (long long)owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION; talloc_steal(call, res); if (res->count == 0) { DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - res->count, owner_in->address, owner_in->min_version, owner_in->max_version, + res->count, owner_in->address, + (long long)owner_in->min_version, + (long long)owner_in->max_version, call->wreplconn->partner->address)); return NT_STATUS_OK; } @@ -275,7 +278,9 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) qsort(names, res->count, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - res->count, owner_in->address, owner_in->min_version, owner_in->max_version, + res->count, owner_in->address, + (long long)owner_in->min_version, + (long long)owner_in->max_version, call->wreplconn->partner->address)); reply_out->num_names = res->count; -- cgit From 363d2f69a8220c61786286778070be546108f780 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Dec 2005 15:30:25 +0000 Subject: r12021: remove shortpath for winsdb_lookup, this isn't needed metze (This used to be commit 8fb07b1ea8fdf353da832212289aceef20495bda) --- source4/wrepl_server/wrepl_in_call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 0dd8095dd2..718442a288 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -265,7 +265,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) NT_STATUS_HAVE_NO_MEMORY(names); for (i = 0; i < res->count; i++) { - status = winsdb_record(res->msgs[i], NULL, call, &rec); + status = winsdb_record(res->msgs[i], call, &rec); NT_STATUS_NOT_OK_RETURN(status); status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); -- cgit From 36acd6e79c8cb881b9c333313402d993a6d0f511 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Dec 2005 21:31:42 +0000 Subject: r12200: - move the the winsreplication client and server code to the packet_context system - this needs to be in one big patch, because of the merging code, that changes client in server connections and the other way around - use socket_connect_send/_recv() in the client code metze (This used to be commit f0105b7fcdc3032d22444a1973927fff2dd9a06f) --- source4/wrepl_server/wrepl_in_call.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 718442a288..d186152848 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -106,7 +106,7 @@ static NTSTATUS wreplsrv_in_stop_association(struct wreplsrv_in_call *call) } /* this will cause to not receive packets anymore and terminate the connection if the reply is send */ - call->wreplconn->terminate = True; + call->terminate_after_send = True; return wreplsrv_in_stop_assoc_ctx(call); } @@ -315,6 +315,7 @@ static NTSTATUS wreplsrv_in_update(struct wreplsrv_in_call *call) struct wreplsrv_out_connection *wrepl_out; struct wrepl_table *update_in = &call->req_packet.message.replication.info.table; struct wreplsrv_in_update_state *update_state; + uint16_t fde_flags; DEBUG(2,("WREPL_REPL_UPDATE: partner[%s] initiator[%s] num_owners[%u]\n", call->wreplconn->partner->address, @@ -325,6 +326,7 @@ static NTSTATUS wreplsrv_in_update(struct wreplsrv_in_call *call) * and do a WREPL_REPL_SEND_REQUEST's on the that connection * and then stop this connection */ + fde_flags = event_get_fd_flags(wrepl_in->conn->event.fde); talloc_free(wrepl_in->conn->event.fde); wrepl_in->conn->event.fde = NULL; @@ -339,9 +341,12 @@ static NTSTATUS wreplsrv_in_update(struct wreplsrv_in_call *call) wrepl_out->assoc_ctx.peer_ctx = wrepl_in->assoc_ctx.peer_ctx; wrepl_out->sock = wrepl_socket_merge(wrepl_out, wrepl_in->conn->event.ctx, - wrepl_in->conn->socket); + wrepl_in->conn->socket, + wrepl_in->packet); NT_STATUS_HAVE_NO_MEMORY(wrepl_out->sock); + event_set_fd_flags(wrepl_out->sock->event.fde, fde_flags); + update_state->wrepl_in = wrepl_in; update_state->wrepl_out = wrepl_out; update_state->cycle_io.in.partner = wrepl_out->partner; -- cgit From adb30c5b2f91ae4918750beb8c4df1aa2c194c9d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Dec 2005 00:55:28 +0000 Subject: r12391: use the new periodic schedule system for the pull replication too metze (This used to be commit 3383568c31545a6716eb7045b56d516d507c0b4d) --- source4/wrepl_server/wrepl_in_call.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index d186152848..23701541a8 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -373,14 +373,12 @@ static NTSTATUS wreplsrv_in_update2(struct wreplsrv_in_call *call) static NTSTATUS wreplsrv_in_inform(struct wreplsrv_in_call *call) { struct wrepl_table *inform_in = &call->req_packet.message.replication.info.table; - NTSTATUS status; DEBUG(2,("WREPL_REPL_INFORM: partner[%s] initiator[%s] num_owners[%u]\n", call->wreplconn->partner->address, inform_in->initiator, inform_in->partner_count)); - status = wreplsrv_sched_inform_action(call->wreplconn->partner, inform_in); - NT_STATUS_NOT_OK_RETURN(status); + wreplsrv_out_partner_pull(call->wreplconn->partner, inform_in); /* we don't reply to WREPL_REPL_INFORM messages */ return ERROR_INVALID_PARAMETER; -- cgit From 3fb95418fa9b4ce19e40401680339fa1e3b13286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Dec 2005 03:36:32 +0000 Subject: r12532: log a message giving the IPs of non-partner clients trying WINS replication (makes getting the wins config right much easier) (This used to be commit 3016c7ee138d29973dfd093de6589a9a798750a7) --- source4/wrepl_server/wrepl_in_call.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 23701541a8..b518adf920 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -407,6 +407,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) } if (!call->wreplconn->partner) { + DEBUG(1,("Failing WINS replication from non-partner %s\n", + socket_get_peer_addr(call->wreplconn->conn->socket, call))); return wreplsrv_in_stop_assoc_ctx(call); } -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/wrepl_server/wrepl_in_call.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index b518adf920..ebcd4f5d83 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -21,14 +21,9 @@ */ #include "includes.h" -#include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" -#include "smbd/service_task.h" #include "smbd/service_stream.h" -#include "lib/messaging/irpc.h" -#include "librpc/gen_ndr/ndr_winsrepl.h" -#include "librpc/gen_ndr/ndr_nbt.h" #include "libcli/wrepl/winsrepl.h" #include "wrepl_server/wrepl_server.h" #include "wrepl_server/wrepl_out_helpers.h" -- cgit From 0391b1cb3a1527aed5beefbdda67a6ce5062bbab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Dec 2005 20:08:52 +0000 Subject: r12617: create a winsdb_handle and pass that arround, so we later can hang the local owner address, on this handle too metze (This used to be commit 49ba4cc11144671cafcbe2967954bfd786ea6e76) --- source4/wrepl_server/wrepl_in_call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index ebcd4f5d83..a2637d1b39 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -244,7 +244,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) (long long)owner_in->min_version, (long long)owner_in->max_version); NT_STATUS_HAVE_NO_MEMORY(filter); - ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); + ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION; talloc_steal(call, res); if (res->count == 0) { -- cgit From 905c3ff8e1e63f2151f63552e556086968424118 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Dec 2005 21:12:15 +0000 Subject: r12618: use our primary interface address or the "winsdb:local_owner" -address as winsOwner: attrbute for owned records metze (This used to be commit 37dece8304c0b9887740f4d4e8096732045a1785) --- source4/wrepl_server/wrepl_in_call.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index a2637d1b39..9bd01c14bb 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -138,7 +138,7 @@ static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, talloc_steal(mem_ctx, rec->name); name->id = rec->version; - name->unknown = WINSDB_GROUP_ADDRESS; + name->unknown = "255.255.255.255"; name->flags = WREPL_NAME_FLAGS(rec->type, rec->state, rec->node, rec->is_static); @@ -153,13 +153,8 @@ static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(ips); for (i = 0; i < num_ips; i++) { - if (strcasecmp(WINSDB_OWNER_LOCAL, rec->addresses[i]->wins_owner) == 0) { - ips[i].owner = talloc_strdup(ips, our_address); - NT_STATUS_HAVE_NO_MEMORY(ips[i].owner); - } else { - ips[i].owner = rec->addresses[i]->wins_owner; - talloc_steal(ips, rec->addresses[i]->wins_owner); - } + ips[i].owner = rec->addresses[i]->wins_owner; + talloc_steal(ips, rec->addresses[i]->wins_owner); ips[i].ip = rec->addresses[i]->address; talloc_steal(ips, rec->addresses[i]->address); } @@ -190,7 +185,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) if (strcmp(call->wreplconn->our_ip, owner_in->address) == 0) { ZERO_STRUCT(local_owner); - local_owner.owner.address = WINSDB_OWNER_LOCAL; + local_owner.owner.address = service->wins_db->local_owner; local_owner.owner.min_version = 0; local_owner.owner.max_version = wreplsrv_local_max_version(service); local_owner.owner.type = 1; @@ -260,7 +255,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) NT_STATUS_HAVE_NO_MEMORY(names); for (i = 0; i < res->count; i++) { - status = winsdb_record(res->msgs[i], call, &rec); + status = winsdb_record(service->wins_db, res->msgs[i], call, &rec); NT_STATUS_NOT_OK_RETURN(status); status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); -- cgit From b75ed7d7ac9b3d5beca71926a15cfec5e3a0092c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Jan 2006 17:19:09 +0000 Subject: r12677: get rid of the special cases for the local wins owner table entry, the call to winsdb_get_maxVersion() is moved into place. This allows us to fetch records with the owner address that matches our local_owner address, this is important if the restart with an empty wins.ldb. w2k3 does this in the same way when you remove the database files from disk and restart the WINS-Service. metze (This used to be commit e43de87d06614206a858e1102cd82e7f02163bba) --- source4/wrepl_server/wrepl_in_call.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 9bd01c14bb..4d5fad8a7c 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -115,7 +115,7 @@ static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) repl_out->command = WREPL_REPL_TABLE_REPLY; return wreplsrv_fill_wrepl_table(service, call, table_out, - our_ip, our_ip, True); + our_ip, True); } static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, @@ -173,7 +173,6 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) struct wrepl_wins_owner *owner_in = &call->req_packet.message.replication.info.owner; struct wrepl_replication *repl_out = &call->rep_packet.message.replication; struct wrepl_send_reply *reply_out = &call->rep_packet.message.replication.info.reply; - struct wreplsrv_owner local_owner; struct wreplsrv_owner *owner; const char *filter; struct ldb_result *res = NULL; @@ -183,16 +182,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) NTSTATUS status; uint32_t i; - if (strcmp(call->wreplconn->our_ip, owner_in->address) == 0) { - ZERO_STRUCT(local_owner); - local_owner.owner.address = service->wins_db->local_owner; - local_owner.owner.min_version = 0; - local_owner.owner.max_version = wreplsrv_local_max_version(service); - local_owner.owner.type = 1; - owner = &local_owner; - } else { - owner = wreplsrv_find_owner(service->table, owner_in->address); - } + owner = wreplsrv_find_owner(service, service->table, owner_in->address); repl_out->command = WREPL_REPL_SEND_REPLY; reply_out->num_names = 0; @@ -203,6 +193,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) * return an empty list. */ if (!owner) { + DEBUG(2,("WINSREPL:reply [0] records unknown owner[%s] to partner[%s]\n", + owner_in->address, call->wreplconn->partner->address)); return NT_STATUS_OK; } @@ -219,6 +211,11 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) * return an empty list. */ if (owner_in->min_version > owner_in->max_version) { + DEBUG(2,("WINSREPL:reply [0] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", + owner_in->address, + (long long)owner_in->min_version, + (long long)owner_in->max_version, + call->wreplconn->partner->address)); return NT_STATUS_OK; } @@ -227,6 +224,11 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) * return an empty list. */ if (owner_in->min_version > owner->owner.max_version) { + DEBUG(2,("WINSREPL:reply [0] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", + owner_in->address, + (long long)owner_in->min_version, + (long long)owner_in->max_version, + call->wreplconn->partner->address)); return NT_STATUS_OK; } -- cgit From 6fbbd471648e3d436e21a0f4fe2bdb21dbe4376d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Jan 2006 18:25:30 +0000 Subject: r12679: create a sperate function to create the 'winsOwner' part of the search filter, this is to handle the special '0.0.0.0' of old or manual added owned records metze (This used to be commit 4c7306608cc3f86c31ed044bc41eda905b64b31f) --- source4/wrepl_server/wrepl_in_call.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 4d5fad8a7c..693c87424a 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -174,6 +174,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) struct wrepl_replication *repl_out = &call->rep_packet.message.replication; struct wrepl_send_reply *reply_out = &call->rep_packet.message.replication.info.reply; struct wreplsrv_owner *owner; + const char *owner_filter; const char *filter; struct ldb_result *res = NULL; int ret; @@ -232,11 +233,13 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) return NT_STATUS_OK; } + owner_filter = wreplsrv_owner_filter(service, call, owner->owner.address); + NT_STATUS_HAVE_NO_MEMORY(owner_filter); filter = talloc_asprintf(call, - "(&(winsOwner=%s)(objectClass=winsRecord)" + "(&%s(objectClass=winsRecord)" "(|(recordState=%u)(recordState=%u))" "(versionID>=%llu)(versionID<=%llu))", - owner->owner.address, + owner_filter, WREPL_STATE_ACTIVE, WREPL_STATE_TOMBSTONE, (long long)owner_in->min_version, (long long)owner_in->max_version); @@ -244,6 +247,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION; talloc_steal(call, res); + DEBUG(10,("WINSREPL: filter '%s' count %d\n", filter, res->count)); + if (res->count == 0) { DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", res->count, owner_in->address, -- cgit From 63d718e243fd03e6ea24c47e7442975ec088a5b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 17:27:33 +0000 Subject: r12696: Reduce the size of include/structs.h (This used to be commit 63917616016133c623fc6ff59454bc313ee7dd8f) --- source4/wrepl_server/wrepl_in_call.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 693c87424a..27428106d4 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -26,7 +26,6 @@ #include "smbd/service_stream.h" #include "libcli/wrepl/winsrepl.h" #include "wrepl_server/wrepl_server.h" -#include "wrepl_server/wrepl_out_helpers.h" #include "libcli/composite/composite.h" #include "nbt_server/wins/winsdb.h" #include "lib/ldb/include/ldb.h" -- cgit From f0e3a0312d77086015e5662494b6be24a51b0091 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Jan 2006 17:03:17 +0000 Subject: r12796: use the correct address as initiator metze (This used to be commit ba97e7c06af6f919a66622c1a6b6e58980ab2b9e) --- source4/wrepl_server/wrepl_in_call.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 27428106d4..8dabc2ee86 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -109,12 +109,11 @@ static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) struct wreplsrv_service *service = call->wreplconn->service; struct wrepl_replication *repl_out = &call->rep_packet.message.replication; struct wrepl_table *table_out = &call->rep_packet.message.replication.info.table; - const char *our_ip = call->wreplconn->our_ip; repl_out->command = WREPL_REPL_TABLE_REPLY; return wreplsrv_fill_wrepl_table(service, call, table_out, - our_ip, True); + service->wins_db->local_owner, True); } static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, @@ -126,7 +125,6 @@ static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, } static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, - const char *our_address, struct wrepl_wins_name *name, struct winsdb_record *rec) { @@ -264,7 +262,7 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) status = winsdb_record(service->wins_db, res->msgs[i], call, &rec); NT_STATUS_NOT_OK_RETURN(status); - status = wreplsrv_record2wins_name(names, call->wreplconn->our_ip, &names[i], rec); + status = wreplsrv_record2wins_name(names, &names[i], rec); NT_STATUS_NOT_OK_RETURN(status); talloc_free(rec); talloc_free(res->msgs[i]); -- cgit From f55ea8bb3dca868e21663cd90eaea7a35cd7886c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 Jan 2006 22:12:53 +0000 Subject: r12804: This patch reworks the Samba4 sockets layer to use a socket_address structure that is more generic than just 'IP/port'. It now passes make test, and has been reviewed and updated by metze. (Thankyou *very* much). This passes 'make test' as well as kerberos use (not currently in the testsuite). The original purpose of this patch was to have Samba able to pass a socket address stucture from the BSD layer into the kerberos routines and back again. It also removes nbt_peer_addr, which was being used for a similar purpose. It is a large change, but worthwhile I feel. Andrew Bartlett (This used to be commit 88198c4881d8620a37086f80e4da5a5b71c5bbb2) --- source4/wrepl_server/wrepl_in_call.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 8dabc2ee86..46ee25b7ad 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -401,8 +401,9 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) } if (!call->wreplconn->partner) { + struct socket_address *partner_ip = socket_get_peer_addr(call->wreplconn->conn->socket, call); DEBUG(1,("Failing WINS replication from non-partner %s\n", - socket_get_peer_addr(call->wreplconn->conn->socket, call))); + partner_ip ? partner_ip->addr : NULL)); return wreplsrv_in_stop_assoc_ctx(call); } -- cgit From 4915f16ab23f3c8e2e98fc0d90696e2d7a7bd6a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Jan 2006 12:26:09 +0000 Subject: r13050: when we have reloaded the partners from wins_config.ldb after a new partner connects, try to find the partner struct on a per call basis if it's not present on the connection yet add some more useful debug messages metze (This used to be commit e57158e216e3564faa337288734d9efb30ab838d) --- source4/wrepl_server/wrepl_in_call.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 46ee25b7ad..3365a1f146 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -402,14 +402,20 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) if (!call->wreplconn->partner) { struct socket_address *partner_ip = socket_get_peer_addr(call->wreplconn->conn->socket, call); - DEBUG(1,("Failing WINS replication from non-partner %s\n", - partner_ip ? partner_ip->addr : NULL)); - return wreplsrv_in_stop_assoc_ctx(call); + + call->wreplconn->partner = wreplsrv_find_partner(call->wreplconn->service, partner_ip->addr); + if (!call->wreplconn->partner) { + DEBUG(1,("Failing WINS replication from non-partner %s\n", + partner_ip ? partner_ip->addr : NULL)); + return wreplsrv_in_stop_assoc_ctx(call); + } } switch (repl_in->command) { case WREPL_REPL_TABLE_QUERY: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) { + DEBUG(2,("Failing WINS replication TABLE_QUERY from non-push-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_table_query(call); @@ -420,6 +426,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) case WREPL_REPL_SEND_REQUEST: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) { + DEBUG(2,("Failing WINS replication SEND_REQUESET from non-push-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_send_request(call); @@ -430,6 +438,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) case WREPL_REPL_UPDATE: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + DEBUG(2,("Failing WINS replication UPDATE from non-pull-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_update(call); @@ -437,6 +447,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) case WREPL_REPL_UPDATE2: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + DEBUG(2,("Failing WINS replication UPDATE2 from non-pull-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_update2(call); @@ -444,6 +456,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) case WREPL_REPL_INFORM: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + DEBUG(2,("Failing WINS replication INFORM from non-pull-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_inform(call); @@ -451,6 +465,8 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) case WREPL_REPL_INFORM2: if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) { + DEBUG(2,("Failing WINS replication INFORM2 from non-pull-partner %s\n", + call->wreplconn->partner->address)); return wreplsrv_in_stop_assoc_ctx(call); } status = wreplsrv_in_inform2(call); -- cgit From f25ad21617d7887d68bff3cad31045e8a98e3cae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 21 Jan 2006 08:53:56 +0000 Subject: r13060: - return only active addresses in name query responses - replicate only active addresses metze (This used to be commit 6325abd95c5df855e8d1de2be9745940a29ba00a) --- source4/wrepl_server/wrepl_in_call.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 3365a1f146..8ce88db6a9 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -30,6 +30,7 @@ #include "nbt_server/wins/winsdb.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" +#include "system/time.h" static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) { @@ -178,7 +179,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) struct wrepl_wins_name *names; struct winsdb_record *rec; NTSTATUS status; - uint32_t i; + uint32_t i, j; + time_t now = time(NULL); owner = wreplsrv_find_owner(service, service->table, owner_in->address); @@ -258,26 +260,37 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call) names = talloc_array(call, struct wrepl_wins_name, res->count); NT_STATUS_HAVE_NO_MEMORY(names); - for (i = 0; i < res->count; i++) { - status = winsdb_record(service->wins_db, res->msgs[i], call, &rec); + for (i=0, j=0; i < res->count; i++) { + status = winsdb_record(service->wins_db, res->msgs[i], call, now, &rec); NT_STATUS_NOT_OK_RETURN(status); - status = wreplsrv_record2wins_name(names, &names[i], rec); - NT_STATUS_NOT_OK_RETURN(status); + /* + * it's possible that winsdb_record() made the record RELEASED + * because it's expired, but in the database it's still stored + * as ACTIVE... + * + * make sure we really only replicate ACTIVE and TOMBSTONE records + */ + if (rec->state == WREPL_STATE_ACTIVE || rec->state == WREPL_STATE_TOMBSTONE) { + status = wreplsrv_record2wins_name(names, &names[j], rec); + NT_STATUS_NOT_OK_RETURN(status); + j++; + } + talloc_free(rec); talloc_free(res->msgs[i]); } /* sort the names before we send them */ - qsort(names, res->count, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); + qsort(names, j, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name); DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n", - res->count, owner_in->address, + j, owner_in->address, (long long)owner_in->min_version, (long long)owner_in->max_version, call->wreplconn->partner->address)); - reply_out->num_names = res->count; + reply_out->num_names = j; reply_out->names = names; return NT_STATUS_OK; -- cgit From 289e9baa1d9ab7fa36d88a5cd50c0a0f706c07bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 4 Feb 2006 13:54:30 +0000 Subject: r13345: let us replicate with NT4sp6a I don't yet know what the extra data in the start_association call mean... This also let w2k use WREPL_REPL_INFORM messages to us, but w2k3 doesn't it do it yet... metze (This used to be commit 02d6dfa1da754857c28125392a561cfde0087c48) --- source4/wrepl_server/wrepl_in_call.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 8ce88db6a9..09ea2c15b4 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -50,10 +50,17 @@ static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) return NT_STATUS_OK; } +/* + * it seems that we don't know all details about the start_association + * to support replication with NT4 (it sends 1.1 instead of 5.2) + * we ignore the version numbers until we know all details + */ +#if 0 if (start->minor_version != 2 || start->major_version != 5) { /* w2k terminate the connection if the versions doesn't match */ return NT_STATUS_UNKNOWN_REVISION; } +#endif call->wreplconn->assoc_ctx.stopped = False; call->wreplconn->assoc_ctx.our_ctx = WREPLSRV_VALID_ASSOC_CTX; @@ -64,6 +71,19 @@ static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) start_reply->minor_version = 2; start_reply->major_version = 5; + /* + * nt4 uses 41 bytes for the start_association call + * so do it the same and as we don't know th emeanings of this bytes + * we just send zeros and nt4, w2k and w2k3 seems to be happy with this + * + * if we don't do this nt4 uses an old version of the wins replication protocol + * and that would break nt4 <-> samba replication + */ + call->rep_packet.padding = data_blob_talloc(call, NULL, 21); + NT_STATUS_HAVE_NO_MEMORY(call->rep_packet.padding.data); + + memset(call->rep_packet.padding.data, 0, call->rep_packet.padding.length); + return NT_STATUS_OK; } -- cgit From 1ffb7908d50d11b7423084cdea15628f0dcfe2d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 20 Apr 2006 12:11:09 +0000 Subject: r15149: fix typo metze (This used to be commit b00d524ef73e2fffd81ef3a8cdd242feda10f59d) --- source4/wrepl_server/wrepl_in_call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 09ea2c15b4..dab7b52307 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -73,7 +73,7 @@ static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) /* * nt4 uses 41 bytes for the start_association call - * so do it the same and as we don't know th emeanings of this bytes + * so do it the same and as we don't know the meanings of this bytes * we just send zeros and nt4, w2k and w2k3 seems to be happy with this * * if we don't do this nt4 uses an old version of the wins replication protocol -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/wrepl_server/wrepl_in_call.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index dab7b52307..75ac4a6e31 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -7,7 +7,7 @@ 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 2 of the License, or + 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, @@ -16,8 +16,7 @@ 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From af0a85bc30223d65f09dc57dea4427a7773d6ddb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 21:48:28 +0000 Subject: r25549: Convert to standard bool type. (This used to be commit 318bf1f7441678860adfff5cdb0d3d2448e58f4b) --- source4/wrepl_server/wrepl_in_call.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/wrepl_server/wrepl_in_call.c') diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 75ac4a6e31..0508c306e0 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -61,7 +61,7 @@ static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call) } #endif - call->wreplconn->assoc_ctx.stopped = False; + call->wreplconn->assoc_ctx.stopped = false; call->wreplconn->assoc_ctx.our_ctx = WREPLSRV_VALID_ASSOC_CTX; call->wreplconn->assoc_ctx.peer_ctx = start->assoc_ctx; @@ -90,7 +90,7 @@ static NTSTATUS wreplsrv_in_stop_assoc_ctx(struct wreplsrv_in_call *call) { struct wrepl_stop *stop_out = &call->rep_packet.message.stop; - call->wreplconn->assoc_ctx.stopped = True; + call->wreplconn->assoc_ctx.stopped = true; call->rep_packet.mess_type = WREPL_STOP_ASSOCIATION; stop_out->reason = 4; @@ -120,7 +120,7 @@ static NTSTATUS wreplsrv_in_stop_association(struct wreplsrv_in_call *call) } /* this will cause to not receive packets anymore and terminate the connection if the reply is send */ - call->terminate_after_send = True; + call->terminate_after_send = true; return wreplsrv_in_stop_assoc_ctx(call); } @@ -133,7 +133,7 @@ static NTSTATUS wreplsrv_in_table_query(struct wreplsrv_in_call *call) repl_out->command = WREPL_REPL_TABLE_REPLY; return wreplsrv_fill_wrepl_table(service, call, table_out, - service->wins_db->local_owner, True); + service->wins_db->local_owner, true); } static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1, -- cgit