source: trunk/samba/source/nmbd/nmbd_browsesync.c @ 26

Last change on this file since 26 was 26, checked in by Paul Smedley, 14 years ago

Updated source to 3.0.25rc1

File size: 23.2 KB
Line 
1/*
2   Unix SMB/CIFS implementation.
3   NBT netbios routines and daemon - version 2
4   Copyright (C) Andrew Tridgell 1994-1998
5   Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6   Copyright (C) Jeremy Allison 1994-2003
7   
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12   
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17   
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21   
22*/
23
24#include "includes.h"
25
26/* This is our local master browser list database. */
27extern struct browse_cache_record *lmb_browserlist;
28
29/****************************************************************************
30As a domain master browser, do a sync with a local master browser.
31**************************************************************************/
32
33static void sync_with_lmb(struct browse_cache_record *browc)
34{                     
35        struct work_record *work;
36
37        if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) ) {
38                if( DEBUGLVL( 0 ) ) {
39                        dbgtext( "sync_with_lmb:\n" );
40                        dbgtext( "Failed to get a workgroup for a local master browser " );
41                        dbgtext( "cache entry workgroup " );
42                        dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
43                }
44                return;
45        }
46
47        /* We should only be doing this if we are a domain master browser for
48                the given workgroup. Ensure this is so. */
49
50        if(!AM_DOMAIN_MASTER_BROWSER(work)) {
51                if( DEBUGLVL( 0 ) ) {
52                        dbgtext( "sync_with_lmb:\n" );
53                        dbgtext( "We are trying to sync with a local master browser " );
54                        dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
55                        dbgtext( "and we are not a domain master browser on this workgroup.\n" );
56                        dbgtext( "Error!\n" );
57                }
58                return;
59        }
60
61        if( DEBUGLVL( 2 ) ) {
62                dbgtext( "sync_with_lmb:\n" );
63                dbgtext( "Initiating sync with local master browser " );
64                dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
65                dbgtext( "for workgroup %s\n", browc->work_group );
66        }
67
68        sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
69
70        browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
71}
72
73/****************************************************************************
74Sync or expire any local master browsers.
75**************************************************************************/
76
77void dmb_expire_and_sync_browser_lists(time_t t)
78{
79        static time_t last_run = 0;
80        struct browse_cache_record *browc;
81
82        /* Only do this every 20 seconds. */ 
83        if (t - last_run < 20) 
84                return;
85
86        last_run = t;
87
88        expire_lmb_browsers(t);
89
90        for( browc = lmb_browserlist; browc; browc = browc->next ) {
91                if (browc->sync_time < t)
92                        sync_with_lmb(browc);
93        }
94}
95
96/****************************************************************************
97As a local master browser, send an announce packet to the domain master browser.
98**************************************************************************/
99
100static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
101{
102        pstring outbuf;
103        unstring myname;
104        unstring dmb_name;
105        char *p;
106
107        if(ismyip(work->dmb_addr)) {
108                if( DEBUGLVL( 2 ) ) {
109                        dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
110                        dbgtext( "We are both a domain and a local master browser for " );
111                        dbgtext( "workgroup %s.  ", work->work_group );
112                        dbgtext( "Do not announce to ourselves.\n" );
113                }
114                return;
115        }
116
117        memset(outbuf,'\0',sizeof(outbuf));
118        p = outbuf;
119        SCVAL(p,0,ANN_MasterAnnouncement);
120        p++;
121
122        unstrcpy(myname, global_myname());
123        strupper_m(myname);
124        myname[15]='\0';
125        /* The call below does CH_UNIX -> CH_DOS conversion. JRA */
126        push_pstring_base(p, myname, outbuf);
127
128        p = skip_string(outbuf,sizeof(outbuf),p);
129
130        if( DEBUGLVL( 4 ) ) {
131                dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
132                dbgtext( "Sending local master announce to " );
133                dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
134                                        work->work_group );
135        }
136
137        /* Target name for send_mailslot must be in UNIX charset. */
138        pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
139        send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
140                global_myname(), 0x0, dmb_name, 0x0, 
141                work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
142}
143
144/****************************************************************************
145As a local master browser, do a sync with a domain master browser.
146**************************************************************************/
147
148static void sync_with_dmb(struct work_record *work)
149{
150        unstring dmb_name;
151
152        if( DEBUGLVL( 2 ) ) {
153                dbgtext( "sync_with_dmb:\n" );
154                dbgtext( "Initiating sync with domain master browser " );
155                dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
156                dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
157                dbgtext( "for workgroup %s\n", work->work_group );
158        }
159
160        pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
161        sync_browse_lists(work, dmb_name, work->dmb_name.name_type, 
162                work->dmb_addr, False, True);
163}
164
165/****************************************************************************
166  Function called when a node status query to a domain master browser IP succeeds.
167****************************************************************************/
168
169static void domain_master_node_status_success(struct subnet_record *subrec,
170                                              struct userdata_struct *userdata,
171                                              struct res_rec *answers,
172                                              struct in_addr from_ip)
173{
174        struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
175
176        if( work == NULL ) {
177                if( DEBUGLVL( 0 ) ) {
178                        dbgtext( "domain_master_node_status_success:\n" );
179                        dbgtext( "Unable to find workgroup " );
180                        dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
181                }
182                return;
183        }
184
185        if( DEBUGLVL( 3 ) ) {
186                dbgtext( "domain_master_node_status_success:\n" );
187                dbgtext( "Success in node status for workgroup " );
188                dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
189        }
190
191  /* Go through the list of names found at answers->rdata and look for
192     the first SERVER<0x20> name. */
193
194        if(answers->rdata != NULL) {
195                char *p = answers->rdata;
196                int numnames = CVAL(p, 0);
197
198                p += 1;
199
200                while (numnames--) {
201                        unstring qname;
202                        uint16 nb_flags;
203                        int name_type;
204
205                        pull_ascii_nstring(qname, sizeof(qname), p);
206                        name_type = CVAL(p,15);
207                        nb_flags = get_nb_flags(&p[16]);
208                        trim_char(qname,'\0',' ');
209
210                        p += 18;
211
212                        if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) {
213                                struct nmb_name nmbname;
214
215                                make_nmb_name(&nmbname, qname, name_type);
216
217                                /* Copy the dmb name and IP address
218                                        into the workgroup struct. */
219
220                                work->dmb_name = nmbname;
221                                putip((char *)&work->dmb_addr, &from_ip);
222
223                                /* Do the local master browser announcement to the domain
224                                        master browser name and IP. */
225                                announce_local_master_browser_to_domain_master_browser( work );
226
227                                /* Now synchronise lists with the domain master browser. */
228                                sync_with_dmb(work);
229                                break;
230                        }
231                }
232        } else if( DEBUGLVL( 0 ) ) {
233                dbgtext( "domain_master_node_status_success:\n" );
234                dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
235                dbgtext( "%s.\n", inet_ntoa(from_ip) );
236        }
237}
238
239/****************************************************************************
240  Function called when a node status query to a domain master browser IP fails.
241****************************************************************************/
242
243static void domain_master_node_status_fail(struct subnet_record *subrec,
244                       struct response_record *rrec)
245{
246        struct userdata_struct *userdata = rrec->userdata;
247
248        if( DEBUGLVL( 0 ) ) {
249                dbgtext( "domain_master_node_status_fail:\n" );
250                dbgtext( "Doing a node status request to the domain master browser\n" );
251                dbgtext( "for workgroup %s ", userdata ? userdata->data : "NULL" );
252                dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
253                dbgtext( "Cannot sync browser lists.\n" );
254        }
255}
256
257/****************************************************************************
258  Function called when a query for a WORKGROUP<1b> name succeeds.
259****************************************************************************/
260
261static void find_domain_master_name_query_success(struct subnet_record *subrec,
262                        struct userdata_struct *userdata_in,
263                        struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
264{
265        /*
266         * Unfortunately, finding the IP address of the Domain Master Browser,
267         * as we have here, is not enough. We need to now do a sync to the
268         * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
269         * respond to the SMBSERVER name. To get this name from IP
270         * address we do a Node status request, and look for the first
271         * NAME<0x20> in the response, and take that as the server name.
272         * We also keep a cache of the Domain Master Browser name for this
273         * workgroup in the Workgroup struct, so that if the same IP addess
274         * is returned every time, we don't need to do the node status
275         * request.
276         */
277
278        struct work_record *work;
279        struct nmb_name nmbname;
280        struct userdata_struct *userdata;
281        size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
282        unstring qname;
283
284        pull_ascii_nstring(qname, sizeof(qname), q_name->name);
285        if( !(work = find_workgroup_on_subnet(subrec, qname)) ) {
286                if( DEBUGLVL( 0 ) ) {
287                        dbgtext( "find_domain_master_name_query_success:\n" );
288                        dbgtext( "Failed to find workgroup %s\n", qname);
289                }
290        return;
291  }
292
293  /* First check if we already have a dmb for this workgroup. */
294
295        if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
296                /* Do the local master browser announcement to the domain
297                        master browser name and IP. */
298                announce_local_master_browser_to_domain_master_browser( work );
299
300                /* Now synchronise lists with the domain master browser. */
301                sync_with_dmb(work);
302                return;
303        } else {
304                zero_ip(&work->dmb_addr);
305        }
306
307        /* Now initiate the node status request. */
308
309        /* We used to use the name "*",0x0 here, but some Windows
310         * servers don't answer that name. However we *know* they
311         * have the name workgroup#1b (as we just looked it up).
312         * So do the node status request on this name instead.
313         * Found at LBL labs. JRA.
314         */
315
316        make_nmb_name(&nmbname,work->work_group,0x1b);
317
318        /* Put the workgroup name into the userdata so we know
319         what workgroup we're talking to when the reply comes
320         back. */
321
322        /* Setup the userdata_struct - this is copied so we can use
323        a stack variable for this. */
324
325        if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) {
326                DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
327                return;
328        }
329
330        userdata->copy_fn = NULL;
331        userdata->free_fn = NULL;
332        userdata->userdata_len = strlen(work->work_group)+1;
333        overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
334
335        node_status( subrec, &nmbname, answer_ip, 
336                domain_master_node_status_success,
337                domain_master_node_status_fail,
338                userdata);
339
340        zero_free(userdata, size);
341}
342
343/****************************************************************************
344  Function called when a query for a WORKGROUP<1b> name fails.
345  ****************************************************************************/
346
347static void find_domain_master_name_query_fail(struct subnet_record *subrec,
348                                    struct response_record *rrec,
349                                    struct nmb_name *question_name, int fail_code)
350{
351        if( DEBUGLVL( 0 ) ) {
352                dbgtext( "find_domain_master_name_query_fail:\n" );
353                dbgtext( "Unable to find the Domain Master Browser name " );
354                dbgtext( "%s for the workgroup %s.\n",
355                        nmb_namestr(question_name), question_name->name );
356                dbgtext( "Unable to sync browse lists in this workgroup.\n" );
357        }
358}
359
360/****************************************************************************
361As a local master browser for a workgroup find the domain master browser
362name, announce ourselves as local master browser to it and then pull the
363full domain browse lists from it onto the given subnet.
364**************************************************************************/
365
366void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
367                                                   struct work_record *work)
368{
369        /* Only do this if we are using a WINS server. */
370        if(we_are_a_wins_client() == False) {
371                if( DEBUGLVL( 10 ) ) {
372                        dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
373                        dbgtext( "Ignoring, as we are not a WINS client.\n" );
374                }
375                return;
376        }
377
378        /* First, query for the WORKGROUP<1b> name from the WINS server. */
379        query_name(unicast_subnet, work->work_group, 0x1b,
380             find_domain_master_name_query_success,
381             find_domain_master_name_query_fail,
382             NULL);
383}
384
385/****************************************************************************
386  Function called when a node status query to a domain master browser IP succeeds.
387  This function is only called on query to a Samba 1.9.18 or above WINS server.
388
389  Note that adding the workgroup name is enough for this workgroup to be
390  browsable by clients, as clients query the WINS server or broadcast
391  nets for the WORKGROUP<1b> name when they want to browse a workgroup
392  they are not in. We do not need to do a sync with this Domain Master
393  Browser in order for our browse clients to see machines in this workgroup.
394  JRA.
395****************************************************************************/
396
397static void get_domain_master_name_node_status_success(struct subnet_record *subrec,
398                                              struct userdata_struct *userdata,
399                                              struct res_rec *answers,
400                                              struct in_addr from_ip)
401{
402        struct work_record *work;
403        unstring server_name;
404
405        server_name[0] = 0;
406
407        if( DEBUGLVL( 3 ) ) {
408                dbgtext( "get_domain_master_name_node_status_success:\n" );
409                dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
410        }
411
412        /*
413         * Go through the list of names found at answers->rdata and look for
414         * the first WORKGROUP<0x1b> name.
415         */
416
417        if(answers->rdata != NULL) {
418                char *p = answers->rdata;
419                int numnames = CVAL(p, 0);
420
421                p += 1;
422
423                while (numnames--) {
424                        unstring qname;
425                        uint16 nb_flags;
426                        int name_type;
427
428                        pull_ascii_nstring(qname, sizeof(qname), p);
429                        name_type = CVAL(p,15);
430                        nb_flags = get_nb_flags(&p[16]);
431                        trim_char(qname,'\0',' ');
432
433                        p += 18;
434
435                        if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && 
436                                        server_name[0] == 0) {
437                                /* this is almost certainly the server netbios name */
438                                unstrcpy(server_name, qname);
439                                continue;
440                        }
441
442                        if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) {
443                                if( DEBUGLVL( 5 ) ) {
444                                        dbgtext( "get_domain_master_name_node_status_success:\n" );
445                                        dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
446                                        dbgtext( "is a domain master browser for workgroup " );
447                                        dbgtext( "%s. Adding this name.\n", qname );
448                                }
449
450                                /*
451                                 * If we don't already know about this workgroup, add it
452                                 * to the workgroup list on the unicast_subnet.
453                                 */
454
455                                if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) {
456                                        struct nmb_name nmbname;
457                                        /*
458                                         * Add it - with an hour in the cache.
459                                         */
460                                        if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
461                                                return;
462
463                                        /* remember who the master is */
464                                        unstrcpy(work->local_master_browser_name, server_name);
465                                        make_nmb_name(&nmbname, server_name, 0x20);
466                                        work->dmb_name = nmbname;
467                                        work->dmb_addr = from_ip;
468                                }
469                                break;
470                        }
471                }
472        } else if( DEBUGLVL( 0 ) ) {
473                dbgtext( "get_domain_master_name_node_status_success:\n" );
474                dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
475                dbgtext( "%s.\n", inet_ntoa(from_ip) );
476        }
477}
478
479/****************************************************************************
480  Function called when a node status query to a domain master browser IP fails.
481****************************************************************************/
482
483static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
484                       struct response_record *rrec)
485{
486        if( DEBUGLVL( 0 ) ) {
487                dbgtext( "get_domain_master_name_node_status_fail:\n" );
488                dbgtext( "Doing a node status request to the domain master browser " );
489                dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
490                dbgtext( "Cannot get workgroup name.\n" );
491        }
492}
493
494/****************************************************************************
495  Function called when a query for *<1b> name succeeds.
496****************************************************************************/
497
498static void find_all_domain_master_names_query_success(struct subnet_record *subrec,
499                        struct userdata_struct *userdata_in,
500                        struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
501{
502        /*
503         * We now have a list of all the domain master browsers for all workgroups
504         * that have registered with the WINS server. Now do a node status request
505         * to each one and look for the first 1b name in the reply. This will be
506         * the workgroup name that we will add to the unicast subnet as a 'non-local'
507         * workgroup.
508         */
509
510        struct nmb_name nmbname;
511        struct in_addr send_ip;
512        int i;
513
514        if( DEBUGLVL( 5 ) ) {
515                dbgtext( "find_all_domain_master_names_query_succes:\n" );
516                dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
517                dbgtext( "IP addresses for Domain Master Browsers.\n" );
518        }
519
520        for(i = 0; i < rrec->rdlength / 6; i++) {
521                /* Initiate the node status requests. */
522                make_nmb_name(&nmbname, "*", 0);
523
524                putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
525
526                /*
527                 * Don't send node status requests to ourself.
528                 */
529
530                if(ismyip( send_ip )) {
531                        if( DEBUGLVL( 5 ) ) {
532                                dbgtext( "find_all_domain_master_names_query_succes:\n" );
533                                dbgtext( "Not sending node status to our own IP " );
534                                dbgtext( "%s.\n", inet_ntoa(send_ip) );
535                        }
536                        continue;
537                }
538
539                if( DEBUGLVL( 5 ) ) {
540                        dbgtext( "find_all_domain_master_names_query_success:\n" );
541                        dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
542                }
543
544                node_status( subrec, &nmbname, send_ip, 
545                                get_domain_master_name_node_status_success,
546                                get_domain_master_name_node_status_fail,
547                                NULL);
548        }
549}
550
551/****************************************************************************
552  Function called when a query for *<1b> name fails.
553  ****************************************************************************/
554static void find_all_domain_master_names_query_fail(struct subnet_record *subrec,
555                                    struct response_record *rrec,
556                                    struct nmb_name *question_name, int fail_code)
557{
558        if( DEBUGLVL( 10 ) ) {
559                dbgtext( "find_domain_master_name_query_fail:\n" );
560                dbgtext( "WINS server did not reply to a query for name " );
561                dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
562                dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
563        }
564}
565
566/****************************************************************************
567 If we are a domain master browser on the unicast subnet, do a query to the
568 WINS server for the *<1b> name. This will only work to a Samba WINS server,
569 so ignore it if we fail. If we succeed, contact each of the IP addresses in
570 turn and do a node status request to them. If this succeeds then look for a
571 <1b> name in the reply - this is the workgroup name. Add this to the unicast
572 subnet. This is expensive, so we only do this every 15 minutes.
573**************************************************************************/
574
575void collect_all_workgroup_names_from_wins_server(time_t t)
576{
577        static time_t lastrun = 0;
578        struct work_record *work;
579
580        /* Only do this if we are using a WINS server. */
581        if(we_are_a_wins_client() == False)
582                return;
583
584        /* Check to see if we are a domain master browser on the unicast subnet. */
585        if((work = find_workgroup_on_subnet( unicast_subnet, lp_workgroup())) == NULL) {
586                if( DEBUGLVL( 0 ) ) {
587                        dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
588                        dbgtext( "Cannot find my workgroup %s ", lp_workgroup() );
589                        dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
590                }
591                return;
592        }
593
594        if(!AM_DOMAIN_MASTER_BROWSER(work))
595                return;
596
597        if ((lastrun != 0) && (t < lastrun + (15 * 60)))
598                return;
599     
600        lastrun = t;
601
602        /* First, query for the *<1b> name from the WINS server. */
603        query_name(unicast_subnet, "*", 0x1b,
604                find_all_domain_master_names_query_success,
605                find_all_domain_master_names_query_fail,
606                NULL);
607} 
608
609
610/****************************************************************************
611 If we are a domain master browser on the unicast subnet, do a regular sync
612 with all other DMBs that we know of on that subnet.
613
614To prevent exponential network traffic with large numbers of workgroups
615we use a randomised system where sync probability is inversely proportional
616to the number of known workgroups
617**************************************************************************/
618
619void sync_all_dmbs(time_t t)
620{
621        static time_t lastrun = 0;
622        struct work_record *work;
623        int count=0;
624
625        /* Only do this if we are using a WINS server. */
626        if(we_are_a_wins_client() == False)
627                return;
628
629        /* Check to see if we are a domain master browser on the
630           unicast subnet. */
631        work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup());
632        if (!work)
633                return;
634
635        if (!AM_DOMAIN_MASTER_BROWSER(work))
636                return;
637
638        if ((lastrun != 0) && (t < lastrun + (5 * 60)))
639                return;
640     
641        /* count how many syncs we might need to do */
642        for (work=unicast_subnet->workgrouplist; work; work = work->next) {
643                if (strcmp(lp_workgroup(), work->work_group)) {
644                        count++;
645                }
646        }
647
648        /* sync with a probability of 1/count */
649        for (work=unicast_subnet->workgrouplist; work; work = work->next) {
650                if (strcmp(lp_workgroup(), work->work_group)) {
651                        unstring dmb_name;
652
653                        if (((unsigned)sys_random()) % count != 0)
654                                continue;
655
656                        lastrun = t;
657
658                        if (!work->dmb_name.name[0]) {
659                                /* we don't know the DMB - assume it is
660                                   the same as the unicast local master */
661                                make_nmb_name(&work->dmb_name, 
662                                              work->local_master_browser_name,
663                                              0x20);
664                        }
665
666                        pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
667
668                        DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
669                                 dmb_name, inet_ntoa(work->dmb_addr)));
670
671                        sync_browse_lists(work, 
672                                          dmb_name,
673                                          work->dmb_name.name_type, 
674                                          work->dmb_addr, False, False);
675                }
676        }
677}
Note: See TracBrowser for help on using the repository browser.