Line data Source code
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-1998
7 :
8 : SMB Version handling
9 : Copyright (C) John H Terpstra 1995-1998
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 :
24 : */
25 :
26 : #include "includes.h"
27 : #include "../librpc/gen_ndr/svcctl.h"
28 : #include "nmbd/nmbd.h"
29 : #include "lib/util/string_wrappers.h"
30 :
31 : extern int updatecount;
32 : extern bool found_lm_clients;
33 :
34 : /****************************************************************************
35 : Send a browser reset packet.
36 : **************************************************************************/
37 :
38 0 : void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip)
39 : {
40 : char outbuf[1024];
41 : char *p;
42 :
43 0 : DBG_NOTICE("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
44 : reset_type, to_name, to_type, inet_ntoa(to_ip) );
45 :
46 0 : memset(outbuf,'\0',sizeof(outbuf));
47 0 : p = outbuf;
48 0 : SCVAL(p,0,ANN_ResetBrowserState);
49 0 : p++;
50 0 : SCVAL(p,0,reset_type);
51 0 : p++;
52 :
53 0 : send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
54 : lp_netbios_name(), 0x0, to_name, to_type, to_ip,
55 0 : FIRST_SUBNET->myip, DGRAM_PORT);
56 0 : }
57 :
58 : /****************************************************************************
59 : Broadcast a packet to the local net requesting that all servers in this
60 : workgroup announce themselves to us.
61 : **************************************************************************/
62 :
63 29 : void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work)
64 : {
65 : char outbuf[1024];
66 : char *p;
67 :
68 29 : work->needannounce = True;
69 :
70 29 : DBG_NOTICE("broadcast_announce_request: sending announce request for workgroup %s \
71 : to subnet %s\n", work->work_group, subrec->subnet_name);
72 :
73 29 : memset(outbuf,'\0',sizeof(outbuf));
74 29 : p = outbuf;
75 29 : SCVAL(p,0,ANN_AnnouncementRequest);
76 29 : p++;
77 :
78 29 : SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
79 29 : p++;
80 29 : p += push_string_check(p+1, lp_netbios_name(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
81 :
82 29 : send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
83 29 : lp_netbios_name(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
84 : subrec->myip, DGRAM_PORT);
85 29 : }
86 :
87 : /****************************************************************************
88 : Broadcast an announcement.
89 : **************************************************************************/
90 :
91 399 : static void send_announcement(struct subnet_record *subrec, int announce_type,
92 : const char *from_name, const char *to_name, int to_type, struct in_addr to_ip,
93 : time_t announce_interval,
94 : const char *server_name, int server_type, const char *server_comment)
95 : {
96 : char outbuf[1024];
97 : unstring upper_server_name;
98 : char *p;
99 :
100 399 : memset(outbuf,'\0',sizeof(outbuf));
101 399 : p = outbuf+1;
102 :
103 399 : SCVAL(outbuf,0,announce_type);
104 :
105 : /* Announcement parameters. */
106 399 : SCVAL(p,0,updatecount);
107 399 : SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
108 :
109 399 : strlcpy(upper_server_name, server_name ? server_name : "", sizeof(upper_server_name));
110 399 : if (!strupper_m(upper_server_name)) {
111 0 : DBG_WARNING("strupper_m %s failed\n", upper_server_name);
112 0 : return;
113 : }
114 399 : push_string_check(p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE);
115 :
116 399 : SCVAL(p,21,SAMBA_MAJOR_NBT_ANNOUNCE_VERSION); /* Major version. */
117 399 : SCVAL(p,22,SAMBA_MINOR_NBT_ANNOUNCE_VERSION); /* Minor version. */
118 :
119 399 : SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
120 : /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
121 399 : SSVAL(p,27,BROWSER_ELECTION_VERSION);
122 399 : SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
123 :
124 399 : p += 31 + push_string_check(p+31, server_comment, sizeof(outbuf) - (p + 31 - outbuf), STR_ASCII|STR_TERMINATE);
125 :
126 399 : send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
127 : from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
128 : DGRAM_PORT);
129 : }
130 :
131 : /****************************************************************************
132 : Broadcast a LanMan announcement.
133 : **************************************************************************/
134 :
135 0 : static void send_lm_announcement(struct subnet_record *subrec, int announce_type,
136 : char *from_name, char *to_name, int to_type, struct in_addr to_ip,
137 : time_t announce_interval,
138 : char *server_name, int server_type, char *server_comment)
139 : {
140 : char outbuf[1024];
141 0 : char *p=outbuf;
142 :
143 0 : memset(outbuf,'\0',sizeof(outbuf));
144 :
145 0 : SSVAL(p,0,announce_type);
146 0 : SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
147 0 : SCVAL(p,6,SAMBA_MAJOR_NBT_ANNOUNCE_VERSION); /* Major version. */
148 0 : SCVAL(p,7,SAMBA_MINOR_NBT_ANNOUNCE_VERSION); /* Minor version. */
149 0 : SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
150 :
151 0 : p += 10;
152 0 : p += push_string_check(p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
153 0 : p += push_string_check(p, server_comment, sizeof(outbuf)- (p - outbuf), STR_ASCII|STR_UPPER|STR_TERMINATE);
154 :
155 0 : send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
156 : from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
157 : DGRAM_PORT);
158 0 : }
159 :
160 : /****************************************************************************
161 : We are a local master browser. Announce this to WORKGROUP<1e>.
162 : ****************************************************************************/
163 :
164 141 : static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work,
165 : struct server_record *servrec)
166 : {
167 : /* Ensure we don't have the prohibited bit set. */
168 141 : uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
169 :
170 141 : DBG_NOTICE("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
171 : type, lp_netbios_name(), subrec->subnet_name, work->work_group);
172 :
173 141 : send_announcement(subrec, ANN_LocalMasterAnnouncement,
174 : lp_netbios_name(), /* From nbt name. */
175 141 : work->work_group, 0x1e, /* To nbt name. */
176 : subrec->bcast_ip, /* To ip. */
177 141 : work->announce_interval, /* Time until next announce. */
178 : lp_netbios_name(), /* Name to announce. */
179 : type, /* Type field. */
180 141 : servrec->serv.comment);
181 141 : }
182 :
183 : /****************************************************************************
184 : Announce the workgroup WORKGROUP to MSBROWSE<01>.
185 : ****************************************************************************/
186 :
187 110 : static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work)
188 : {
189 110 : DBG_NOTICE("send_workgroup_announcement: on subnet %s for workgroup %s\n",
190 : subrec->subnet_name, work->work_group);
191 :
192 220 : send_announcement(subrec, ANN_DomainAnnouncement,
193 : lp_netbios_name(), /* From nbt name. */
194 : MSBROWSE, 0x1, /* To nbt name. */
195 : subrec->bcast_ip, /* To ip. */
196 110 : work->announce_interval, /* Time until next announce. */
197 110 : work->work_group, /* Name to announce. */
198 : SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
199 : lp_netbios_name()); /* From name as comment. */
200 110 : }
201 :
202 : /****************************************************************************
203 : Announce the given host to WORKGROUP<1d>.
204 : ****************************************************************************/
205 :
206 148 : static void send_host_announcement(struct subnet_record *subrec, struct work_record *work,
207 : struct server_record *servrec)
208 : {
209 : /* Ensure we don't have the prohibited bits set. */
210 148 : uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
211 :
212 148 : DBG_NOTICE("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
213 : type, servrec->serv.name, subrec->subnet_name, work->work_group);
214 :
215 148 : send_announcement(subrec, ANN_HostAnnouncement,
216 148 : servrec->serv.name, /* From nbt name. */
217 148 : work->work_group, 0x1d, /* To nbt name. */
218 : subrec->bcast_ip, /* To ip. */
219 148 : work->announce_interval, /* Time until next announce. */
220 148 : servrec->serv.name, /* Name to announce. */
221 : type, /* Type field. */
222 148 : servrec->serv.comment);
223 148 : }
224 :
225 : /****************************************************************************
226 : Announce the given LanMan host
227 : ****************************************************************************/
228 :
229 0 : static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work,
230 : struct server_record *servrec, int lm_interval)
231 : {
232 : /* Ensure we don't have the prohibited bits set. */
233 0 : uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
234 :
235 0 : DBG_NOTICE("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
236 : type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval);
237 :
238 0 : send_lm_announcement(subrec, ANN_HostAnnouncement,
239 0 : servrec->serv.name, /* From nbt name. */
240 0 : work->work_group, 0x00, /* To nbt name. */
241 : subrec->bcast_ip, /* To ip. */
242 : lm_interval, /* Time until next announce. */
243 0 : servrec->serv.name, /* Name to announce (fstring not netbios name struct). */
244 : type, /* Type field. */
245 0 : servrec->serv.comment);
246 0 : }
247 :
248 : /****************************************************************************
249 : Announce a server record.
250 : ****************************************************************************/
251 :
252 211 : static void announce_server(struct subnet_record *subrec, struct work_record *work,
253 : struct server_record *servrec)
254 : {
255 : /* Only do domain announcements if we are a master and it's
256 : our primary name we're being asked to announce. */
257 :
258 211 : if (AM_LOCAL_MASTER_BROWSER(work) && strequal(lp_netbios_name(),servrec->serv.name)) {
259 110 : send_local_master_announcement(subrec, work, servrec);
260 110 : send_workgroup_announcement(subrec, work);
261 : } else {
262 101 : send_host_announcement(subrec, work, servrec);
263 : }
264 211 : }
265 :
266 : /****************************************************************************
267 : Go through all my registered names on all broadcast subnets and announce
268 : them if the timeout requires it.
269 : **************************************************************************/
270 :
271 17145 : void announce_my_server_names(time_t t)
272 : {
273 : struct subnet_record *subrec;
274 :
275 34290 : for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
276 17145 : struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
277 :
278 17145 : if(work) {
279 : struct server_record *servrec;
280 :
281 17145 : if (work->needannounce) {
282 : /* Drop back to a max 3 minute announce. This is to prevent a
283 : single lost packet from breaking things for too long. */
284 :
285 79 : work->announce_interval = MIN(work->announce_interval,
286 : CHECK_TIME_MIN_HOST_ANNCE*60);
287 79 : work->lastannounce_time = t - (work->announce_interval+1);
288 79 : work->needannounce = False;
289 : }
290 :
291 : /* Announce every minute at first then progress to every 12 mins */
292 17145 : if (t >= work->lastannounce_time &&
293 17145 : (t - work->lastannounce_time) < work->announce_interval) {
294 16950 : continue;
295 : }
296 :
297 195 : if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
298 195 : work->announce_interval += 60;
299 :
300 195 : work->lastannounce_time = t;
301 :
302 477 : for (servrec = work->serverlist; servrec; servrec = servrec->next) {
303 282 : if (is_myname(servrec->serv.name))
304 211 : announce_server(subrec, work, servrec);
305 : }
306 : } /* if work */
307 : } /* for subrec */
308 17145 : }
309 :
310 : /****************************************************************************
311 : Go through all my registered names on all broadcast subnets and announce
312 : them as a LanMan server if the timeout requires it.
313 : **************************************************************************/
314 :
315 17145 : void announce_my_lm_server_names(time_t t)
316 : {
317 : struct subnet_record *subrec;
318 : static time_t last_lm_announce_time=0;
319 17145 : int announce_interval = lp_lm_interval();
320 17145 : int lm_announce = lp_lm_announce();
321 :
322 17145 : if ((announce_interval <= 0) || (lm_announce <= 0)) {
323 : /* user absolutely does not want LM announcements to be sent. */
324 0 : return;
325 : }
326 :
327 17145 : if ((lm_announce >= 2) && (!found_lm_clients)) {
328 : /* has been set to 2 (Auto) but no LM clients detected (yet). */
329 17145 : return;
330 : }
331 :
332 : /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
333 : been detected. */
334 :
335 0 : for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
336 0 : struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
337 :
338 0 : if(work) {
339 : struct server_record *servrec;
340 :
341 0 : if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
342 0 : continue;
343 :
344 0 : last_lm_announce_time = t;
345 :
346 0 : for (servrec = work->serverlist; servrec; servrec = servrec->next) {
347 0 : if (is_myname(servrec->serv.name))
348 : /* skipping equivalent of announce_server() */
349 0 : send_lm_host_announcement(subrec, work, servrec, announce_interval);
350 : }
351 : } /* if work */
352 : } /* for subrec */
353 : }
354 :
355 : /* Announce timer. Moved into global static so it can be reset
356 : when a machine becomes a local master browser. */
357 : static time_t announce_timer_last=0;
358 :
359 : /****************************************************************************
360 : Reset the announce_timer so that a local master browser announce will be done
361 : immediately.
362 : ****************************************************************************/
363 :
364 29 : void reset_announce_timer(void)
365 : {
366 29 : announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
367 29 : }
368 :
369 : /****************************************************************************
370 : Announce myself as a local master browser to a domain master browser.
371 : **************************************************************************/
372 :
373 17145 : void announce_myself_to_domain_master_browser(time_t t)
374 : {
375 : struct subnet_record *subrec;
376 : struct work_record *work;
377 :
378 17145 : if(!we_are_a_wins_client()) {
379 17145 : DBG_DEBUG("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n");
380 17145 : return;
381 : }
382 :
383 0 : if (!announce_timer_last)
384 0 : announce_timer_last = t;
385 :
386 0 : if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60)) {
387 0 : DBG_DEBUG("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
388 : (int)t, (int)announce_timer_last,
389 : CHECK_TIME_MST_ANNOUNCE * 60 );
390 0 : return;
391 : }
392 :
393 0 : announce_timer_last = t;
394 :
395 : /* Look over all our broadcast subnets to see if any of them
396 : has the state set as local master browser. */
397 :
398 0 : for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
399 0 : for (work = subrec->workgrouplist; work; work = work->next) {
400 0 : if (AM_LOCAL_MASTER_BROWSER(work)) {
401 0 : DBG_NOTICE( "announce_myself_to_domain_master_browser: I am a local master browser for \
402 : workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name);
403 :
404 : /* Look in nmbd_browsersync.c for the rest of this code. */
405 0 : announce_and_sync_with_domain_master_browser(subrec, work);
406 : }
407 : }
408 : }
409 : }
410 :
411 : /****************************************************************************
412 : Announce all samba's server entries as 'gone'.
413 : This must *only* be called on shutdown.
414 : ****************************************************************************/
415 :
416 43 : void announce_my_servers_removed(void)
417 : {
418 43 : int announce_interval = lp_lm_interval();
419 43 : int lm_announce = lp_lm_announce();
420 : struct subnet_record *subrec;
421 :
422 86 : for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
423 : struct work_record *work;
424 138 : for (work = subrec->workgrouplist; work; work = work->next) {
425 : struct server_record *servrec;
426 :
427 95 : work->announce_interval = 0;
428 158 : for (servrec = work->serverlist; servrec; servrec = servrec->next) {
429 63 : if (!is_myname(servrec->serv.name))
430 16 : continue;
431 47 : servrec->serv.type = 0;
432 47 : if(AM_LOCAL_MASTER_BROWSER(work))
433 31 : send_local_master_announcement(subrec, work, servrec);
434 47 : send_host_announcement(subrec, work, servrec);
435 :
436 47 : if ((announce_interval <= 0) || (lm_announce <= 0)) {
437 : /* user absolutely does not want LM announcements to be sent. */
438 0 : continue;
439 : }
440 :
441 47 : if ((lm_announce >= 2) && (!found_lm_clients)) {
442 : /* has been set to 2 (Auto) but no LM clients detected (yet). */
443 47 : continue;
444 : }
445 :
446 : /*
447 : * lm announce was set or we have seen lm announcements, so do
448 : * a lm announcement of host removed.
449 : */
450 :
451 0 : send_lm_host_announcement(subrec, work, servrec, 0);
452 : }
453 : }
454 : }
455 43 : }
456 :
457 : /****************************************************************************
458 : Do all the "remote" announcements. These are used to put ourselves
459 : on a remote browse list. They are done blind, no checking is done to
460 : see if there is actually a local master browser at the other end.
461 : **************************************************************************/
462 :
463 17145 : void announce_remote(time_t t)
464 : {
465 17145 : char *s = NULL;
466 : const char *ptr;
467 : static time_t last_time = 0;
468 : char *s2;
469 : struct in_addr addr;
470 : char *comment;
471 17145 : int stype = lp_default_server_announce();
472 17145 : TALLOC_CTX *frame = NULL;
473 : const struct loadparm_substitution *lp_sub =
474 17145 : loadparm_s3_global_substitution();
475 :
476 17145 : if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
477 17145 : return;
478 :
479 205 : last_time = t;
480 :
481 205 : s = lp_remote_announce(talloc_tos(), lp_sub);
482 205 : if (!*s)
483 205 : return;
484 :
485 0 : comment = string_truncate(lp_server_string(talloc_tos(), lp_sub),
486 : MAX_SERVER_STRING_LENGTH);
487 :
488 0 : frame = talloc_stackframe();
489 0 : for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) {
490 : /* The entries are of the form a.b.c.d/WORKGROUP with
491 : WORKGROUP being optional */
492 : const char *wgroup;
493 : char *pwgroup;
494 : int i;
495 :
496 0 : pwgroup = strchr_m(s2,'/');
497 0 : if (pwgroup)
498 0 : *pwgroup++ = 0;
499 0 : if (!pwgroup || !*pwgroup)
500 0 : wgroup = lp_workgroup();
501 : else
502 0 : wgroup = pwgroup;
503 :
504 0 : addr = interpret_addr2(s2);
505 :
506 : /* Announce all our names including aliases */
507 : /* Give the ip address as the address of our first
508 : broadcast subnet. */
509 :
510 0 : for(i=0; my_netbios_names(i); i++) {
511 0 : const char *name = my_netbios_names(i);
512 :
513 0 : DBG_INFO("announce_remote: Doing remote announce for server %s to IP %s.\n",
514 : name, inet_ntoa(addr) );
515 :
516 0 : send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
517 : name, /* From nbt name. */
518 : wgroup, 0x1d, /* To nbt name. */
519 : addr, /* To ip. */
520 : REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
521 : name, /* Name to announce. */
522 : stype, /* Type field. */
523 : comment);
524 : }
525 : }
526 0 : TALLOC_FREE(frame);
527 : }
528 :
529 : /****************************************************************************
530 : Implement the 'remote browse sync' feature Andrew added.
531 : These are used to put our browse lists into remote browse lists.
532 : **************************************************************************/
533 :
534 17145 : void browse_sync_remote(time_t t)
535 : {
536 : char *s;
537 : const char *ptr;
538 : static time_t last_time = 0;
539 : char *s2;
540 : struct in_addr addr;
541 : struct work_record *work;
542 : char outbuf[1024];
543 : char *p;
544 : unstring myname;
545 17145 : TALLOC_CTX *frame = NULL;
546 : const struct loadparm_substitution *lp_sub =
547 17145 : loadparm_s3_global_substitution();
548 :
549 17145 : if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
550 17145 : return;
551 :
552 205 : last_time = t;
553 :
554 205 : s = lp_remote_browse_sync(talloc_tos(), lp_sub);
555 205 : if (!*s)
556 205 : return;
557 :
558 : /*
559 : * We only do this if we are the local master browser
560 : * for our workgroup on the firsst subnet.
561 : */
562 :
563 0 : if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {
564 0 : DBG_WARNING("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
565 : lp_workgroup(), FIRST_SUBNET->subnet_name );
566 0 : return;
567 : }
568 :
569 0 : if(!AM_LOCAL_MASTER_BROWSER(work)) {
570 0 : DBG_NOTICE("browse_sync_remote: We can only do this if we are a local master browser \
571 : for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name );
572 0 : return;
573 : }
574 :
575 0 : memset(outbuf,'\0',sizeof(outbuf));
576 0 : p = outbuf;
577 0 : SCVAL(p,0,ANN_MasterAnnouncement);
578 0 : p++;
579 :
580 0 : unstrcpy(myname, lp_netbios_name());
581 0 : if (!strupper_m(myname)) {
582 0 : DBG_WARNING("strupper_m %s failed\n", myname);
583 0 : return;
584 : }
585 0 : myname[15]='\0';
586 0 : push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
587 :
588 0 : p = skip_string(outbuf,sizeof(outbuf),p);
589 :
590 0 : frame = talloc_stackframe();
591 0 : for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) {
592 : /* The entries are of the form a.b.c.d */
593 0 : addr = interpret_addr2(s2);
594 :
595 0 : DBG_INFO("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
596 : lp_netbios_name(), inet_ntoa(addr) );
597 :
598 0 : send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
599 0 : lp_netbios_name(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
600 : }
601 0 : TALLOC_FREE(frame);
602 : }
|