diff options
Diffstat (limited to 'source4/wrepld')
-rw-r--r-- | source4/wrepld/parser.c | 759 | ||||
-rw-r--r-- | source4/wrepld/partners.c | 200 | ||||
-rw-r--r-- | source4/wrepld/process.c | 983 | ||||
-rw-r--r-- | source4/wrepld/server.c | 737 | ||||
-rw-r--r-- | source4/wrepld/socket.c | 69 | ||||
-rw-r--r-- | source4/wrepld/wins_repl.h | 159 |
6 files changed, 0 insertions, 2907 deletions
diff --git a/source4/wrepld/parser.c b/source4/wrepld/parser.c deleted file mode 100644 index b619cb0cef..0000000000 --- a/source4/wrepld/parser.c +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Jean François Micouleau 1998-2002. - * - * 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 "wins_repl.h" - -extern TALLOC_CTX *mem_ctx; - -/**************************************************************************** -grow the send buffer if necessary -****************************************************************************/ -BOOL grow_buffer(struct BUFFER *buffer, int more) -{ - char *temp; - - DEBUG(10,("grow_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more)); - - /* grow by at least 256 bytes */ - if (more<256) - more=256; - - if (buffer->offset+more >= buffer->length) { - temp=(char *)talloc_realloc(mem_ctx, buffer->buffer, sizeof(char)* (buffer->length+more) ); - if (temp==NULL) { - DEBUG(0,("grow_buffer: can't grow buffer\n")); - return False; - } - buffer->length+=more; - buffer->buffer=temp; - } - - return True; -} - -/**************************************************************************** -check if the buffer has that much data -****************************************************************************/ -static BOOL check_buffer(struct BUFFER *buffer, int more) -{ - DEBUG(10,("check_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more)); - - if (buffer->offset+more > buffer->length) { - DEBUG(10,("check_buffer: buffer smaller than requested, size is: %d needed: %d\n", buffer->length, buffer->offset+more)); - return False; - } - - return True; -} - -/**************************************************************************** -decode a WINS_OWNER struct -****************************************************************************/ -static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner) -{ - if(!check_buffer(inbuf, 24)) - return; - - wins_owner->address.s_addr=IVAL(inbuf->buffer, inbuf->offset); - wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+4))<<32; - wins_owner->max_version|=RIVAL(inbuf->buffer, inbuf->offset+8); - wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+12))<<32; - wins_owner->min_version|=RIVAL(inbuf->buffer, inbuf->offset+16); - wins_owner->type=RIVAL(inbuf->buffer, inbuf->offset+20); - inbuf->offset+=24; - -} - -/**************************************************************************** -decode a WINS_NAME struct -****************************************************************************/ -static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name) -{ - char *p; - int i; - - if(!check_buffer(outbuf, 40)) - return; - - wins_name->name_len=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - memcpy(wins_name->name,outbuf->buffer+outbuf->offset, 15); - wins_name->name[15]='\0'; - if((p = strchr(wins_name->name,' ')) != NULL) - *p = 0; - - outbuf->offset+=15; - - wins_name->type=(int)outbuf->buffer[outbuf->offset++]; - - /* - * fix to bug in WINS replication, - * present in all versions including W2K SP2 ! - */ - if (wins_name->name[0]==0x1B) { - wins_name->name[0]=(char)wins_name->type; - wins_name->type=0x1B; - } - - wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - - wins_name->name_flag=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - wins_name->group_flag=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf->buffer, outbuf->offset))<<32; - outbuf->offset+=4; - wins_name->id|=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - - /* special groups have multiple address */ - if (wins_name->name_flag & 2) { - if(!check_buffer(outbuf, 4)) - return; - wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - } - else - wins_name->num_ip=1; - - if(!check_buffer(outbuf, 4)) - return; - wins_name->owner.s_addr=IVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - - if (wins_name->name_flag & 2) { - wins_name->others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*wins_name->num_ip); - if (wins_name->others==NULL) - return; - - if(!check_buffer(outbuf, 4*wins_name->num_ip)) - return; - for (i=0; i<wins_name->num_ip; i++) { - wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - } - } - - if(!check_buffer(outbuf, 4)) - return; - wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset); - outbuf->offset+=4; - -} - -/**************************************************************************** -decode a update notification request -****************************************************************************/ -static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq) -{ - int i; - - if(!check_buffer(inbuf, 4)) - return; - un_rq->partner_count=RIVAL(inbuf->buffer, inbuf->offset); - inbuf->offset+=4; - - un_rq->wins_owner=(WINS_OWNER *)talloc(mem_ctx, un_rq->partner_count*sizeof(WINS_OWNER)); - if (un_rq->wins_owner==NULL) - return; - - for (i=0; i<un_rq->partner_count; i++) - decode_wins_owner(inbuf, &un_rq->wins_owner[i]); - - if(!check_buffer(inbuf, 4)) - return; - un_rq->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset); - inbuf->offset+=4; -} - -/**************************************************************************** -decode a send entries request -****************************************************************************/ -static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq) -{ - decode_wins_owner(inbuf, &se_rq->wins_owner); -} - -/**************************************************************************** -decode a send entries reply -****************************************************************************/ -static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp) -{ - int i; - - if(!check_buffer(inbuf, 4)) - return; - se_rp->max_names = RIVAL(inbuf->buffer, inbuf->offset); - inbuf->offset+=4; - - se_rp->wins_name=(WINS_NAME *)talloc(mem_ctx, se_rp->max_names*sizeof(WINS_NAME)); - if (se_rp->wins_name==NULL) - return; - - for (i=0; i<se_rp->max_names; i++) - decode_wins_name(inbuf, &se_rp->wins_name[i]); -} - -/**************************************************************************** -decode a add version number map table reply -****************************************************************************/ -static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep) -{ - int i; - - if(!check_buffer(inbuf, 4)) - return; - - avmt_rep->partner_count=RIVAL(inbuf->buffer, inbuf->offset); - inbuf->offset+=4; - - avmt_rep->wins_owner=(WINS_OWNER *)talloc(mem_ctx, avmt_rep->partner_count*sizeof(WINS_OWNER)); - if (avmt_rep->wins_owner==NULL) - return; - - for (i=0; i<avmt_rep->partner_count; i++) - decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]); - - if(!check_buffer(inbuf, 4)) - return; - avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset); - inbuf->offset+=4; -} - -/**************************************************************************** -decode a replicate packet and fill a structure -****************************************************************************/ -static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep) -{ - if(!check_buffer(inbuf, 4)) - return; - - rep->msg_type = RIVAL(inbuf->buffer, inbuf->offset); - - inbuf->offset+=4; - - switch (rep->msg_type) { - case 0: - break; - case 1: - /* add version number map table reply */ - decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep); - break; - case 2: - /* send entry request */ - decode_send_entries_request(inbuf, &rep->se_rq); - break; - case 3: - /* send entry request */ - decode_send_entries_reply(inbuf, &rep->se_rp); - break; - case 4: - /* update notification request */ - decode_update_notify_request(inbuf, &rep->un_rq); - break; - default: - DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type)); - break; - } -} - -/**************************************************************************** -read the generic header and fill the struct. -****************************************************************************/ -static void read_generic_header(struct BUFFER *inbuf, generic_header *q) -{ - if(!check_buffer(inbuf, 16)) - return; - - q->data_size = RIVAL(inbuf->buffer, inbuf->offset+0); - q->opcode = RIVAL(inbuf->buffer, inbuf->offset+4); - q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+8); - q->mess_type = RIVAL(inbuf->buffer, inbuf->offset+12); -} - -/******************************************************************* -decode a start association request -********************************************************************/ -static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q) -{ - if(!check_buffer(inbuf, 8)) - return; - - q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+0); - q->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4); - q->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6); -} - -/******************************************************************* -decode a start association reply -********************************************************************/ -static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r) -{ - if(!check_buffer(inbuf, 8)) - return; - - r->assoc_ctx=RIVAL(inbuf->buffer, inbuf->offset+0); - r->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4); - r->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6); -} - -/******************************************************************* -decode a start association reply -********************************************************************/ -static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r) -{ - if(!check_buffer(inbuf, 4)) - return; - - r->reason=RIVAL(inbuf->buffer, inbuf->offset); -} - -/**************************************************************************** -decode a packet and fill a generic structure -****************************************************************************/ -void decode_generic_packet(struct BUFFER *inbuf, GENERIC_PACKET *q) -{ - read_generic_header(inbuf, &q->header); - - inbuf->offset+=16; - - switch (q->header.mess_type) { - case 0: - decode_start_assoc_request(inbuf, &q->sa_rq); - break; - case 1: - decode_start_assoc_reply(inbuf, &q->sa_rp); - break; - case 2: - decode_stop_assoc(inbuf, &q->so); - break; - case 3: - decode_replicate(inbuf, &q->rep); - break; - default: - DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type)); - break; - } -} - -/**************************************************************************** -encode a WINS_OWNER struct -****************************************************************************/ -static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner) -{ - if (!grow_buffer(outbuf, 24)) - return; - - SIVAL(outbuf->buffer, outbuf->offset, wins_owner->address.s_addr); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version>>32)); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version&0xffffffff)); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version>>32); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version&0xffffffff); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->type); - outbuf->offset+=4; - -} - -/**************************************************************************** -encode a WINS_NAME struct -****************************************************************************/ -static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name) -{ - int i; - - if (!grow_buffer(outbuf, 48+(4*wins_name->num_ip))) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_len); - outbuf->offset+=4; - - memset(outbuf->buffer+outbuf->offset, ' ', 15); - - /* to prevent copying the leading \0 */ - memcpy(outbuf->buffer+outbuf->offset, wins_name->name, strlen(wins_name->name)); - outbuf->offset+=15; - - outbuf->buffer[outbuf->offset++]=(char)wins_name->type; - - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->empty); - outbuf->offset+=4; - - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_flag); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->group_flag); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id>>32); - outbuf->offset+=4; - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id); - outbuf->offset+=4; - - if (wins_name->name_flag & 2) { - SIVAL(outbuf->buffer, outbuf->offset, wins_name->num_ip); - outbuf->offset+=4; - } - - SIVAL(outbuf->buffer, outbuf->offset, wins_name->owner.s_addr); - outbuf->offset+=4; - - if (wins_name->name_flag & 2) { - for (i=0;i<wins_name->num_ip;i++) { - SIVAL(outbuf->buffer, outbuf->offset, wins_name->others[i].s_addr); - outbuf->offset+=4; - } - } - - RSIVAL(outbuf->buffer, outbuf->offset, wins_name->foo); - outbuf->offset+=4; -} - -/**************************************************************************** -encode a update notification request -****************************************************************************/ -static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq) -{ - int i; - - if (!grow_buffer(outbuf, 8)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, un_rq->partner_count); - outbuf->offset+=4; - - for (i=0; i<un_rq->partner_count; i++) - encode_wins_owner(outbuf, &un_rq->wins_owner[i]); - - SIVAL(outbuf->buffer, outbuf->offset, un_rq->initiating_wins_server.s_addr); - outbuf->offset+=4; - -} - -/**************************************************************************** -decode a send entries request -****************************************************************************/ -static void encode_send_entries_request(struct BUFFER *outbuf, SEND_ENTRIES_REQUEST *se_rq) -{ - encode_wins_owner(outbuf, &se_rq->wins_owner); -} - -/**************************************************************************** -decode a send entries reply -****************************************************************************/ -static void encode_send_entries_reply(struct BUFFER *outbuf, SEND_ENTRIES_REPLY *se_rp) -{ - int i; - - if (!grow_buffer(outbuf, 4)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, se_rp->max_names); - outbuf->offset+=4; - - for (i=0; i<se_rp->max_names; i++) - encode_wins_name(outbuf, &se_rp->wins_name[i]); - -} - -/**************************************************************************** -encode a add version number map table reply -****************************************************************************/ -static void encode_add_version_number_map_table_reply(struct BUFFER *outbuf, AVMT_REP *avmt_rep) -{ - int i; - - if (!grow_buffer(outbuf, 8)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, avmt_rep->partner_count); - outbuf->offset+=4; - - for (i=0; i<avmt_rep->partner_count; i++) - encode_wins_owner(outbuf, &avmt_rep->wins_owner[i]); - - SIVAL(outbuf->buffer, outbuf->offset, avmt_rep->initiating_wins_server.s_addr); - outbuf->offset+=4; - -} - -/**************************************************************************** -decode a replicate packet and fill a structure -****************************************************************************/ -static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep) -{ - if (!grow_buffer(outbuf, 4)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, rep->msg_type); - outbuf->offset+=4; - - switch (rep->msg_type) { - case 0: - break; - case 1: - /* add version number map table reply */ - encode_add_version_number_map_table_reply(outbuf, &rep->avmt_rep); - break; - case 2: - /* send entry request */ - encode_send_entries_request(outbuf, &rep->se_rq); - break; - case 3: - /* send entry request */ - encode_send_entries_reply(outbuf, &rep->se_rp); - break; - case 4: - /* update notification request */ - encode_update_notify_request(outbuf, &rep->un_rq); - break; - default: - DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type)); - break; - } -} - -/**************************************************************************** -write the generic header. -****************************************************************************/ -static void write_generic_header(struct BUFFER *outbuf, generic_header *r) -{ - RSIVAL(outbuf->buffer, 0, r->data_size); - RSIVAL(outbuf->buffer, 4, r->opcode); - RSIVAL(outbuf->buffer, 8, r->assoc_ctx); - RSIVAL(outbuf->buffer,12, r->mess_type); -} - -/******************************************************************* -decode a start association request -********************************************************************/ -static void encode_start_assoc_request(struct BUFFER *outbuf, START_ASSOC_REQUEST *q) -{ - if (!grow_buffer(outbuf, 45)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, q->assoc_ctx); - RSSVAL(outbuf->buffer, outbuf->offset+4, q->min_ver); - RSSVAL(outbuf->buffer, outbuf->offset+6, q->maj_ver); - - outbuf->offset=45; -} - -/******************************************************************* -decode a start association reply -********************************************************************/ -static void encode_start_assoc_reply(struct BUFFER *outbuf, START_ASSOC_REPLY *r) -{ - if (!grow_buffer(outbuf, 45)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, r->assoc_ctx); - RSSVAL(outbuf->buffer, outbuf->offset+4, r->min_ver); - RSSVAL(outbuf->buffer, outbuf->offset+6, r->maj_ver); - - outbuf->offset=45; -} - -/******************************************************************* -decode a start association reply -********************************************************************/ -static void encode_stop_assoc(struct BUFFER *outbuf, STOP_ASSOC *r) -{ - if (!grow_buffer(outbuf, 44)) - return; - - RSIVAL(outbuf->buffer, outbuf->offset, r->reason); - - outbuf->offset=44; -} - -/**************************************************************************** -write the generic header size. -****************************************************************************/ -static void write_generic_header_size(generic_header *r, int size) -{ - /* the buffer size is the total size minus the size field */ - r->data_size=size-4; -} - -/**************************************************************************** -encode a packet and read a generic structure -****************************************************************************/ -void encode_generic_packet(struct BUFFER *outbuf, GENERIC_PACKET *q) -{ - if (!grow_buffer(outbuf, 16)) - return; - - outbuf->offset=16; - - switch (q->header.mess_type) { - case 0: - encode_start_assoc_request(outbuf, &q->sa_rq); - break; - case 1: - encode_start_assoc_reply(outbuf, &q->sa_rp); - break; - case 2: - encode_stop_assoc(outbuf, &q->so); - break; - case 3: - encode_replicate(outbuf, &q->rep); - break; - default: - DEBUG(0,("encode_generic_packet: unknown message type:%d\n", q->header.mess_type)); - break; - } - - write_generic_header_size(&q->header, outbuf->offset); - write_generic_header(outbuf, &q->header); -} - - -/**************************************************************************** -dump a WINS_OWNER structure -****************************************************************************/ -static void dump_wins_owner(WINS_OWNER *wins_owner) -{ - DEBUGADD(10,("\t\t\t\taddress : %s\n", inet_ntoa(wins_owner->address))); - DEBUGADD(10,("\t\t\t\tmax version: %d\n", (int)wins_owner->max_version)); - DEBUGADD(10,("\t\t\t\tmin version: %d\n", (int)wins_owner->min_version)); - DEBUGADD(10,("\t\t\t\ttype : %d\n", wins_owner->type)); -} - -/**************************************************************************** -dump a WINS_NAME structure -****************************************************************************/ -static void dump_wins_name(WINS_NAME *wins_name) -{ - fstring name; - int i; - - strncpy(name, wins_name->name, 15); - - DEBUGADD(10,("name: %d, %s<%02x> %x,%x, %d %s %d ", wins_name->name_len, name, wins_name->type, - wins_name->name_flag, wins_name->group_flag, (int)wins_name->id, - inet_ntoa(wins_name->owner), wins_name->num_ip)); - - if (wins_name->num_ip!=1) - for (i=0; i<wins_name->num_ip; i++) - DEBUGADD(10,("%s ", inet_ntoa(wins_name->others[i]))); - - DEBUGADD(10,("\n")); -} - -/**************************************************************************** -dump a replicate structure -****************************************************************************/ -static void dump_replicate(REPLICATE *rep) -{ - int i; - - DEBUGADD(5,("\t\tmsg_type: %d ", rep->msg_type)); - - switch (rep->msg_type) { - case 0: - DEBUGADD(5,("(Add Version Map Table Request)\n")); - break; - case 1: - DEBUGADD(5,("(Add Version Map Table Reply)\n")); - DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->avmt_rep.partner_count)); - for (i=0; i<rep->avmt_rep.partner_count; i++) - dump_wins_owner(&rep->avmt_rep.wins_owner[i]); - DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->avmt_rep.initiating_wins_server))); - break; - case 2: - DEBUGADD(5,("(Send Entries Request)\n")); - dump_wins_owner(&rep->se_rq.wins_owner); - break; - case 3: - DEBUGADD(5,("(Send Entries Reply)\n")); - DEBUGADD(5,("\t\t\tmax_names : %d\n", rep->se_rp.max_names)); - for (i=0; i<rep->se_rp.max_names; i++) - dump_wins_name(&rep->se_rp.wins_name[i]); - break; - case 4: - DEBUGADD(5,("(Update Notify Request)\n")); - DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->un_rq.partner_count)); - for (i=0; i<rep->un_rq.partner_count; i++) - dump_wins_owner(&rep->un_rq.wins_owner[i]); - DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->un_rq.initiating_wins_server))); - break; - default: - DEBUG(5,("\n")); - break; - } -} - -/**************************************************************************** -dump a generic structure -****************************************************************************/ -void dump_generic_packet(GENERIC_PACKET *q) -{ - DEBUG(5,("dump_generic_packet:\n")); - DEBUGADD(5,("\tdata_size: %08x\n", q->header.data_size)); - DEBUGADD(5,("\topcode : %08x\n", q->header.opcode)); - DEBUGADD(5,("\tassoc_ctx: %08x\n", q->header.assoc_ctx)); - DEBUGADD(5,("\tmess_type: %08x ", q->header.mess_type)); - - switch (q->header.mess_type) { - case 0: - DEBUGADD(5,("(Start Association Request)\n")); - DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rq.assoc_ctx)); - DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rq.min_ver)); - DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rq.maj_ver)); - break; - case 1: - DEBUGADD(5,("(Start Association Reply)\n")); - DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rp.assoc_ctx)); - DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rp.min_ver)); - DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rp.maj_ver)); - break; - case 2: - DEBUGADD(5,("(Stop Association)\n")); - DEBUGADD(5,("\t\treason: %08x\n", q->so.reason)); - break; - case 3: - DEBUGADD(5,("(Replication Message)\n")); - dump_replicate(&q->rep); - break; - default: - DEBUG(5,("\n")); - break; - } - -} - -/**************************************************************************** -generate a stop packet -****************************************************************************/ -void stop_packet(GENERIC_PACKET *q, GENERIC_PACKET *r, int reason) -{ - r->header.opcode=OPCODE_NON_NBT; - r->header.assoc_ctx=get_server_assoc(q->header.assoc_ctx); - r->header.mess_type=MESSAGE_TYPE_STOP_ASSOC; - r->so.reason=reason; - -} - - diff --git a/source4/wrepld/partners.c b/source4/wrepld/partners.c deleted file mode 100644 index 2387f5b45f..0000000000 --- a/source4/wrepld/partners.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - Unix SMB/CIFS implementation. - process incoming packets - main loop - Copyright (C) Jean François Micouleau 1998-2002. - - 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 "wins_repl.h" - -/* we can exchange info with 64 partners at any given time */ -WINS_PARTNER current_partners[64]; -int total_current_partners; - -/******************************************************************* -verify if we know this partner -********************************************************************/ -BOOL check_partner(int assoc) -{ - int i; - - DEBUG(5,("check_partner: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==assoc) - return True; - - return False; -} - -/******************************************************************* -add a new entry to the list -********************************************************************/ -BOOL add_partner(int client_assoc, int server_assoc, BOOL pull, BOOL push) -{ - DEBUG(5,("add_partner: total_current_partners: %d\n", total_current_partners)); - - if (total_current_partners==64) - return False; - - current_partners[total_current_partners].client_assoc=client_assoc; - current_partners[total_current_partners].server_assoc=server_assoc; - current_partners[total_current_partners].pull_partner=pull; - current_partners[total_current_partners].push_partner=push; - - total_current_partners++; - - return True; -} - -/******************************************************************* -remove an entry to the list -********************************************************************/ -BOOL remove_partner(int client_assoc) -{ - int i,j; - - DEBUG(5,("remove_partner: total_current_partners: %d\n", total_current_partners)); - - for (i=0; current_partners[i].client_assoc!=client_assoc && i<total_current_partners; i++) - ; - - if (i==total_current_partners) - return False; - - for (j=i+1; j<total_current_partners; j++) { - current_partners[j-1].client_assoc=current_partners[j].client_assoc; - current_partners[j-1].server_assoc=current_partners[j].server_assoc; - current_partners[j-1].pull_partner=current_partners[j].pull_partner; - current_partners[j-1].push_partner=current_partners[j].push_partner; - current_partners[j-1].partner_server.s_addr=current_partners[j].partner_server.s_addr; - current_partners[j-1].other_server.s_addr=current_partners[j].other_server.s_addr; - } - - total_current_partners--; - - return True; -} - -/******************************************************************* -link the client and server context -********************************************************************/ -BOOL update_server_partner(int client_assoc, int server_assoc) -{ - int i; - - DEBUG(5,("update_server_partner: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==client_assoc) { - current_partners[i].server_assoc=server_assoc; - return True; - } - - return False; -} - -/******************************************************************* -verify if it's a pull partner -********************************************************************/ -BOOL check_pull_partner(int assoc) -{ - int i; - - DEBUG(5,("check_pull_partner: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==assoc && - current_partners[i].pull_partner==True) - return True; - - return False; -} - -/******************************************************************* -verify if it's a push partner -********************************************************************/ -BOOL check_push_partner(int assoc) -{ - int i; - - DEBUG(5,("check_push_partner: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==assoc && - current_partners[i].push_partner==True) - return True; - - return False; -} - -/******************************************************************* -return the server ctx linked to the client ctx -********************************************************************/ -int get_server_assoc(int assoc) -{ - int i; - - DEBUG(5,("get_server_assoc: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==assoc) - return current_partners[i].server_assoc; - - return 0; -} - - -/******************************************************************* -link the client and server context -********************************************************************/ -BOOL write_server_assoc_table(int client_assoc, struct in_addr partner, struct in_addr server) -{ - int i; - - DEBUG(5,("write_server_assoc_table: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==client_assoc) { - current_partners[i].partner_server=partner; - current_partners[i].other_server=server; - return True; - } - - return False; -} - -/******************************************************************* -link the client and server context -********************************************************************/ -BOOL get_server_assoc_table(int client_assoc, struct in_addr *partner, struct in_addr *server) -{ - int i; - - DEBUG(5,("get_server_assoc_table: total_current_partners: %d\n", total_current_partners)); - - for (i=0; i<total_current_partners; i++) - if (current_partners[i].client_assoc==client_assoc) { - partner->s_addr=current_partners[i].partner_server.s_addr; - server->s_addr=current_partners[i].other_server.s_addr; - return True; - } - - return False; -} - - diff --git a/source4/wrepld/process.c b/source4/wrepld/process.c deleted file mode 100644 index 1f96dc996c..0000000000 --- a/source4/wrepld/process.c +++ /dev/null @@ -1,983 +0,0 @@ -/* - Unix SMB/CIFS implementation. - process incoming packets - main loop - Copyright (C) Jean François Micouleau 1998-2002. - - 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 "wins_repl.h" - -extern fd_set *listen_set; -extern int listen_number; -extern int *sock_array; - -WINS_OWNER global_wins_table[64][64]; -int partner_count; - -TALLOC_CTX *mem_ctx; - -#define WINS_LIST "wins.tdb" -#define INFO_VERSION "INFO/version" -#define INFO_COUNT "INFO/num_entries" -#define INFO_ID_HIGH "INFO/id_high" -#define INFO_ID_LOW "INFO/id_low" -#define ENTRY_PREFIX "ENTRY/" - - -/******************************************************************* -fill the header of a reply. -********************************************************************/ -static void fill_header(GENERIC_PACKET *g, int opcode, int ctx, int mess) -{ - if (g==NULL) - return; - - g->header.opcode=opcode; - g->header.assoc_ctx=ctx; - g->header.mess_type=mess; -} - -/******************************************************************* -dump the global table, that's a debug code. -********************************************************************/ -static void dump_global_table(void) -{ - int i,j; - - for (i=0;i<partner_count;i++) { - DEBUG(10,("\n%d ", i)); - for (j=0; global_wins_table[i][j].address.s_addr!=0; j++) - DEBUG(10,("%s:%d \t", inet_ntoa(global_wins_table[i][j].address), - (int)global_wins_table[i][j].max_version)); - } - DEBUG(10,("\n")); -} - -/******************************************************************* -start association -********************************************************************/ -static void start_assoc_process(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - /* - * add this request to our current wins partners list - * this list is used to know with who we are in contact - * - */ - r->sa_rp.assoc_ctx=time(NULL); - fill_header(r, OPCODE_NON_NBT, q->sa_rq.assoc_ctx, MESSAGE_TYPE_START_ASSOC_REPLY); - - /* reply we are a NT4 server */ - - /* w2K is min=2, maj=5 */ - - r->sa_rp.min_ver=1; - r->sa_rp.maj_ver=1; - - add_partner(r->sa_rp.assoc_ctx, q->sa_rq.assoc_ctx, False, False); -} - -/******************************************************************* -start association reply -********************************************************************/ -static void start_assoc_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - int i; - - /* check if we have already registered this client */ - if (!check_partner(q->header.assoc_ctx)) { - DEBUG(0,("start_assoc_reply: unknown client\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - if (!update_server_partner(q->header.assoc_ctx, q->sa_rp.assoc_ctx)) { - DEBUG(0,("start_assoc_reply: can't update server ctx\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - /* if pull, request map table */ - if (check_pull_partner(q->header.assoc_ctx)) { - fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE); - - r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST; - DEBUG(5,("start_assoc_reply: requesting map table\n")); - - return; - } - - /* if push, send our table */ - if (check_push_partner(q->header.assoc_ctx)) { - fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE); - r->rep.msg_type=MESSAGE_REP_UPDATE_NOTIFY_REQUEST; - r->rep.un_rq.partner_count=partner_count; - - r->rep.un_rq.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER)); - if (r->rep.un_rq.wins_owner==NULL) { - DEBUG(0,("start_assoc_reply: can't alloc memory\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - for (i=0; i<partner_count; i++) - r->rep.un_rq.wins_owner[i]=global_wins_table[0][i]; - - DEBUG(5,("start_assoc_reply: sending update table\n")); - return; - } - - /* neither push/pull, stop */ - /* we should not come here */ - DEBUG(0,("we have a partner which is neither push nor pull !\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); -} - -/**************************************************************************** -initialise and fill the in-memory partner table. -****************************************************************************/ -int init_wins_partner_table(void) -{ - int i=1,j=0,k; - char **partner = str_list_make(lp_wins_partners(), NULL); - - if (partner==NULL) { - DEBUG(0,("wrepld: no partner list in smb.conf, exiting\n")); - exit_server("normal exit"); - return(0); - } - - DEBUG(4, ("init_wins_partner_table: partners: %s\n", lp_wins_partners())); - - global_wins_table[0][0].address=*iface_n_ip(0); - global_wins_table[0][0].max_version=0; - global_wins_table[0][0].min_version=0; - global_wins_table[0][0].type=0; - - while (partner[j]!=NULL) { - DEBUG(3,("init_wins_partner_table, adding partner: %s\n", partner[j])); - - global_wins_table[0][i].address=*interpret_addr2(partner[j]); - global_wins_table[0][i].max_version=0; - global_wins_table[0][i].min_version=0; - global_wins_table[0][i].type=0; - global_wins_table[0][i].last_pull=0; - global_wins_table[0][i].last_push=0; - - i++; - j++; - } - - for (k=1; k<i;k++) - for (j=0; j<i; j++) - global_wins_table[k][j]=global_wins_table[0][j]; - - str_list_free (&partner); - - return i; -} - -/**************************************************************************** -read the last ID from the wins tdb file. -****************************************************************************/ -static void get_our_last_id(WINS_OWNER *wins_owner) -{ - TDB_CONTEXT *tdb; - - tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600); - if (!tdb) { - DEBUG(2,("get_our_last_id: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) )); - return; - } - - wins_owner->max_version=((SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_HIGH))<<32 | - (SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_LOW); - - tdb_close(tdb); -} - -/**************************************************************************** -send the list of wins server we know. -****************************************************************************/ -static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - int i; - int s_ctx=get_server_assoc(q->header.assoc_ctx); - - if (s_ctx==0) { - DEBUG(5, ("send_version_number_map_table: request for a partner not in our table\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - /* - * return an array of wins servers, we are partner with. - * each entry contains the IP address and the version info - * version: ID of the last entry we've got - */ - - /* the first wins server must be self */ - - /* - * get our last ID from the wins database - * it can have been updated since last read - * as nmbd got registration/release. - */ - get_our_last_id(&global_wins_table[0][0]); - - r->rep.avmt_rep.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER)); - if (r->rep.avmt_rep.wins_owner==NULL) { - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - DEBUG(5,("send_version_number_map_table: partner_count: %d\n", partner_count)); - - for (i=0; i<partner_count; i++) { - DEBUG(5,("send_version_number_map_table, partner: %d -> %s, \n", i, inet_ntoa(global_wins_table[0][i].address))); - r->rep.avmt_rep.wins_owner[i]=global_wins_table[0][i]; - } - - r->rep.msg_type=1; - r->rep.avmt_rep.partner_count=partner_count; - r->rep.avmt_rep.initiating_wins_server.s_addr=0; /* blatant lie, NT4/w2K do the same ! */ - fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE); -} - -/**************************************************************************** -for a given partner, ask it to send entries we don't have. -****************************************************************************/ -static BOOL check_partners_and_send_entries(GENERIC_PACKET *q, GENERIC_PACKET *r, int partner) -{ - int server; - int other; - SMB_BIG_UINT temp; - SMB_BIG_UINT current; - - - /* - * we check if our partner has more records than us. - * we need to check more than our direct partners as - * we can have this case: - * us: A, partners: B,C, indirect partner: D - * A<->B, A<->C, B<->D, C<->D - * - * So if we're talking to B, we need to check if between - * B and C, which one have more records about D. - * and also check if we don't already have the records. - */ - - - /* check all servers even indirect */ - for (server=1; global_wins_table[0][server].address.s_addr!=0; server++) { - current = global_wins_table[partner][server].max_version; - - temp=0; - - for (other=1; other<partner_count; other++) { - /* skip the partner itself */ - if (other==partner) - continue; - - if (global_wins_table[other][server].max_version > temp) - temp=global_wins_table[other][server].max_version; - } - - if (current >= temp && current > global_wins_table[0][server].max_version) { - /* - * it has more records than every body else and more than us, - * ask it the difference between what we have and what it has - */ - fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE); - - r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REQUEST; - r->rep.se_rq.wins_owner.address=global_wins_table[partner][server].address; - - r->rep.se_rq.wins_owner.max_version=global_wins_table[partner][server].max_version; - r->rep.se_rq.wins_owner.min_version=global_wins_table[0][server].max_version; - r->rep.se_rq.wins_owner.type=0; - - write_server_assoc_table(q->header.assoc_ctx, global_wins_table[0][partner].address, global_wins_table[partner][server].address); - - /* - * and we update our version for this server - * as we can't use the IDs returned in the send_entries function - * the max ID can be larger than the largest ID returned - */ - - global_wins_table[0][server].max_version=global_wins_table[partner][server].max_version; - - return True; - } - } - return False; -} - -/**************************************************************************** -receive the list of wins server we know. -****************************************************************************/ -static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - fstring peer; - struct in_addr addr; - int i,j,k,l; - int s_ctx=get_server_assoc(q->header.assoc_ctx); - - if (s_ctx==0) { - DEBUG(5, ("receive_version_number_map_table: request for a partner not in our table\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - fstrcpy(peer,get_socket_addr(q->fd)); - addr=*interpret_addr2(peer); - - get_our_last_id(&global_wins_table[0][0]); - - DEBUG(5,("receive_version_number_map_table: received a map of %d server from: %s\n", - q->rep.avmt_rep.partner_count ,inet_ntoa(q->rep.avmt_rep.initiating_wins_server))); - DEBUG(5,("real peer is: %s\n", peer)); - - for (i=0; global_wins_table[0][i].address.s_addr!=addr.s_addr && i<partner_count;i++) - ; - - if (i==partner_count) { - DEBUG(5,("receive_version_number_map_table: unknown partner: %s\n", peer)); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - for (j=0; j<q->rep.avmt_rep.partner_count;j++) { - /* - * search if we already have this entry or if it's a new one - * it can be a new one in case of propagation - */ - for (k=0; global_wins_table[0][k].address.s_addr!=0 && - global_wins_table[0][k].address.s_addr!=q->rep.avmt_rep.wins_owner[j].address.s_addr; k++); - - global_wins_table[i][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr; - global_wins_table[i][k].max_version=q->rep.avmt_rep.wins_owner[j].max_version; - global_wins_table[i][k].min_version=q->rep.avmt_rep.wins_owner[j].min_version; - global_wins_table[i][k].type=q->rep.avmt_rep.wins_owner[j].type; - - /* - * in case it's a new one, rewrite the address for all the partner - * to reserve the slot. - */ - - for(l=0; l<partner_count; l++) - global_wins_table[l][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr; - } - - dump_global_table(); - - /* - * if this server have newer records than what we have - * for several wins servers, we need to ask it. - * Alas a send entry request is only on one server. - * So in the send entry reply, we'll ask for the next server if required. - */ - - if (check_partners_and_send_entries(q, r, i)) - return; - - /* it doesn't have more entries than us */ - stop_packet(q, r, STOP_REASON_USER_REASON); -} - -/**************************************************************************** -add an entry to the wins list we'll send. -****************************************************************************/ -static BOOL add_record_to_winsname(WINS_NAME **wins_name, int *max_names, char *name, int type, int wins_flags, int id, struct in_addr *ip_list, int num_ips) -{ - WINS_NAME *temp_list; - int i; - int current=*max_names; - - temp_list=talloc_realloc(mem_ctx, *wins_name, (current+1)*sizeof(WINS_NAME)); - if (temp_list==NULL) - return False; - - temp_list[current].name_len=0x11; - - safe_strcpy(temp_list[current].name, name, 15); - - temp_list[current].type=type; - temp_list[current].empty=0; - - temp_list[current].name_flag=wins_flags; - - if ( (wins_flags&0x03) == 1 || (wins_flags&0x03)==2) - temp_list[current].group_flag=0x01000000; - else - temp_list[current].group_flag=0x00000000; - - temp_list[current].id=id; - - temp_list[current].owner.s_addr=ip_list[0].s_addr; - - if (temp_list[current].name_flag & 2) { - temp_list[current].num_ip=num_ips; - temp_list[current].others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*num_ips); - if (temp_list[current].others==NULL) - return False; - - for (i=0; i<num_ips; i++) - temp_list[current].others[i].s_addr=ip_list[i].s_addr; - - } else - temp_list[current].num_ip=1; - - temp_list[current].foo=0xffffffff; - - *wins_name=temp_list; - - return True; -} - -/**************************************************************************** -send the list of name we have. -****************************************************************************/ -static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - int max_names=0; - int i; - time_t time_now = time(NULL); - WINS_OWNER *wins_owner; - TDB_CONTEXT *tdb; - TDB_DATA kbuf, dbuf, newkey; - int s_ctx=get_server_assoc(q->header.assoc_ctx); - int num_interfaces = iface_count(); - - if (s_ctx==0) { - DEBUG(1, ("send_entry_request: request for a partner not in our table\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - - wins_owner=&q->rep.se_rq.wins_owner; - r->rep.se_rp.wins_name=NULL; - - DEBUG(3,("send_entry_request: we have been asked to send the list of wins records\n")); - DEBUGADD(3,("owned by: %s and between min: %d and max: %d\n", inet_ntoa(wins_owner->address), - (int)wins_owner->min_version, (int)wins_owner->max_version)); - - /* - * if we are asked to send records owned by us - * we overwrite the wins ip with 0.0.0.0 - * to make it easy in case of multihomed - */ - - for (i=0; i<num_interfaces; i++) - if (ip_equal(wins_owner->address, *iface_n_ip(i))) { - wins_owner->address=*interpret_addr2("0.0.0.0"); - break; - } - - - tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600); - if (!tdb) { - DEBUG(2,("send_entry_request: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) )); - return; - } - - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - fstring name_type; - pstring name, ip_str; - char *p; - int type = 0; - int nb_flags; - int ttl; - unsigned int num_ips; - int low, high; - SMB_BIG_UINT version; - struct in_addr wins_ip; - struct in_addr *ip_list; - int wins_flags; - int len; - - if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0) - continue; - - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; - - fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX)); - pstrcpy(name, name_type); - - if((p = strchr(name,'#')) != NULL) { - *p = 0; - sscanf(p+1,"%x",&type); - } - - len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd", - &nb_flags, - &high, - &low, - ip_str, - &ttl, - &num_ips, - &wins_flags); - - wins_ip=*interpret_addr2(ip_str); - - /* Allocate the space for the ip_list. */ - if((ip_list = (struct in_addr *)talloc(mem_ctx, num_ips * sizeof(struct in_addr))) == NULL) { - SAFE_FREE(dbuf.dptr); - DEBUG(0,("initialise_wins: talloc fail !\n")); - return; - } - - for (i = 0; i < num_ips; i++) { - len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str); - ip_list[i] = *interpret_addr2(ip_str); - } - - SAFE_FREE(dbuf.dptr); - - /* add all entries that have 60 seconds or more to live */ - if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) { - if(ttl != PERMANENT_TTL) - ttl -= time_now; - - DEBUG( 4, ("send_entry_request: add name: %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - - /* add the record to the list to send */ - version=((SMB_BIG_UINT)high)<<32 | low; - - if (wins_owner->min_version<=version && wins_owner->max_version>=version && - wins_owner->address.s_addr==wins_ip.s_addr) { - if(!add_record_to_winsname(&r->rep.se_rp.wins_name, &max_names, name, type, wins_flags, version, ip_list, num_ips)) - return; - max_names++; - } - - } else { - DEBUG(4, ("send_entry_request: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - } - } - - tdb_close(tdb); - - DEBUG(4,("send_entry_request, sending %d records\n", max_names)); - fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE); - r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REPLY; /* reply */ - r->rep.se_rp.max_names=max_names; -} - - -/**************************************************************************** -. -****************************************************************************/ -static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - int i,j,k,l; - UPDATE_NOTIFY_REQUEST *u; - int s_ctx=get_server_assoc(q->header.assoc_ctx); - - if (s_ctx==0) { - DEBUG(4, ("update_notify_request: request for a partner not in our table\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - u=&q->rep.un_rq; - - /* check if we already have the range of records */ - - DEBUG(5,("update_notify_request: wins server: %s offered this list of %d records:\n", - inet_ntoa(u->initiating_wins_server), u->partner_count)); - - get_our_last_id(&global_wins_table[0][0]); - - for (i=0; i<partner_count; i++) { - if (global_wins_table[0][i].address.s_addr==u->initiating_wins_server.s_addr) { - DEBUG(5,("update_notify_request: found initiator at index %d\n", i)); - break; - } - } - - /* - * some explanation is required, before someone say it's crap. - * - * let's take an example, we have 2 wins partners, we already now - * that our max id is 10, partner 1 ID is 20 and partner 2 ID is 30 - * the array looks like: - * - * 0 1 2 - * 0 10 20 30 - * 1 - * 2 - * - * we receive an update from partner 2 saying he has: 1:15, 2:40, 3:50 - * we must enlarge the array to add partner 3, it will look like: - * - * 0 1 2 3 - * 0 10 20 30 - * 1 - * 2 15 40 50 - * - * now we know, we should pull from partner 2, the records 30->40 of 2 and 0->50 of 3. - * once the pull will be over, our table will look like: - * - * 0 1 2 3 - * 0 10 20 40 50 - * 1 - * 2 15 40 50 - * - * - */ - - for (j=0; j<u->partner_count;j++) { - /* - * search if we already have this entry or if it's a new one - * it can be a new one in case of propagation - */ - - for (k=0; global_wins_table[0][k].address.s_addr!=0 && - global_wins_table[0][k].address.s_addr!=u->wins_owner[j].address.s_addr; k++); - - global_wins_table[i][k].address.s_addr=u->wins_owner[j].address.s_addr; - global_wins_table[i][k].max_version=u->wins_owner[j].max_version; - global_wins_table[i][k].min_version=u->wins_owner[j].min_version; - global_wins_table[i][k].type=u->wins_owner[j].type; - - /* - * in case it's a new one, rewrite the address for all the partner - * to reserve the slot. - */ - - for(l=0; l<partner_count; l++) - global_wins_table[l][k].address.s_addr=u->wins_owner[j].address.s_addr; - } - - dump_global_table(); - - stop_packet(q, r, STOP_REASON_USER_REASON); -} - -/**************************************************************************** -. -****************************************************************************/ -static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - int i,j,k; - struct in_addr partner, server; - pid_t pid; - int s_ctx=get_server_assoc(q->header.assoc_ctx); - WINS_RECORD record; - - if (s_ctx==0) { - DEBUG(1, ("send_entry_reply: request for a partner not in our table\n")); - stop_packet(q, r, STOP_REASON_USER_REASON); - return; - } - - DEBUG(5,("send_entry_reply:got %d new records\n", q->rep.se_rp.max_names)); - - /* we got records from a wins partner but that can be from another wins server */ - /* hopefully we track that */ - - /* and the only doc available from MS is wrong ! */ - - get_server_assoc_table(q->header.assoc_ctx, &partner, &server); - - for (j=0; global_wins_table[0][j].address.s_addr!=0; j++) { - if (global_wins_table[0][j].address.s_addr==server.s_addr) { - DEBUG(5,("send_entry_reply: found server at index %d\n", j)); - break; - } - } - - pid = pidfile_pid("nmbd"); - if (pid == 0) { - DEBUG(0,("send_entry_reply: Can't find pid for nmbd\n")); - return; - } - - for (k=0; k<q->rep.se_rp.max_names; k++) { - DEBUG(5,("send_entry_reply: %s<%02x> %d\n", q->rep.se_rp.wins_name[k].name, q->rep.se_rp.wins_name[k].type, - (int)q->rep.se_rp.wins_name[k].id)); - - safe_strcpy(record.name, q->rep.se_rp.wins_name[k].name, 16); - record.type=q->rep.se_rp.wins_name[k].type; - record.id=q->rep.se_rp.wins_name[k].id; - record.wins_flags=q->rep.se_rp.wins_name[k].name_flag&0x00ff; - record.num_ips=q->rep.se_rp.wins_name[k].num_ip; - - record.wins_ip.s_addr=server.s_addr; - - if (record.num_ips==1) - record.ip[0]=q->rep.se_rp.wins_name[k].owner; - else - for (i=0; i<record.num_ips; i++) - record.ip[i]=q->rep.se_rp.wins_name[k].others[i]; - - record.nb_flags=0; - - if (record.wins_flags&WINS_NGROUP || record.wins_flags&WINS_SGROUP) - record.nb_flags|=NB_GROUP; - - if (record.wins_flags&WINS_ACTIVE) - record.nb_flags|=NB_ACTIVE; - - record.nb_flags|=record.wins_flags&WINS_HNODE; - - message_send_pid(pid, MSG_WINS_NEW_ENTRY, &record, sizeof(record), False); - - } - - dump_global_table(); - - /* - * we got some entries, - * ask the partner to send us the map table again - * to get the other servers entries. - * - * we're getting the map table 1 time more than really - * required. We could remove that call, but that - * would complexify the code. I prefer this trade-of. - */ - fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE); - - r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST; -} - -/**************************************************************************** -decode the replication message and reply. -****************************************************************************/ -static void replicate(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - switch (q->rep.msg_type) { - case 0: - /* add version number map table request */ - send_version_number_map_table(q, r); - break; - case 1: - receive_version_number_map_table(q, r); - break; - case 2: - /* send entry request */ - send_entry_request(q, r); - break; - case 3: - /* send entry reply */ - send_entry_reply(q, r); - break; - case 4: - /* update notification request */ - update_notify_request(q, r); - break; - } -} - -/**************************************************************************** -do a switch on the message type, and return the response size -****************************************************************************/ -static BOOL switch_message(GENERIC_PACKET *q, GENERIC_PACKET *r) -{ - switch (q->header.mess_type) { - case 0: - /* Start association type */ - start_assoc_process(q, r); - return True; - break; - case 1: - /* start association reply */ - start_assoc_reply(q, r); - return True; - break; - case 2: - /* stop association message */ - return False; - break; - case 3: - /* replication message */ - replicate(q, r); - return True; - break; - } - - return False; -} - - -/**************************************************************************** - construct a reply to the incoming packet -****************************************************************************/ -void construct_reply(struct wins_packet_struct *p) -{ - GENERIC_PACKET r; - struct BUFFER buffer; - - buffer.buffer=NULL; - buffer.offset=0; - buffer.length=0; - - DEBUG(5,("dump: received packet\n")); - dump_generic_packet(p->packet); - - /* Verify if the request we got is from a listed partner */ - if (!check_partner(p->packet->header.assoc_ctx)) { - fstring peer; - struct in_addr addr; - int i; - fstrcpy(peer,get_socket_addr(p->fd)); - addr=*interpret_addr2(peer); - - for (i=1; i<partner_count; i++) - if (ip_equal(addr, global_wins_table[0][i].address)) - break; - - if (i==partner_count) { - DEBUG(1,("construct_reply: got a request from a non peer machine: %s\n", peer)); - stop_packet(p->packet, &r, STOP_REASON_AUTH_FAILED); - p->stop_packet=True; - encode_generic_packet(&buffer, &r); - if (!send_smb(p->fd, buffer.buffer)) - exit_server("process_smb: send_smb failed."); - return; - } - } - - if (switch_message(p->packet, &r)) { - encode_generic_packet(&buffer, &r); - DEBUG(5,("dump: sending packet\n")); - dump_generic_packet(&r); - - if(buffer.offset > 0) { - if (!send_smb(p->fd, buffer.buffer)) - exit_server("process_smb: send_smb failed."); - } - } - - /* if we got a stop assoc or if we send a stop assoc, close the fd after */ - if (p->packet->header.mess_type==MESSAGE_TYPE_STOP_ASSOC || - r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC) { - remove_partner(p->packet->header.assoc_ctx); - p->stop_packet=True; - } -} - -/**************************************************************************** - contact periodically our wins partner to do a pull replication -****************************************************************************/ -void run_pull_replication(time_t t) -{ - /* we pull every 30 minutes to query about new records*/ - int i, s; - struct BUFFER buffer; - GENERIC_PACKET p; - - buffer.buffer=NULL; - buffer.offset=0; - buffer.length=0; - - for (i=1; i<partner_count; i++) { - if (global_wins_table[0][i].last_pull < t) { - global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */ - - /* contact the wins server */ - p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST; - p.header.opcode=OPCODE_NON_NBT; - p.header.assoc_ctx=0; - p.sa_rq.assoc_ctx=(int)t; - p.sa_rq.min_ver=1; - p.sa_rq.maj_ver=1; - - DEBUG(3,("run_pull_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address))); - encode_generic_packet(&buffer, &p); - dump_generic_packet(&p); - - /* send the packet to the server and add the descriptor to receive answers */ - s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT); - if (s==-1) { - DEBUG(0,("run_pull_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address))); - return; - } - - if(buffer.offset > 0) { - if (!send_smb(s, buffer.buffer)) - exit_server("run_pull_replication: send_smb failed."); - } - - add_fd_to_sock_array(s); - FD_SET(s, listen_set); - - /* add ourself as a client */ - add_partner((int)t, 0, True, False); - } - } -} - -/**************************************************************************** - contact periodically our wins partner to do a push replication -****************************************************************************/ -void run_push_replication(time_t t) -{ - /* we push every 30 minutes or 25 new entries */ - int i, s; - struct BUFFER buffer; - GENERIC_PACKET p; - - buffer.buffer=NULL; - buffer.offset=0; - buffer.length=0; - - for (i=1; i<partner_count; i++) { - if (global_wins_table[0][i].last_pull < t) { - global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */ - - /* contact the wins server */ - p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST; - p.header.opcode=OPCODE_NON_NBT; - p.header.assoc_ctx=0; - p.sa_rq.assoc_ctx=(int)t; - p.sa_rq.min_ver=1; - p.sa_rq.maj_ver=1; - - DEBUG(3,("run_push_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address))); - encode_generic_packet(&buffer, &p); - dump_generic_packet(&p); - - /* send the packet to the server and add the descriptor to receive answers */ - s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT); - if (s==-1) { - DEBUG(0,("run_push_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address))); - return; - } - - if(buffer.offset > 0) { - if (!send_smb(s, buffer.buffer)) - exit_server("run_push_replication: send_smb failed."); - } - - add_fd_to_sock_array(s); - FD_SET(s, listen_set); - - /* add ourself as a client */ - add_partner((int)t, 0, False, True); - } - } -} - diff --git a/source4/wrepld/server.c b/source4/wrepld/server.c deleted file mode 100644 index f49596dc41..0000000000 --- a/source4/wrepld/server.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Main SMB server routines - Copyright (C) Jean François Micouleau 1998-2002. - - 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 "wins_repl.h" - -extern WINS_OWNER *global_wins_table; -extern int partner_count; - -extern fd_set *listen_set; -extern int listen_number; -extern int *sock_array; - -extern TALLOC_CTX *mem_ctx; - -int wins_port = 42; - -/**************************************************************************** - when exiting, take the whole family -****************************************************************************/ -static void *dflt_sig(void) -{ - exit_server("caught signal"); - return NULL; -} - -/**************************************************************************** - reload the services file - **************************************************************************/ -BOOL reload_services(BOOL test) -{ - BOOL ret; - - if (lp_loaded()) { - pstring fname; - pstrcpy(fname,lp_configfile()); - if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { - pstrcpy(dyn_CONFIGFILE,fname); - test = False; - } - } - - reopen_logs(); - - if (test && !lp_file_list_changed()) - return(True); - - ret = lp_load(dyn_CONFIGFILE,False,False,True); - - - /* perhaps the config filename is now set */ - if (!test) - reload_services(True); - - reopen_logs(); - - load_interfaces(); - - return(ret); -} - -/**************************************************************************** - Catch a sighup. -****************************************************************************/ - -VOLATILE sig_atomic_t reload_after_sighup = False; - -static void sig_hup(int sig) -{ - BlockSignals(True,SIGHUP); - DEBUG(0,("Got SIGHUP\n")); - - sys_select_signal(); - reload_after_sighup = True; - BlockSignals(False,SIGHUP); -} - -#if DUMP_CORE -/******************************************************************* -prepare to dump a core file - carefully! -********************************************************************/ -static BOOL dump_core(void) -{ - char *p; - pstring dname; - pstrcpy(dname,lp_logfile()); - if ((p=strrchr_m(dname,'/'))) *p=0; - pstrcat(dname,"/corefiles"); - mkdir(dname,0700); - sys_chown(dname,getuid(),getgid()); - chmod(dname,0700); - if (chdir(dname)) return(False); - umask(~(0700)); - -#ifdef HAVE_GETRLIMIT -#ifdef RLIMIT_CORE - { - struct rlimit rlp; - getrlimit(RLIMIT_CORE, &rlp); - rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur); - setrlimit(RLIMIT_CORE, &rlp); - getrlimit(RLIMIT_CORE, &rlp); - DEBUG(3,("Core limits now %d %d\n", - (int)rlp.rlim_cur,(int)rlp.rlim_max)); - } -#endif -#endif - - - DEBUG(0,("Dumping core in %s\n",dname)); - abort(); - return(True); -} -#endif - -/**************************************************************************** -exit the server -****************************************************************************/ -void exit_server(const char *reason) -{ - static int firsttime=1; - - if (!firsttime) - exit(0); - firsttime = 0; - - DEBUG(2,("Closing connections\n")); - - if (!reason) { - int oldlevel = DEBUGLEVEL; - DEBUGLEVEL = 10; - DEBUGLEVEL = oldlevel; - DEBUG(0,("===============================================================\n")); -#if DUMP_CORE - if (dump_core()) return; -#endif - } - - DEBUG(3,("Server exit (%s)\n", (reason ? reason : ""))); - exit(0); -} - -/**************************************************************************** - Usage of the program. -****************************************************************************/ - -static void usage(char *pname) -{ - - d_printf("Usage: %s [-DFSaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname); - d_printf(" [-O socket options] [-s services file]\n"); - d_printf("\t-D Become a daemon (default)\n"); - d_printf("\t-F Run daemon in foreground (for daemontools, etc)\n"); - d_printf("\t-S Log to stdout\n"); - d_printf("\t-a Append to log file (default)\n"); - d_printf("\t-i Run interactive (not a daemon)\n" ); - d_printf("\t-o Overwrite log file, don't append\n"); - d_printf("\t-h Print usage\n"); - d_printf("\t-? Print usage\n"); - d_printf("\t-V Print version\n"); - d_printf("\t-d debuglevel Set the debuglevel\n"); - d_printf("\t-l log basename. Basename for log/debug files\n"); - d_printf("\t-p port Listen on the specified port\n"); - d_printf("\t-O socket options Socket options\n"); - d_printf("\t-s services file. Filename of services file\n"); - d_printf("\n"); -} - -/**************************************************************************** - Create an fd_set containing all the sockets in the subnet structures, - plus the broadcast sockets. -***************************************************************************/ - -static BOOL create_listen_fdset(void) -{ - int i; - int num_interfaces = iface_count(); - int s; - - listen_set = (fd_set *)malloc(sizeof(fd_set)); - if(listen_set == NULL) { - DEBUG(0,("create_listen_fdset: malloc fail !\n")); - return True; - } - -#ifdef HAVE_ATEXIT - { - static int atexit_set; - if(atexit_set == 0) { - atexit_set=1; - } - } -#endif - - FD_ZERO(listen_set); - - if(lp_interfaces() && lp_bind_interfaces_only()) { - /* We have been given an interfaces line, and been - told to only bind to those interfaces. Create a - socket per interface and bind to only these. - */ - - if(num_interfaces > FD_SETSIZE) { - DEBUG(0,("create_listen_fdset: Too many interfaces specified to bind to. Number was %d max can be %d\n", num_interfaces, FD_SETSIZE)); - return False; - } - - /* Now open a listen socket for each of the interfaces. */ - for(i = 0; i < num_interfaces; i++) { - struct in_addr *ifip = iface_n_ip(i); - - if(ifip == NULL) { - DEBUG(0,("create_listen_fdset: interface %d has NULL IP address !\n", i)); - continue; - } - s = open_socket_in(SOCK_STREAM, wins_port, 0, ifip->s_addr, True); - if(s == -1) - return False; - - /* ready to listen */ - set_socket_options(s,"SO_KEEPALIVE"); - set_socket_options(s,lp_socket_options()); - - if (listen(s, 5) == -1) { - DEBUG(5,("listen: %s\n",strerror(errno))); - close(s); - return False; - } - add_fd_to_sock_array(s); - FD_SET(s, listen_set); - } - } else { - /* Just bind to 0.0.0.0 - accept connections from anywhere. */ - num_interfaces = 1; - - /* open an incoming socket */ - s = open_socket_in(SOCK_STREAM, wins_port, 0, interpret_addr(lp_socket_address()),True); - if (s == -1) - return(False); - - /* ready to listen */ - set_socket_options(s,"SO_KEEPALIVE"); - set_socket_options(s, lp_socket_options()); - - if (listen(s, 5) == -1) { - DEBUG(0,("create_listen_fdset: listen: %s\n", strerror(errno))); - close(s); - return False; - } - - add_fd_to_sock_array(s); - FD_SET(s, listen_set); - } - - return True; -} - -/******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ -static struct wins_packet_struct *read_wins_packet(int fd, int timeout) -{ - struct wins_packet_struct *p; - GENERIC_PACKET *q; - struct BUFFER inbuf; - ssize_t len=0; - size_t total=0; - ssize_t ret; - BOOL ok = False; - - inbuf.buffer=NULL; - inbuf.length=0; - inbuf.offset=0; - - if(!grow_buffer(&inbuf, 4)) - return NULL; - - ok = (read(fd, inbuf.buffer,4) == 4); - if (!ok) - return NULL; - len = smb_len(inbuf.buffer); - - if (len<=0) - return NULL; - - if(!grow_buffer(&inbuf, len)) - return NULL; - - while (total < len) { - ret = read(fd, inbuf.buffer + total + 4, len - total); - if (ret == 0) { - DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(len - total), strerror(errno) )); - return NULL; - } - if (ret == -1) { - DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(len - total), strerror(errno) )); - return NULL; - } - total += ret; - } - - q = (GENERIC_PACKET *)talloc(mem_ctx, sizeof(GENERIC_PACKET)); - p = (struct wins_packet_struct *)talloc(mem_ctx, sizeof(*p)); - if (q==NULL || p==NULL) - return NULL; - - decode_generic_packet(&inbuf, q); - - q->fd=fd; - - p->next = NULL; - p->prev = NULL; - p->stop_packet = False; - p->timestamp = time(NULL); - p->fd = fd; - p->packet=q; - - return p; -} - -static struct wins_packet_struct *packet_queue = NULL; - -/******************************************************************* - Queue a packet into a packet queue -******************************************************************/ -static void queue_packet(struct wins_packet_struct *packet) -{ - struct wins_packet_struct *p; - - if (!packet_queue) { - packet->prev = NULL; - packet->next = NULL; - packet_queue = packet; - return; - } - - /* find the bottom */ - for (p=packet_queue;p->next;p=p->next) - ; - - p->next = packet; - packet->next = NULL; - packet->prev = p; -} - -/**************************************************************************** - Listens for NMB or DGRAM packets, and queues them. - return True if the socket is dead -***************************************************************************/ -static BOOL listen_for_wins_packets(void) -{ - int num_interfaces = iface_count(); - fd_set fds; - int i, num, s, new_s; - struct timeval timeout; - - if(listen_set == NULL) { - if(!create_listen_fdset()) { - DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n")); - return True; - } - } - - memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set)); - - timeout.tv_sec = NMBD_SELECT_LOOP; - timeout.tv_usec = 0; - - /* Prepare for the select - allow certain signals. */ - - BlockSignals(False, SIGTERM); - - num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - - /* We can only take signals when we are in the select - block them again here. */ - - BlockSignals(True, SIGTERM); - - if(num == -1) - return False; - - for (; num > 0; num--) { - s = -1; - /* check the sockets we are only listening on, waiting to accept */ - for (i=0; i<num_interfaces; i++) { - struct sockaddr addr; - socklen_t in_addrlen = sizeof(addr); - - if(FD_ISSET(sock_array[i], &fds)) { - s = sock_array[i]; - /* Clear this so we don't look at it again. */ - FD_CLR(sock_array[i], &fds); - - /* accept and add the new socket to the listen set */ - new_s=accept(s, &addr, &in_addrlen); - - if (new_s < 0) - continue; - - DEBUG(5,("listen_for_wins_packets: new connection, old: %d, new : %d\n", s, new_s)); - - set_socket_options(new_s, "SO_KEEPALIVE"); - set_socket_options(new_s, lp_socket_options()); - FD_SET(new_s, listen_set); - add_fd_to_sock_array(new_s); - } - } - - /* - * check for the sockets we are waiting data from - * either client sending datas - * or reply to our requests - */ - for (i=num_interfaces; i<listen_number; i++) { - if(FD_ISSET(sock_array[i], &fds)) { - struct wins_packet_struct *packet = read_wins_packet(sock_array[i], timeout.tv_sec); - if (packet) { - packet->fd = sock_array[i]; - queue_packet(packet); - } - DEBUG(2,("listen_for_wins_packets: some data on fd %d\n", sock_array[i])); - FD_CLR(sock_array[i], &fds); - break; - } - - } - - } - - return False; -} - - -/******************************************************************* - Run elements off the packet queue till its empty -******************************************************************/ - -static void run_wins_packet_queue(void) -{ - struct wins_packet_struct *p; - - while ((p = packet_queue)) { - packet_queue = p->next; - if (packet_queue) - packet_queue->prev = NULL; - p->next = p->prev = NULL; - - construct_reply(p); - - /* if it was a stop assoc, close the connection */ - if (p->stop_packet) { - FD_CLR(p->fd, listen_set); - remove_fd_from_sock_array(p->fd); - close(p->fd); - } - } -} - -/**************************************************************************** ** - The main select loop. - **************************************************************************** */ -static void process(void) -{ - - while( True ) { - time_t t = time(NULL); - - /* check for internal messages */ - message_dispatch(); - - if(listen_for_wins_packets()) - return; - - run_wins_packet_queue(); - - run_pull_replication(t); - - run_push_replication(t); - - /* - * Reload the services file if we got a sighup. - */ - - if(reload_after_sighup) { - reload_services( True ); - reopen_logs(); - reload_after_sighup = False; - } - - /* free temp memory */ - talloc_destroy_pool(mem_ctx); - - /* free up temp memory */ - lp_talloc_free(); - } -} /* process */ - -/**************************************************************************** - main program -****************************************************************************/ - int main(int argc,char *argv[]) -{ - extern char *optarg; - /* shall I run as a daemon */ - BOOL is_daemon = False; - BOOL interactive = False; - BOOL specified_logfile = False; - BOOL Fork = True; - BOOL log_stdout = False; - int opt; - pstring logfile; - -#ifdef HAVE_SET_AUTH_PARAMETERS - set_auth_parameters(argc,argv); -#endif - - /* this is for people who can't start the program correctly */ - while (argc > 1 && (*argv[1] != '-')) { - argv++; - argc--; - } - - while ( EOF != (opt = getopt(argc, argv, "FSO:l:s:d:Dp:h?Vaiof:")) ) - switch (opt) { - case 'F': - Fork = False; - break; - case 'S': - log_stdout = True; - break; - case 'O': - lp_set_cmdline("socket options", optarg); - break; - - case 's': - pstrcpy(dyn_CONFIGFILE,optarg); - break; - - case 'l': - specified_logfile = True; - slprintf(logfile, sizeof(logfile)-1, "%s/log.wrepld", optarg); - lp_set_logfile(logfile); - break; - - case 'i': - interactive = True; - Fork = False; - log_stdout = True; - break; - - case 'D': - is_daemon = True; - break; - - case 'd': - if (*optarg == 'A') - DEBUGLEVEL = 10000; - else - DEBUGLEVEL = atoi(optarg); - break; - - case 'p': - wins_port = atoi(optarg); - break; - - case 'h': - case '?': - usage(argv[0]); - exit(0); - break; - - case 'V': - d_printf("Version %s\n",VERSION); - exit(0); - break; - default: - DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n")); - usage(argv[0]); - exit(1); - } - if (log_stdout && Fork) { - d_printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"); - usage(argv[0]); - exit(1); - } - -#ifdef HAVE_SETLUID - /* needed for SecureWare on SCO */ - setluid(0); -#endif - - sec_init(); - - load_case_tables(); - - if(!specified_logfile) { - slprintf(logfile, sizeof(logfile)-1, "%s/log.wrepld", - dyn_LOGFILEBASE); - lp_set_logfile(logfile); - } - - set_remote_machine_name("wrepld"); - - setup_logging(argv[0],log_stdout?DEBUG_STDOUT:DEBUG_FILE); - - /* we want to re-seed early to prevent time delays causing - client problems at a later date. (tridge) */ - generate_random_buffer(NULL, 0, False); - - /* make absolutely sure we run as root - to handle cases where people - are crazy enough to have it setuid */ - - gain_root_privilege(); - gain_root_group_privilege(); - - fault_setup((void (*)(void *))exit_server); - CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig); - - /* we are never interested in SIGPIPE */ - BlockSignals(True,SIGPIPE); - -#if defined(SIGFPE) - /* we are never interested in SIGFPE */ - BlockSignals(True,SIGFPE); -#endif - -#if defined(SIGUSR2) - /* We are no longer interested in USR2 */ - BlockSignals(True,SIGUSR2); -#endif - - /* POSIX demands that signals are inherited. If the invoking process has - * these signals masked, we will have problems, as we won't recieve them. */ - BlockSignals(False, SIGHUP); - BlockSignals(False, SIGUSR1); - - /* we want total control over the permissions on created files, - so set our umask to 0 */ - umask(0); - - reopen_logs(); - - DEBUG(1,( "wrepld version %s started.\n", VERSION)); - DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n")); - - DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", - (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); - - if (sizeof(uint16) < 2 || sizeof(uint32) < 4) { - DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); - exit(1); - } - - /* - * Do this before reload_services. - */ - - if (!reload_services(False)) - return(-1); - - if (!init_names()) - return -1; - -#ifdef WITH_PROFILE - if (!profile_setup(False)) { - DEBUG(0,("ERROR: failed to setup profiling\n")); - return -1; - } -#endif - - CatchSignal(SIGHUP,SIGNAL_CAST sig_hup); - - DEBUG(3,( "loaded services\n")); - - if (!is_daemon && !is_a_socket(0)) { - DEBUG(0,("standard input is not a socket, assuming -D option\n")); - is_daemon = True; - } - - if (is_daemon && !interactive) { - DEBUG( 3, ( "Becoming a daemon.\n" ) ); - become_daemon(Fork); - } - -#if HAVE_SETPGID - /* - * If we're interactive we want to set our own process group for - * signal management. - */ - if (interactive) - setpgid( (pid_t)0, (pid_t)0); -#endif - - if (!directory_exist(lp_lockdir(), NULL)) { - mkdir(lp_lockdir(), 0755); - } - - if (is_daemon) { - pidfile_create("wrepld"); - } - - if (!message_init()) { - exit(1); - } - - /* Initialise the memory context */ - mem_ctx=talloc_init("wins repl talloc ctx"); - - /* initialise the global partners table */ - partner_count=init_wins_partner_table(); - - /* We can only take signals in the select. */ - BlockSignals( True, SIGTERM ); - - process(); - - exit_server("normal exit"); - return(0); -} diff --git a/source4/wrepld/socket.c b/source4/wrepld/socket.c deleted file mode 100644 index 3d759f0ab8..0000000000 --- a/source4/wrepld/socket.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - Unix SMB/CIFS implementation. - process incoming packets - main loop - Copyright (C) Jean François Micouleau 1998-2002. - - 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 "wins_repl.h" - -fd_set *listen_set = NULL; -int listen_number = 0; -int *sock_array = NULL; - -/******************************************************************* - Add an fd from the sock_array -******************************************************************/ -void add_fd_to_sock_array(int fd) -{ - int *temp_sock=NULL; - - temp_sock=(int *)Realloc(sock_array, (listen_number+1)*sizeof(int)); - if (temp_sock==NULL) - return; - - sock_array=temp_sock; - sock_array[listen_number]=fd; - listen_number++; -} - - -/******************************************************************* - Remove an fd from the sock_array -******************************************************************/ -void remove_fd_from_sock_array(int fd) -{ - int i,j; - - for (i=0; sock_array[i]!=fd && i<listen_number; i++) - ; - - if (i==listen_number) { - DEBUG(0,("remove_fd_from_sock_array: unknown fd: %d\n", fd)); - return; - } - - if (i==listen_number-1) { - sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int)); - return; - } - - for (j=i; j<listen_number-1; j++) - sock_array[j]=sock_array[j+1]; - - sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int)); -} diff --git a/source4/wrepld/wins_repl.h b/source4/wrepld/wins_repl.h deleted file mode 100644 index 7aa7fa6a9e..0000000000 --- a/source4/wrepld/wins_repl.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Jean François Micouleau 1998-2002. - * - * 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. - */ - -#define OPCODE_NON_NBT 0x00007800 - -/* the messages */ -#define MESSAGE_TYPE_START_ASSOC_REQUEST 0 -#define MESSAGE_TYPE_START_ASSOC_REPLY 1 -#define MESSAGE_TYPE_STOP_ASSOC 2 -#define MESSAGE_TYPE_REPLICATE 3 - -/* the replication sub-message */ -#define MESSAGE_REP_ADD_VERSION_REQUEST 0 -#define MESSAGE_REP_ADD_VERSION_REPLY 1 -#define MESSAGE_REP_SEND_ENTRIES_REQUEST 2 -#define MESSAGE_REP_SEND_ENTRIES_REPLY 3 -#define MESSAGE_REP_UPDATE_NOTIFY_REQUEST 4 - -/* stop reasons */ -#define STOP_REASON_USER_REASON 0 -#define STOP_REASON_AUTH_FAILED 1 -#define STOP_REASON_INCOMPLETE_VERSION 2 -#define STOP_REASON_BUG_CHECK 3 -#define STOP_REASON_MESSAGE_ERROR 4 - - -typedef struct _WINS_OWNER { - struct in_addr address; - SMB_BIG_UINT max_version; - SMB_BIG_UINT min_version; - int type; - time_t last_pull; - time_t last_push; -} WINS_OWNER; - -typedef struct _WINS_NAME { - int name_len; /* always 0x11 */ - char name[16]; - char type; - int empty; - int name_flag; - int group_flag; - SMB_BIG_UINT id; - int num_ip; - struct in_addr owner; - struct in_addr *others; - int foo; /* 0xffffff */ -} WINS_NAME; - -typedef struct _WINS_PARTNERS -{ - int client_assoc; - int server_assoc; - BOOL pull_partner; - BOOL push_partner; - struct in_addr partner_server; - struct in_addr other_server; -} WINS_PARTNER; - -typedef struct _generic_header{ - int data_size; - int opcode; - int assoc_ctx; - int mess_type; -} generic_header; - -typedef struct _START_ASSOC_REQUEST { - int assoc_ctx; - int min_ver; - int maj_ver; -} START_ASSOC_REQUEST; - -typedef struct _START_ASSOC_REPLY { - int assoc_ctx; - int min_ver; - int maj_ver; -} START_ASSOC_REPLY; - -typedef struct _STOP_ASSOC { - int reason; -} STOP_ASSOC; - -typedef struct _AVMT_REP { - int partner_count; - WINS_OWNER *wins_owner; - struct in_addr initiating_wins_server; -} AVMT_REP; - -typedef struct _SEND_ENTRIES_REQUEST { - WINS_OWNER wins_owner; -} SEND_ENTRIES_REQUEST; - -typedef struct _SEND_ENTRIES_REPLY { - int max_names; - WINS_NAME *wins_name; -} SEND_ENTRIES_REPLY; - -typedef struct _UPDATE_NOTIFY_REQUEST { - int partner_count; - WINS_OWNER *wins_owner; - struct in_addr initiating_wins_server; -} UPDATE_NOTIFY_REQUEST; - -typedef struct _REPLICATE { - int msg_type; - - AVMT_REP avmt_rep; - SEND_ENTRIES_REQUEST se_rq; - SEND_ENTRIES_REPLY se_rp; - UPDATE_NOTIFY_REQUEST un_rq; -} REPLICATE; - - -typedef struct _GENERIC_PACKET { - int fd; - - generic_header header; - - START_ASSOC_REQUEST sa_rq; - START_ASSOC_REPLY sa_rp; - STOP_ASSOC so; - REPLICATE rep; -} GENERIC_PACKET; - -struct wins_packet_struct -{ - struct wins_packet_struct *next; - struct wins_packet_struct *prev; - BOOL stop_packet; - int fd; - time_t timestamp; - GENERIC_PACKET *packet; -}; - -struct BUFFER { - char *buffer; - int offset; - int length; -}; - - - |