2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
31 extern int ClientDGRAM;
33 #define TEST_CODE /* want to debug unknown browse packets */
35 extern int DEBUGLEVEL;
37 extern BOOL CanRecurse;
39 extern pstring myname;
42 extern int ClientDGRAM;
44 extern struct in_addr ipzero;
46 extern int workgroup_count; /* total number of workgroups we know about */
48 /* this is our domain/workgroup/server database */
49 extern struct subnet_record *subnetlist;
51 /* machine comment for host announcements */
52 extern pstring ServerComment;
54 extern int updatecount;
56 /* what server type are we currently */
57 #define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
58 SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
59 SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
61 /* backup request types: which servers are to be included */
62 #define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
63 #define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
65 extern time_t StartupTime;
67 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
70 /****************************************************************************
71 tell a server to become a backup browser
72 state - 0x01 become backup instead of master
73 - 0x02 remove all entries in browse list and become non-master
74 - 0x04 stop master browser service altogether. NT ignores this
75 **************************************************************************/
76 void reset_server(char *name, int state, struct in_addr ip)
81 bzero(outbuf,sizeof(outbuf));
84 CVAL(p,0) = ANN_ResetBrowserState;
88 DEBUG(2,("sending reset to %s %s of state %d\n",
89 name,inet_ntoa(ip),state));
91 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
92 myname,name,0x20,0x1d,ip,*iface_ip(ip));
96 /****************************************************************************
97 tell a server to become a backup browser
98 **************************************************************************/
99 void tell_become_backup(void)
101 /* XXXX note: this function is currently unsuitable for use, as it
102 does not properly check that a server is in a fit state to become
103 a backup browser before asking it to be one.
106 struct subnet_record *d;
107 for (d = subnetlist; d; d = d->next)
109 struct work_record *work;
110 for (work = d->workgrouplist; work; work = work->next)
112 struct server_record *s;
116 for (s = work->serverlist; s; s = s->next)
118 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
122 if (strequal(myname, s->serv.name)) continue;
124 if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
129 if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
131 if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
133 DEBUG(3,("num servers: %d num backups: %d\n",
134 num_servers, num_backups));
136 /* make first server a backup server. thereafter make every
137 tenth server a backup server */
138 if (num_backups != 0 && (num_servers+9) / num_backups > 10)
143 DEBUG(2,("sending become backup to %s %s for %s\n",
144 s->serv.name, inet_ntoa(d->bcast_ip),
147 /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
148 do_announce_request(s->serv.name, work->work_group,
149 ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
156 /*******************************************************************
157 same context: scope. should check name_type as well, and makes sure
158 we don't process messages from ourselves
159 ******************************************************************/
160 BOOL same_context(struct dgram_packet *dgram)
162 if (!strequal(dgram->dest_name .scope,scope )) return(True);
163 if ( strequal(dgram->source_name.name ,myname)) return(True);
169 /*******************************************************************
170 am I listening on a name. XXXX check the type of name as well.
171 ******************************************************************/
172 BOOL listening_name(struct work_record *work, struct nmb_name *n)
174 if (strequal(n->name,myname) ||
175 strequal(n->name,work->work_group) ||
176 strequal(n->name,MSBROWSE))
185 /*******************************************************************
186 process a domain announcement frame
188 Announce frames come in 3 types. Servers send host announcements
189 (command=1) to let the master browswer know they are
190 available. Master browsers send local master announcements
191 (command=15) to let other masters and backups that they are the
192 master. They also send domain announcements (command=12) to register
195 The comment field of domain announcements contains the master
196 browser name. The servertype is used by NetServerEnum to select
197 resources. We just have to pass it to smbd (via browser.dat) and let
198 the client choose using bit masks.
199 ******************************************************************/
200 static void process_announce(struct packet_struct *p,int command,char *buf)
202 struct dgram_packet *dgram = &p->packet.dgram;
203 struct in_addr ip = dgram->header.source_ip;
204 struct subnet_record *d = find_subnet(ip);
205 int update_count = CVAL(buf,0);
206 int ttl = IVAL(buf,1)/1000;
208 int osmajor=CVAL(buf,21);
209 int osminor=CVAL(buf,22);
210 uint32 servertype = IVAL(buf,23);
211 char *comment = buf+31;
212 struct work_record *work;
214 char *serv_name = dgram->source_name.name;
219 DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
220 DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
221 namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
222 servertype,comment));
226 if (dgram->dest_name.name_type == 0 && command == ANN_HostAnnouncement)
228 DEBUG(2,("Announce to nametype(0) not supported yet\n"));
232 if (command == ANN_DomainAnnouncement &&
233 ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
234 dgram->dest_name.name_type != 0x1))
236 DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
237 command, inet_ntoa(ip), namestr(&dgram->dest_name)));
241 if (same_context(dgram)) return;
243 if (command == ANN_DomainAnnouncement) {
244 /* XXXX if we are a master browser for the workgroup work_name,
245 then there is a local subnet configuration problem. only
246 we should be sending out such domain announcements, because
247 as the master browser, that is our job.
249 stop being a master browser, and force an election. this will
250 sort out the network problem. hopefully.
255 work_name = dgram->dest_name.name;
258 /* we need some way of finding out about new workgroups
259 that appear to be sending packets to us. The name_type checks make
260 sure we don't add host names as workgroups */
261 if (command == ANN_HostAnnouncement &&
262 (dgram->dest_name.name_type == 0x1d ||
263 dgram->dest_name.name_type == 0x1e))
266 if (!(work = find_workgroupstruct(d, work_name,add)))
269 DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
273 /* add them to our browse list */
274 add_server_entry(d,work,name,servertype,ttl,comment,True);
277 /* the tell become backup code is broken, no great harm is done by
279 tell_become_backup();
282 /* XXXX over-kill: i don't think we should really be doing this,
283 but it doesn't do much harm other than to add extra network
284 traffic. to be more precise, we should (possibly) only
285 sync browse lists with a host that sends an
286 ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement.
290 /* get their browse list from them and add it to ours. */
291 add_browser_entry(serv_name,dgram->dest_name.name_type,
292 work->work_group,30,ip);
295 /*******************************************************************
296 process a master announcement frame
297 ******************************************************************/
298 static void process_master_announce(struct packet_struct *p,char *buf)
300 struct dgram_packet *dgram = &p->packet.dgram;
301 struct in_addr ip = dgram->header.source_ip;
302 struct subnet_record *d = find_subnet(ip);
303 struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
305 struct work_record *work;
308 DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
310 if (same_context(dgram)) return;
312 if (!d || !mydomain) return;
314 if (!lp_domain_master()) return;
316 for (work = mydomain->workgrouplist; work; work = work->next)
320 /* merge browse lists with them */
321 add_browser_entry(name,0x1b, work->work_group,30,ip);
326 /*******************************************************************
327 process a receive backup list request
329 we receive a list of servers, and we attempt to locate them all on
330 our local subnet, and sync browse lists with them on the workgroup
331 they are said to be in.
333 XXXX NOTE: this function is in overdrive. it should not really do
334 half of what it actually does (it should pick _one_ name from the
335 list received and sync with it at regular intervals, rather than
336 sync with them all only once!)
338 ******************************************************************/
339 static void process_rcv_backup_list(struct packet_struct *p,char *buf)
341 struct dgram_packet *dgram = &p->packet.dgram;
342 struct in_addr ip = dgram->header.source_ip;
343 int count = CVAL(buf,0);
344 int Index = IVAL(buf,1); /* caller's index representing workgroup */
347 DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
348 namestr(&dgram->dest_name), inet_ntoa(ip),
351 if (same_context(dgram)) return;
353 if (count <= 0) return;
355 /* go through the list of servers attempting to sync browse lists */
356 for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
358 struct in_addr back_ip;
359 struct subnet_record *d;
361 DEBUG(4,("Searching for backup browser %s at %s...\n",
362 buf1, inet_ntoa(ip)));
364 /* XXXX assume name is a DNS name NOT a netbios name. a more complete
365 approach is to use reply_name_query functionality to find the name */
366 back_ip = *interpret_addr2(buf1);
368 if (zero_ip(back_ip))
370 DEBUG(4,("Failed to find backup browser server using DNS\n"));
374 DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
376 if ((d = find_subnet(back_ip)))
378 struct subnet_record *d1;
379 for (d1 = subnetlist; d1; d1 = d1->next)
381 struct work_record *work;
382 for (work = d1->workgrouplist; work; work = work->next)
384 if (work->token == Index)
386 queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
387 work->work_group,0x1d,0,0,
388 False,False,back_ip);
398 /****************************************************************************
399 send a backup list response.
400 **************************************************************************/
401 static void send_backup_list(char *work_name, struct nmb_name *src_name,
402 int info_count, int token, int info,
403 int name_type, struct in_addr ip)
405 struct subnet_record *d;
407 char *p, *countptr, *nameptr;
410 char *theirname = src_name->name;
412 DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
413 work_name, inet_ntoa(ip),
414 myname,0x20,theirname,0x0));
416 if (name_type == 0x1d)
418 DEBUG(4,("master browsers: "));
420 else if (name_type == 0x1b)
422 DEBUG(4,("domain controllers: "));
426 DEBUG(0,("backup request for unknown type %0x\n", name_type));
430 bzero(outbuf,sizeof(outbuf));
433 CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */
436 countptr = p; /* count pointer */
438 SSVAL(p,1,token); /* sender's workgroup index representation */
439 SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
444 for (d = subnetlist; d; d = d->next)
446 struct work_record *work;
448 for (work = d->workgrouplist; work; work = work->next)
450 struct server_record *s;
452 if (!strequal(work->work_group, work_name)) continue;
454 for (s = work->serverlist; s; s = s->next)
459 if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
461 for (n = nameptr; n < p; n = skip_string(n, 1))
463 if (strequal(n, s->serv.name)) found = True;
466 if (found) continue; /* exclude names already added */
468 /* workgroup request: include all backup browsers in the list */
469 /* domain request: include all domain members in the list */
471 if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
472 (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
474 DEBUG(4, ("%s ", s->serv.name));
477 strcpy(p,s->serv.name);
479 p = skip_string(p,1);
487 DEBUG(4, ("none\n"));
492 DEBUG(4, (" - count %d\n", count));
495 CVAL(countptr,0) = count; /* total number of backup browsers found */
498 int len = PTR_DIFF(p, outbuf);
500 for (i = 0; i < len; i+= 16)
502 DEBUG(4, ("%3x char ", i));
504 for (j = 0; j < 16; j++)
506 unsigned char x = outbuf[i+j];
507 if (x < 32 || x > 127) x = '.';
509 if (i+j >= len) break;
513 DEBUG(4, (" hex ", i));
515 for (j = 0; j < 16; j++)
517 if (i+j >= len) break;
518 DEBUG(4, (" %02x", outbuf[i+j]));
525 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
526 myname,theirname,0x20,0x0,ip,*iface_ip(ip));
530 /*******************************************************************
531 process a send backup list request
533 A client sends a backup list request to ask for a list of servers on
534 the net that maintain server lists for a domain. A server is then
535 chosen from this list to send NetServerEnum commands to to list
538 Currently samba only sends back one name in the backup list, its
539 own. For larger nets we'll have to add backups and send "become
540 backup" requests occasionally.
541 ******************************************************************/
542 static void process_send_backup_list(struct packet_struct *p,char *buf)
544 struct dgram_packet *dgram = &p->packet.dgram;
545 struct in_addr ip = dgram->header.source_ip;
546 struct subnet_record *d;
547 struct work_record *work;
549 int count = CVAL(buf,0);
550 int token = SVAL(buf,1); /* sender's key index for the workgroup? */
551 int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
552 int name_type = dgram->dest_name.name_type;
554 if (same_context(dgram)) return;
556 if (count <= 0) return;
558 if (name_type != 0x1b && name_type != 0x1d) {
559 DEBUG(0,("backup request to wrong type %d from %s\n",
560 name_type,inet_ntoa(ip)));
564 for (d = subnetlist; d; d = d->next)
566 for (work = d->workgrouplist; work; work = work->next)
568 if (strequal(work->work_group, dgram->dest_name.name))
570 DEBUG(2,("sending backup list to %s %s count=%d\n",
571 namestr(&dgram->dest_name),inet_ntoa(ip),count));
573 send_backup_list(work->work_group,&dgram->source_name,
574 count,token,info,name_type,ip);
582 /*******************************************************************
583 process a reset browser state
586 0x1 - stop being a master browser and become a backup browser.
587 0x2 - discard browse lists, stop being a master browser, try again.
588 0x4 - stop being a master browser forever. no way. ain't gonna.
590 ******************************************************************/
591 static void process_reset_browser(struct packet_struct *p,char *buf)
593 struct dgram_packet *dgram = &p->packet.dgram;
594 int state = CVAL(buf,0);
596 DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n",
597 namestr(&dgram->dest_name), state));
599 /* stop being a master but still deal with being a backup browser */
602 struct subnet_record *d;
603 for (d = subnetlist; d; d = d->next)
605 struct work_record *work;
606 for (work = d->workgrouplist; work; work = work->next)
610 become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
616 /* XXXX documentation inconsistency: the above description does not
617 exactly tally with what is implemented for state & 0x2
620 /* totally delete all servers and start afresh */
623 struct subnet_record *d;
624 for (d = subnetlist; d; d = d->next)
626 struct work_record *work;
627 for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
629 add_my_subnets(lp_workgroup());
632 /* stop browsing altogether. i don't think this is a good idea! */
635 DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
640 /*******************************************************************
641 process a announcement request
643 clients send these when they want everyone to send an announcement
644 immediately. This can cause quite a storm of packets!
645 ******************************************************************/
646 static void process_announce_request(struct packet_struct *p,char *buf)
648 struct dgram_packet *dgram = &p->packet.dgram;
649 struct work_record *work;
650 struct in_addr ip = dgram->header.source_ip;
651 struct subnet_record *d = find_subnet(ip);
652 int token = CVAL(buf,0);
657 DEBUG(3,("Announce request from %s to %s token=0x%X\n",
658 name,namestr(&dgram->dest_name), token));
660 if (strequal(dgram->source_name.name,myname)) return;
662 /* XXXX BUG or FEATURE?: need to ensure that we are a member of
663 this workgroup before announcing, particularly as we only
664 respond on local interfaces anyway.
666 if (strequal(dgram->dest_name, lp_workgroup()) return; ???
671 if (!d->my_interface) return;
673 for (work = d->workgrouplist; work; work = work->next)
675 /* XXXX BUG: the destination name type should also be checked,
676 not just the name. e.g if the name is WORKGROUP(0x1d) then
677 we should only respond if we own that name */
679 if (strequal(dgram->dest_name.name,work->work_group))
681 work->needannounce = True;
687 /****************************************************************************
688 depending on what announce has been made, we are only going to
689 accept certain types of name announce. XXXX untested code
691 check listening name type
692 ****************************************************************************/
693 BOOL listening_type(struct packet_struct *p, int command)
695 struct dgram_packet *dgram = &p->packet.dgram;
696 int type = dgram->dest_name.name_type;
700 case ANN_HostAnnouncement:
702 if (type != 0x0 || type != 0x20) return (False);
706 case ANN_AnnouncementRequest:
718 case ANN_GetBackupListReq:
724 case ANN_GetBackupListResp:
730 case ANN_DomainAnnouncement:
732 if (type != 0x1b || type != 0x1c) return (False);
736 case ANN_MasterAnnouncement:
738 if (type != 0x1d) return (False);
742 case ANN_LocalMasterAnnouncement:
744 if (type != 0x1c || type != 0x1d) return (False);
748 return (True); /* we're not dealing with unknown packet types */
752 /****************************************************************************
753 process a browse frame
754 ****************************************************************************/
755 void process_browse_packet(struct packet_struct *p,char *buf,int len)
757 int command = CVAL(buf,0);
760 case ANN_HostAnnouncement:
761 case ANN_DomainAnnouncement:
762 case ANN_LocalMasterAnnouncement:
764 process_announce(p,command,buf+1);
768 case ANN_AnnouncementRequest:
770 process_announce_request(p,buf+1);
776 process_election(p,buf+1);
780 case ANN_GetBackupListReq:
782 process_send_backup_list(p,buf+1);
786 case ANN_GetBackupListResp:
788 process_rcv_backup_list(p, buf+1);
792 case ANN_ResetBrowserState:
794 process_reset_browser(p, buf+1);
798 case ANN_MasterAnnouncement:
800 process_master_announce(p,buf+1);
806 struct dgram_packet *dgram = &p->packet.dgram;
807 DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
808 command, namestr(&dgram->source_name),
809 inet_ntoa(p->ip), namestr(&dgram->dest_name)));
815 /****************************************************************************
816 process udp 138 datagrams
817 ****************************************************************************/
818 void process_dgram(struct packet_struct *p)
823 struct dgram_packet *dgram = &p->packet.dgram;
825 if (dgram->header.msg_type != 0x10 &&
826 dgram->header.msg_type != 0x11 &&
827 dgram->header.msg_type != 0x12) {
828 /* don't process error packets etc yet */
832 buf = &dgram->data[0];
833 buf -= 4; /* XXXX for the pseudo tcp length -
834 someday I need to get rid of this */
836 if (CVAL(buf,smb_com) != SMBtrans) return;
838 len = SVAL(buf,smb_vwv11);
839 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
841 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
842 namestr(&dgram->source_name),namestr(&dgram->dest_name),
843 smb_buf(buf),CVAL(buf2,0),len));
846 if (len <= 0) return;
848 /* datagram packet received for the browser mailslot */
849 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
850 process_browse_packet(p,buf2,len);
854 /* datagram packet received for the domain log on mailslot */
855 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
856 process_logon_packet(p,buf2,len);