diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-07-15 10:35:28 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-07-15 10:35:28 +0000 |
commit | e90b65284812aaa5ff9e9935ce9bbad7791cbbcd (patch) | |
tree | 9e744d1dc2f93934a4b49166a37383d3cb2b2139 /source3/wrepld | |
parent | ec167dc9cc0ec2ee461837c25a371d2981744208 (diff) | |
download | samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.tar.gz samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.tar.bz2 samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.zip |
updated the 3.0 branch from the head branch - ready for alpha18
(This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce)
Diffstat (limited to 'source3/wrepld')
-rw-r--r-- | source3/wrepld/parser.c | 243 | ||||
-rw-r--r-- | source3/wrepld/partners.c | 20 | ||||
-rw-r--r-- | source3/wrepld/process.c | 119 | ||||
-rw-r--r-- | source3/wrepld/server.c | 45 |
4 files changed, 295 insertions, 132 deletions
diff --git a/source3/wrepld/parser.c b/source3/wrepld/parser.c index 61d8a604ce..f5b9be6727 100644 --- a/source3/wrepld/parser.c +++ b/source3/wrepld/parser.c @@ -26,19 +26,23 @@ extern TALLOC_CTX *mem_ctx; /**************************************************************************** grow the send buffer if necessary ****************************************************************************/ -static BOOL grow_buffer(struct BUFFER *buffer, int more) +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+256) ); + 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+=256; + buffer->length+=more; buffer->buffer=temp; } @@ -46,44 +50,59 @@ static BOOL grow_buffer(struct BUFFER *buffer, int more) } /**************************************************************************** +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 int decode_wins_owner(char *inbuf, int offset, WINS_OWNER *wins_owner) +static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner) { - wins_owner->address.s_addr=IVAL(inbuf, offset); - offset+=4; - wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf, offset))<<32; - offset+=4; - wins_owner->max_version|=RIVAL(inbuf, offset); - offset+=4; - wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf, offset))<<32; - offset+=4; - wins_owner->min_version|=RIVAL(inbuf, offset); - offset+=4; - wins_owner->type=RIVAL(inbuf, offset); - offset+=4; - - return offset; + 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 int decode_wins_name(char *outbuf, int offset, WINS_NAME *wins_name) +static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name) { char *p; int i; - wins_name->name_len=RIVAL(outbuf, offset); - offset+=4; - memcpy(wins_name->name,outbuf+offset, 15); + 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[16]='\0'; if((p = strchr(wins_name->name,' ')) != NULL) *p = 0; - offset+=15; + outbuf->offset+=15; - wins_name->type=(int)outbuf[offset++]; + wins_name->type=(int)outbuf->buffer[outbuf->offset++]; /* * fix to bug in WINS replication, @@ -94,136 +113,162 @@ static int decode_wins_name(char *outbuf, int offset, WINS_NAME *wins_name) wins_name->type=0x1B; } - wins_name->empty=RIVAL(outbuf, offset); - offset+=4; + wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset); + outbuf->offset+=4; - wins_name->name_flag=RIVAL(outbuf, offset); - offset+=4; - wins_name->group_flag=RIVAL(outbuf, offset); - offset+=4; - wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf, offset))<<32; - offset+=4; - wins_name->id|=RIVAL(outbuf, offset); - 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) { - wins_name->num_ip=IVAL(outbuf, offset); - offset+=4; + if(!check_buffer(outbuf, 4)) + return; + wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset); + outbuf->offset+=4; } else wins_name->num_ip=1; - wins_name->owner.s_addr=IVAL(outbuf, offset); - offset+=4; + 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 offset; + 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, offset); - offset+=4; + wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset); + outbuf->offset+=4; } } - wins_name->foo=RIVAL(outbuf, offset); - offset+=4; + if(!check_buffer(outbuf, 4)) + return; + wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset); + outbuf->offset+=4; - return offset; } /**************************************************************************** decode a update notification request ****************************************************************************/ -static void decode_update_notify_request(char *inbuf, UPDATE_NOTIFY_REQUEST *un_rq) +static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq) { int i; - int offset=4; - un_rq->partner_count=RIVAL(inbuf, 0); + 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++) - offset=decode_wins_owner(inbuf, offset, &un_rq->wins_owner[i]); + decode_wins_owner(inbuf, &un_rq->wins_owner[i]); - un_rq->initiating_wins_server.s_addr=IVAL(inbuf, offset); + 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(char *inbuf, SEND_ENTRIES_REQUEST *se_rq) +static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq) { - int offset; - offset=decode_wins_owner(inbuf, 0, &se_rq->wins_owner); + decode_wins_owner(inbuf, &se_rq->wins_owner); } /**************************************************************************** decode a send entries reply ****************************************************************************/ -static void decode_send_entries_reply(char *inbuf, SEND_ENTRIES_REPLY *se_rp) +static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp) { - int i, offset=4; - se_rp->max_names = RIVAL(inbuf, 0); + 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++) - offset = decode_wins_name(inbuf, offset, &se_rp->wins_name[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(char *inbuf, AVMT_REP *avmt_rep) +static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep) { int i; - int offset=4; - avmt_rep->partner_count=RIVAL(inbuf, 0); + 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++) - offset=decode_wins_owner(inbuf, offset, &avmt_rep->wins_owner[i]); + decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]); - avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf, offset); + 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(char *inbuf, REPLICATE *rep) +static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep) { - rep->msg_type = RIVAL(inbuf, 0); + 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+4, &rep->avmt_rep); + decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep); break; case 2: /* send entry request */ - decode_send_entries_request(inbuf+4, &rep->se_rq); + decode_send_entries_request(inbuf, &rep->se_rq); break; case 3: /* send entry request */ - decode_send_entries_reply(inbuf+4, &rep->se_rp); + decode_send_entries_reply(inbuf, &rep->se_rp); break; case 4: /* update notification request */ - decode_update_notify_request(inbuf+4, &rep->un_rq); + decode_update_notify_request(inbuf, &rep->un_rq); break; default: DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type)); @@ -234,61 +279,75 @@ static void decode_replicate(char *inbuf, REPLICATE *rep) /**************************************************************************** read the generic header and fill the struct. ****************************************************************************/ -static void read_generic_header(char *inbuf, generic_header *q) +static void read_generic_header(struct BUFFER *inbuf, generic_header *q) { - q->data_size = RIVAL(inbuf,0); - q->opcode = RIVAL(inbuf,4); - q->assoc_ctx = RIVAL(inbuf,8); - q->mess_type = RIVAL(inbuf,12); + 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(char *inbuf, START_ASSOC_REQUEST *q) +static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q) { - q->assoc_ctx = RIVAL(inbuf, 0); - q->min_ver = RSVAL(inbuf, 4); - q->maj_ver = RSVAL(inbuf, 6); + 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(char *inbuf, START_ASSOC_REPLY *r) +static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r) { - r->assoc_ctx=RIVAL(inbuf, 0); - r->min_ver = RSVAL(inbuf, 4); - r->maj_ver = RSVAL(inbuf, 6); + 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(char *inbuf, STOP_ASSOC *r) +static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r) { - r->reason=RIVAL(inbuf, 0); + 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(char *inbuf, GENERIC_PACKET *q) +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+16, &q->sa_rq); + decode_start_assoc_request(inbuf, &q->sa_rq); break; case 1: - decode_start_assoc_reply(inbuf+16, &q->sa_rp); + decode_start_assoc_reply(inbuf, &q->sa_rp); break; case 2: - decode_stop_assoc(inbuf+16, &q->so); + decode_stop_assoc(inbuf, &q->so); break; case 3: - decode_replicate(inbuf+16, &q->rep); + decode_replicate(inbuf, &q->rep); break; default: DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type)); @@ -296,6 +355,9 @@ void decode_generic_packet(char *inbuf, GENERIC_PACKET *q) } } +/**************************************************************************** +encode a WINS_OWNER struct +****************************************************************************/ static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner) { if (!grow_buffer(outbuf, 24)) @@ -316,6 +378,9 @@ static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner) } +/**************************************************************************** +encode a WINS_NAME struct +****************************************************************************/ static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name) { int i; @@ -366,7 +431,7 @@ static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name) } /**************************************************************************** -decode a update notification request +encode a update notification request ****************************************************************************/ static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq) { @@ -464,7 +529,7 @@ static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep) encode_update_notify_request(outbuf, &rep->un_rq); break; default: - DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type)); + DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type)); break; } } diff --git a/source3/wrepld/partners.c b/source3/wrepld/partners.c index abdaeaf2ee..2387f5b45f 100644 --- a/source3/wrepld/partners.c +++ b/source3/wrepld/partners.c @@ -31,7 +31,9 @@ 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; @@ -44,6 +46,8 @@ 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; @@ -64,6 +68,8 @@ 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++) ; @@ -91,6 +97,8 @@ 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; @@ -107,6 +115,8 @@ 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) @@ -122,6 +132,8 @@ 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) @@ -137,6 +149,8 @@ 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; @@ -152,6 +166,8 @@ BOOL write_server_assoc_table(int client_assoc, struct in_addr partner, struct i { 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; @@ -169,6 +185,8 @@ BOOL get_server_assoc_table(int client_assoc, struct in_addr *partner, struct in { 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; diff --git a/source3/wrepld/process.c b/source3/wrepld/process.c index e63b8a993c..7615b8c78a 100644 --- a/source3/wrepld/process.c +++ b/source3/wrepld/process.c @@ -59,12 +59,12 @@ static void dump_global_table(void) int i,j; for (i=0;i<partner_count;i++) { - DEBUG(0,("\n%d ", i)); + DEBUG(10,("\n%d ", i)); for (j=0; global_wins_table[i][j].address.s_addr!=0; j++) - DEBUG(0,("%s:%d \t", inet_ntoa(global_wins_table[i][j].address), + DEBUG(10,("%s:%d \t", inet_ntoa(global_wins_table[i][j].address), (int)global_wins_table[i][j].max_version)); } - DEBUG(0,("\n")); + DEBUG(10,("\n")); } /******************************************************************* @@ -115,7 +115,7 @@ static void start_assoc_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) 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(0,("start_assoc_reply: requesting map table\n")); + DEBUG(5,("start_assoc_reply: requesting map table\n")); return; } @@ -136,7 +136,7 @@ static void start_assoc_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) for (i=0; i<partner_count; i++) r->rep.un_rq.wins_owner[i]=global_wins_table[0][i]; - DEBUG(0,("start_assoc_reply: sending update table\n")); + DEBUG(5,("start_assoc_reply: sending update table\n")); return; } @@ -152,9 +152,15 @@ initialise and fill the in-memory partner table. int init_wins_partner_table(void) { int i=1,j=0,k; - char **partner = lp_list_make(lp_wins_partners()); + char **partner = str_list_make(lp_wins_partners()); - DEBUG(0, ("init_wins_partner_table: partners: %s\n", lp_wins_partners())); + 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; @@ -162,7 +168,7 @@ int init_wins_partner_table(void) global_wins_table[0][0].type=0; while (partner[j]!=NULL) { - DEBUG(0,("init_wins_partner_table, adding partner: %s\n", partner[j])); + 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; @@ -179,7 +185,7 @@ int init_wins_partner_table(void) for (j=0; j<i; j++) global_wins_table[k][j]=global_wins_table[0][j]; - lp_list_free (&partner); + str_list_free (&partner); return i; } @@ -212,7 +218,7 @@ static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r) int s_ctx=get_server_assoc(q->header.assoc_ctx); if (s_ctx==0) { - DEBUG(0, ("send_entry_reply: request for a partner not in our table\n")); + 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; } @@ -238,10 +244,10 @@ static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r) return; } - DEBUG(0,("send_version_number_map_table: partner_count: %d\n", partner_count)); + DEBUG(5,("send_version_number_map_table: partner_count: %d\n", partner_count)); for (i=0; i<partner_count; i++) { - DEBUG(0,("send_version_number_map_table, partner: %d -> %s, \n", i, inet_ntoa(global_wins_table[0][i].address))); + 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]; } @@ -331,7 +337,7 @@ static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET * int s_ctx=get_server_assoc(q->header.assoc_ctx); if (s_ctx==0) { - DEBUG(0, ("receive_version_number_map_table: request for a partner not in our table\n")); + 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; } @@ -341,15 +347,15 @@ static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET * get_our_last_id(&global_wins_table[0][0]); - DEBUG(0,("receive_version_number_map_table: received a map of %d server from: %s\n", + 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(0,("real peer is: %s\n", peer)); + 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(0,("receive_version_number_map_table: unknown partner: %s\n", peer)); + DEBUG(5,("receive_version_number_map_table: unknown partner: %s\n", peer)); stop_packet(q, r, STOP_REASON_USER_REASON); return; } @@ -382,7 +388,7 @@ static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET * * 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 is required. + * So in the send entry reply, we'll ask for the next server if required. */ if (check_partners_and_send_entries(q, r, i)) @@ -457,7 +463,7 @@ static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r) int num_interfaces = iface_count(); if (s_ctx==0) { - DEBUG(0, ("send_entry_request: request for a partner not in our table\n")); + DEBUG(1, ("send_entry_request: request for a partner not in our table\n")); stop_packet(q, r, STOP_REASON_USER_REASON); return; } @@ -466,8 +472,8 @@ static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r) wins_owner=&q->rep.se_rq.wins_owner; r->rep.se_rp.wins_name=NULL; - DEBUG(0,("send_entry_request: we have been asked to send the list of wins records\n")); - DEBUGADD(0,("owned by: %s and between min: %d and max: %d\n", inet_ntoa(wins_owner->address), + 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)); /* @@ -569,7 +575,7 @@ static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r) tdb_close(tdb); - DEBUG(0,("send_entry_request, sending %d records\n", max_names)); + 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; @@ -586,7 +592,7 @@ static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r) int s_ctx=get_server_assoc(q->header.assoc_ctx); if (s_ctx==0) { - DEBUG(0, ("send_entry_reply: request for a partner not in our table\n")); + DEBUG(4, ("update_notify_request: request for a partner not in our table\n")); stop_packet(q, r, STOP_REASON_USER_REASON); return; } @@ -595,14 +601,14 @@ static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r) /* check if we already have the range of records */ - DEBUG(0,("update_notify_request: wins server: %s offered this list of %d records:\n", + 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(0,("update_notify_request: found initiator at index %d\n", i)); + DEBUG(5,("update_notify_request: found initiator at index %d\n", i)); break; } } @@ -678,12 +684,12 @@ static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) WINS_RECORD record; if (s_ctx==0) { - DEBUG(0, ("send_entry_reply: request for a partner not in our table\n")); + DEBUG(1, ("send_entry_reply: request for a partner not in our table\n")); stop_packet(q, r, STOP_REASON_USER_REASON); return; } - DEBUG(0,("send_entry_reply:got %d new records\n", q->rep.se_rp.max_names)); + 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 */ @@ -694,7 +700,7 @@ static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) 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(0,("send_entry_reply: found server at index %d\n", j)); + DEBUG(5,("send_entry_reply: found server at index %d\n", j)); break; } } @@ -706,7 +712,7 @@ static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r) } for (k=0; k<q->rep.se_rp.max_names; k++) { - DEBUG(0,("send_entry_reply: %s<%02x> %d\n", q->rep.se_rp.wins_name[k].name, q->rep.se_rp.wins_name[k].type, + 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); @@ -799,11 +805,6 @@ static BOOL switch_message(GENERIC_PACKET *q, GENERIC_PACKET *r) break; case 2: /* stop association message */ - /* - * remove the partner from the list and - * reply false to NOT send a packet - */ - remove_partner(q->header.assoc_ctx); return False; break; case 3: @@ -829,7 +830,7 @@ void construct_reply(struct wins_packet_struct *p) buffer.offset=0; buffer.length=0; - DEBUG(0,("dump: received packet\n")); + DEBUG(5,("dump: received packet\n")); dump_generic_packet(p->packet); /* Verify if the request we got is from a listed partner */ @@ -845,7 +846,7 @@ void construct_reply(struct wins_packet_struct *p) break; if (i==partner_count) { - DEBUG(0,("construct_reply: got a request from a non peer machine: %s\n", peer)); + 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); @@ -857,7 +858,7 @@ void construct_reply(struct wins_packet_struct *p) if (switch_message(p->packet, &r)) { encode_generic_packet(&buffer, &r); - DEBUG(0,("dump: sending packet\n")); + DEBUG(5,("dump: sending packet\n")); dump_generic_packet(&r); if(buffer.offset > 0) { @@ -868,8 +869,10 @@ void construct_reply(struct wins_packet_struct *p) /* 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) + r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC) { + remove_partner(p->packet->header.assoc_ctx); p->stop_packet=True; + } } /**************************************************************************** @@ -929,6 +932,48 @@ void run_pull_replication(time_t t) 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/source3/wrepld/server.c b/source3/wrepld/server.c index d078a833ae..740003035c 100644 --- a/source3/wrepld/server.c +++ b/source3/wrepld/server.c @@ -263,7 +263,7 @@ static BOOL create_listen_fdset(void) set_socket_options(s,user_socket_options); if (listen(s, 5) == -1) { - DEBUG(0,("listen: %s\n",strerror(errno))); + DEBUG(5,("listen: %s\n",strerror(errno))); close(s); return False; } @@ -304,17 +304,49 @@ static struct wins_packet_struct *read_wins_packet(int fd, int timeout) { struct wins_packet_struct *p; GENERIC_PACKET *q; - char buf[4096]; + struct BUFFER inbuf; + ssize_t len=0; + size_t total=0; + ssize_t ret; + BOOL ok = False; - if (!receive_smb(fd, buf, timeout)) + 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(buf, q); + decode_generic_packet(&inbuf, q); q->fd=fd; @@ -403,7 +435,10 @@ static BOOL listen_for_wins_packets(void) /* 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"); |