summaryrefslogtreecommitdiff
path: root/source3/wrepld
diff options
context:
space:
mode:
Diffstat (limited to 'source3/wrepld')
-rw-r--r--source3/wrepld/parser.c243
-rw-r--r--source3/wrepld/partners.c20
-rw-r--r--source3/wrepld/process.c119
-rw-r--r--source3/wrepld/server.c45
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");