1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25#include <sys/tzfile.h>
26#include <errno.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <unistd.h>
30#include <syslog.h>
31#include <string.h>
32#include <strings.h>
33#include <time.h>
34#include <synch.h>
35#include <netdb.h>
36#include <sys/socket.h>
37#include <arpa/inet.h>
38
39#include <smbsrv/libsmb.h>
40#include <smbsrv/libsmbns.h>
41#include <smbsrv/smb.h>
42#include <smbsrv/mailslot.h>
43#include <smbns_browser.h>
44#include <smbns_netbios.h>
45
46/*
47 * ntdomain_info
48 * Temporary. It should be removed once NBTD is integrated.
49 */
50smb_ntdomain_t ntdomain_info;
51mutex_t ntdomain_mtx;
52cond_t ntdomain_cv;
53
54#define	SMB_SERVER_SIGNATURE		0xaa550415
55
56typedef struct smb_hostinfo {
57	list_node_t	hi_lnd;
58	smb_nic_t	hi_nic;
59	char		hi_nbname[NETBIOS_NAME_SZ];
60	name_entry_t	hi_netname;
61	uint32_t	hi_nextannouce;
62	int		hi_reps;
63	int		hi_interval;
64	uint8_t		hi_updatecnt;
65	uint32_t	hi_type;
66	smb_version_t	hi_version;
67} smb_hostinfo_t;
68
69typedef struct smb_browserinfo {
70	list_t		bi_hlist;
71	int		bi_hcnt;
72	rwlock_t	bi_hlist_rwl;
73	boolean_t	bi_changed;
74	mutex_t		bi_mtx;
75} smb_browserinfo_t;
76
77static smb_browserinfo_t smb_binfo;
78
79static int smb_browser_init(void);
80static void smb_browser_infoinit(void);
81static void smb_browser_infoterm(void);
82static void smb_browser_infofree(void);
83
84
85void
86smb_browser_reconfig(void)
87{
88	(void) mutex_lock(&smb_binfo.bi_mtx);
89	smb_binfo.bi_changed = B_TRUE;
90	(void) mutex_unlock(&smb_binfo.bi_mtx);
91}
92
93/*
94 * 3. Browser Overview
95 *
96 * Hosts involved in the browsing process can be separated into two
97 * distinct groups, browser clients and browser servers (often referred to
98 * simply as "browsers").
99 *
100 * A browser is a server which maintains information about servers -
101 * primarily the domain they are in and the services that they are running
102 * -- and about domains. Browsers may assume several different roles in
103 * their lifetimes, and dynamically switch between them.
104 *
105 *  Browser clients are of two types: workstations and (non-browser)
106 * servers. In the context of browsing, workstations query browsers for the
107 * information they contain; servers supply browsers the information by
108 * registering with them. Note that, at times, browsers may themselves
109 * behave as browser clients and query other browsers.
110 *
111 * For the purposes of this specification, a domain is simply a name with
112 * which to associate a group of resources such as computers, servers and
113 * users. Domains allow a convenient means for browser clients to restrict
114 * the scope of a search when they query browser servers. Every domain has
115 * a "master" server called the Primary Domain Controller (PDC) that
116 * manages various  activities within the domain.
117 *
118 * One browser for each domain on a subnet is designated the Local Master
119 * Browser for that domain. Servers in its domain on the subnet register
120 * with it, as do the Local Master Browsers for other domains on the
121 * subnet. It uses these registrations to maintain authoritative
122 * information about its domain on its subnet. If there are other subnets
123 * in the network, it also knows the name of the server running the
124 * domain's Domain Master Browser; it registers with it, and uses it to
125 * obtain information about the rest of the network (see below).
126 *
127 * Clients on a subnet query browsers designated as the Backup Browsers for
128 * the subnet (not the Master Browser). Backup Browsers maintain a copy of
129 * the information on the Local Master Browser; they get it by periodically
130 * querying the Local Master Browser for all of its information. Clients
131 * find the Backup Browsers by asking the Local Master Browser. Clients are
132 * expected to spread their queries evenly across Backup Browsers to
133 * balance the load.
134 *
135 * The Local Master Browser is dynamically elected automatically. Multiple
136 * Backup Browser Servers may exist per subnet; they are selected from
137 * among the potential browser servers by the Local Master Browser, which
138 * is configured to select enough to handle the expected query load.
139 *
140 * When there are multiple subnets, a Domain Master Browser is assigned
141 * the task of keeping the multiple subnets in synchronization. The Primary
142 * Domain Controller (PDC) always acts as the Domain Master Browser. The
143 * Domain Master Browser periodically acts as a client and queries all the
144 * Local Master Browsers for its domain, asking them for a list containing
145 * all the domains and all the servers in their domain known within their
146 * subnets; it merges all the replies into a single master list. This
147 * allows a Domain Master Browser server to act as a collection point for
148 * inter-subnet browsing information. Local Master Browsers periodically
149 * query the Domain Master Browser to retrieve the network-wide information
150 * it maintains.
151 *
152 * When a domain spans only a single subnet, there will not be any distinct
153 * Local Master Browser; this role will be handled by the Domain Master
154 * Browser. Similarly, the Domain Master Browser is always the Local Master
155 * Browser for the subnet it is on.
156 *
157 * When a browser client suspects that the Local Master Browser has failed,
158 * the client will instigate an election in which the browser servers
159 * participate, and some browser servers may change roles.
160 *
161 * Some characteristics of a good browsing mechanism include:
162 * . minimal network traffic
163 * . minimum server discovery time
164 * . minimum change discovery latency
165 * . immunity to machine failures
166 *
167 * Historically, Browser implementations had been very closely tied to
168 * NETBIOS and datagrams. The early implementations caused a lot of
169 * broadcast traffic. See Appendix D for an overview that presents how the
170 * Browser specification evolved.
171 *
172 * 4. Browsing Protocol Architecture
173 *
174 * This section first describes the how the browsing protocol is layered,
175 * then describes the roles of clients, servers, and browsers in the
176 * browsing subsystem.
177 *
178 * 4.1 Layering of Browsing Protocol Requests
179 *
180 * Most of the browser functionality is implemented using mailslots.
181 * Mailslots provide a mechanism for fast, unreliable unidirectional data
182 * transfer; they are named via ASCII "mailslot (path) name". Mailslots are
183 * implemented using the CIFS Transact SMB which is encapsulated in a
184 * NETBIOS datagram. Browser protocol requests are sent to browser specific
185 * mailslots using some browser-specific NETBIOS names. These datagrams can
186 * either be unicast or broadcast, depending on whether the NETBIOS name is
187 * a "unique name" or a "group name". Various data structures, which are
188 * detailed subsequently within this document, flow as the data portion of
189 * the Transact SMB.
190 *
191 * Here is an example of a generic browser SMB, showing how a browser
192 * request is encapsulated in a TRANSACT SMB request. Note that the PID,
193 * TID, MID, UID, and Flags are all 0 in mailslot requests.
194 *
195 * SMB: C transact, File = \MAILSLOT\BROWSE
196 *   SMB: SMB Status = Error Success
197 *     SMB: Error class = No Error
198 *     SMB: Error code = No Error
199 *   SMB: Header: PID = 0x0000 TID = 0x0000 MID = 0x0000 UID = 0x0000
200 *     SMB: Tree ID   (TID) = 0 (0x0)
201 *     SMB: Process ID  (PID) = 0 (0x0)
202 *     SMB: User ID   (UID) = 0 (0x0)
203 *     SMB: Multiplex ID (MID) = 0 (0x0)
204 *     SMB: Flags Summary = 0 (0x0)
205 *   SMB: Command = C transact
206 *     SMB: Word count = 17
207 *     SMB: Word parameters
208 *     SMB: Total parm bytes = 0
209 *     SMB: Total data bytes = 33
210 *     SMB: Max parm bytes = 0
211 *     SMB: Max data bytes = 0
212 *     SMB: Max setup words = 0
213 *     SMB: Transact Flags Summary = 0 (0x0)
214 *       SMB: ...............0 = Leave session intact
215 *       SMB: ..............0. = Response required
216 *     SMB: Transact timeout = 0 (0x0)
217 *     SMB: Parameter bytes = 0 (0x0)
218 *     SMB: Parameter offset = 0 (0x0)
219 *     SMB: Data bytes = 33 (0x21)
220 *     SMB: Data offset = 86 (0x56)
221 *     SMB: Setup word count = 3
222 *     SMB: Setup words
223 *     SMB: Mailslot opcode = Write mailslot
224 *     SMB: Transaction priority = 1
225 *     SMB: Mailslot class = Unreliable (broadcast)
226 *     SMB: Byte count = 50
227 *     SMB: Byte parameters
228 *     SMB: Path name = \MAILSLOT\BROWSE
229 *     SMB: Transaction data
230 *   SMB: Data: Number of data bytes remaining = 33 (0x0021)
231 *
232 * Note the SMB command is Transact, the opcode within the Transact SMB is
233 * Mailslot Write, and the browser data structure is carried as the
234 * Transact data.
235 * The Transaction data begins with an opcode, that signifies the operation
236 * and determines the size and structure of data that follows. This opcode
237 * is named as per one of the below:
238 *
239 * HostAnnouncement         1
240 * AnnouncementRequest      2
241 * RequestElection          8
242 * GetBackupListReq         9
243 * GetBackupListResp        10
244 * BecomeBackup             11
245 * DomainAnnouncment        12
246 * MasterAnnouncement       13
247 * LocalMasterAnnouncement  15
248 *
249 * Browser datagrams are often referred to as simply browser frames. The
250 * frames are in particular, referred to by the name of the opcode within
251 * the Transaction data e.g. a GetBackupListReq browser frame, a
252 * RequestElection browser frame, etc.
253 *
254 * The structures that are sent as the data portion of the Transact SMB are
255 * described in section(s) 6.2 through 6.12 in this document. These
256 * structures are tightly packed, i.e. there are no intervening pad bytes
257 * in the structure, unless they are explicitly described as being there.
258 * All quantities are sent in native Intel format and multi-byte values are
259 * transmitted least significant byte first.
260 *
261 * Besides mailslots and Transaction SMBs, the other important piece of the
262 * browser architecture is the NetServerEnum2 request. This request that
263 * allows an application to interrogate a Browser Server and obtain a
264 * complete list of resources (servers, domains, etc) known to that Browser
265 * server. Details of the NetServerEnum2 request are presented in section
266 * 6.4. Some examples of the NetServerEnum2 request being used are when a
267 * Local Master Browser sends a NetServerEnum2 request to the Domain Master
268 * Browser and vice versa. Another example is when a browser client sends a
269 * NetServerEnum2 request to a Backup Browser server.
270 *
271 * 4.3 Non-Browser Server
272 *
273 * A non-browser server is a server that has some resource(s) or service(s)
274 * it wishes to advertise as being available using the browsing protocol.
275 * Examples of non-browser servers would be an SQL server, print server,
276 * etc.
277 *
278 * A non-browser server MUST periodically send a HostAnnouncement browser
279 * frame, specifying the type of resources or services it is advertising.
280 * Details are in section 6.5.
281 *
282 * A non-browser server SHOULD announce itself relatively frequently when
283 * it first starts up in order to make its presence quickly known to the
284 * browsers and thence to potential clients. The frequency of the
285 * announcements SHOULD then be gradually stretched, so as to minimize
286 * network traffic. Typically,  non-browser servers announce themselves
287 * once every minute upon start up and then gradually adjust the frequency
288 * of the announcements to once every 12 minutes.
289 *
290 * A non-browser server SHOULD send a HostAnnouncement browser frame
291 * specifying a type of  0 just prior to shutting down, to allow it to
292 * quickly be removed from the list of available servers.
293 *
294 * A non-browser server MUST receive and process AnnouncementRequest frames
295 * from the Local Master Browser, and MUST respond with a HostAnnouncement
296 * frame, after a delay chosen randomly from the interval [0,30] seconds.
297 * AnnouncementRequests typically happen when a Local Master Browser starts
298 * up with an empty list of servers for the domain, and wants to fill it
299 * quickly. The 30 second range for responses prevents the Master Browser
300 * from becoming overloaded and losing replies, as well as preventing the
301 * network from being flooded with responses.
302 *
303 * 4.4  Browser Servers
304 *
305 * The following sections describe the roles of the various types of
306 * browser servers.
307 *
308 * 4.4.1  Potential Browser Server
309 *
310 * A Potential Browser server is a browser server that is capable of being
311 * a Backup Browser server or Master Browser server, but is not currently
312 * fulfilling either of those roles.
313 *
314 * A Potential Browser MUST set type SV_TYPE_POTENTIAL_BROWSER (see section
315 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its
316 * last HostAnnouncement frame before it shuts down, it SHOULD specify a
317 * type of  0.
318 *
319 * A Potential Browser server MUST receive and process BecomeBackup frames
320 * (see section 6.9) and become a backup browser upon their receipt.
321 *
322 * A Potential Browser MUST participate in browser elections (see section
323 * 6.8).
324 *
325 * 4.4.2  Backup Browser
326 *
327 * Backup Browser servers are a subset of the Potential Browsers that have
328 * been chosen by the Master Browser on their subnet to be the Backup
329 * Browsers for the subnet.
330 *
331 * A Backup Browser MUST set type SV_TYPE_BACKUP_BROWSER (see section
332 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its
333 * last HostAnnouncement frame before it shuts down, it SHOULD specify a
334 * type of  0.
335 *
336 * A Backup Browser MUST listen for a LocalMasterAnnouncement frame (see
337 * section 6.10) from the Local Master Browser, and use it to set the name
338 * of the Master Browser it queries for the server and domain lists.
339 *
340 * A  Backup Browsers MUST periodically make a NetServerEnum2 request of
341 * the Master Browser on its subnet for its domain to get a list of servers
342 * in that domain, as well as a list of domains. The period is a
343 * configuration option balancing currency of the information with network
344 * traffic costs - a typical value is 15 minutes.
345 *
346 * A Backup Browser SHOULD force an election by sending a RequestElection
347 * frame (see section 6.7) if it does not get a response to its periodic
348 * NetServeEnum2 request to the Master Browser.
349 *
350 * A Backup Browser MUST receive and process NetServerEnum2 requests from
351 * browser clients, for its own domain and others. If the request is for a
352 * list of servers in its domain, or for a list of domains, it can answer
353 * from its internal lists. If the request is for a list of servers in a
354 * domain different than the one it serves, it sends a NetServerEnum2
355 * request to the Domain Master Browser for that domain (which it can in
356 * find in its list of domains and their Domain Master Browsers).
357 *
358 * A Backup Browser MUST participate in browser elections (see section
359 * 6.8).
360 *
361 * 4.4.3 Master Browser
362 *
363 * Master Browsers are responsible for:
364 * . indicating it is a Master Browser
365 * . receiving server announcements and building a list of such servers
366 *   and keeping it reasonably up-to-date.
367 * . returning lists of Backup Browsers to browser clients.
368 * . ensuring an appropriate number of Backup Browsers are available.
369 * . announcing their existence to other Master Browsers on their subnet,
370 *   to the Domain Master Browser for their domain, and to all browsers in
371 *   their domain on their subnet
372 * . forwarding requests for lists of servers on other domains to the
373 *   Master Browser for that domain
374 * . keeping a list of domains in its subnet
375 * . synchronizing with the Domain Master Browser (if any) for its domain
376 * . participating in browser elections
377 * . ensuring that there is only one Master Browser on its subnet
378 *
379 * A Master Browser MUST set type SV_TYPE_MASTER_BROWSER (see section
380 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its
381 * last HostAnnouncement frame before it shuts down, it SHOULD specify a
382 * type of  0.
383 *
384 * A Master Browser MUST receive and process HostAnnouncement frames from
385 * servers, adding the server name and other information to its servers
386 * list; it must mark them as "local" entries. Periodically, it MUST check
387 * all local server entries to see if a server's HostAnnouncement has timed
388 * out (no HostAnnouncement received for three times the periodicity the
389 * server gave in the last received HostAnnouncement) and remove timed-out
390 * servers from its list.
391 *
392 * A Master Browser MUST receive and process DomainAnnouncement frames (see
393 * section 6.12) and maintain the domain names and their associated (Local)
394 * Master Browsers in its internal domain list until they time out; it must
395 * mark these as "local" entries. Periodically, it MUST check all local
396 * domain entries to see if a server's DomainAnnouncement has timed out (no
397 * DomainAnnouncement received for three times the periodicity the server
398 * gave in the last received DomainAnnouncement) and remove timed-out
399 * servers from its list.
400 *
401 * A Master Browser MUST receive and process GetBackupListRequest frames
402 * from clients, returning GetBackupListResponse frames containing a list
403 * of the Backup Servers for its domain.
404 *
405 * A Master Browser MUST eventually send BecomeBackup frames (see section
406 * 6.9) to one or more Potential Browser servers to increase the number of
407 * Backup Browsers if there are not enough Backup Browsers to handle the
408 * anticipated query load. Note: possible good times for checking for
409 * sufficient backup browsers are after being elected, when timing out
410 * server HostAnnouncements, and when receiving a server's HostAnnouncement
411 * for the first time.
412 *
413 * A Master Browser MUST periodically announce itself and the domain it
414 * serves to other (Local) Master Browsers on its subnet, by sending a
415 * DomainAnnouncement frame (see section 6.12) to its subnet.
416 *
417 * A Master Browser MUST send a MasterAnnouncement frame (see section 6.11)
418 * to the Domain Master Browser after it is first elected, and periodically
419 * thereafter. This informs the Domain Master Browser of the presence of
420 * all the Master Browsers.
421 *
422 * A Master Browser MUST periodically announce itself to all browsers for
423 * its domain on its subnet by sending a LocalMasterAnnouncement frame (see
424 * section 6.10).
425 *
426 * A Master Browser MUST receive and process NetServerEnum2 requests from
427 * browser clients, for its own domain and others. If the request is for a
428 * list of servers in its domain, or for a list of domains, it can answer
429 * from its internal lists. Entries in its list marked "local" MUST have
430 * the SV_TYPE_LOCAL_LIST_ONLY bit set in the returned results; it must be
431 * clear for all other entries. If the request is for a list of servers in
432 * a domain different than the one it serves, it sends a NetServerEnum2
433 * request to the Domain Master Browser for that domain (which it can in
434 * find in its list of domains and their Domain Master Browsers).
435 *
436 *     Note: The list of servers that the Master Browser maintains and
437 *     returns to the Backup Browsers, is limited in size to 64K of
438 *     data. This will limit the number of systems that can be in a
439 *     browse list in a single workgroup or domain to approximately two
440 *     thousand systems.
441 *
442 * A Master Browser SHOULD request all servers to register with it by
443 * sending an AnnouncementRequest frame, if, on becoming the Master Browser
444 * by winning an election, its server list is empty. Otherwise, clients
445 * might get an incomplete list of servers until the servers' periodic
446 * registrations fill the server list.
447 *
448 * If the Master Browser on a subnet is not the Primary Domain Controller
449 * (PDC), then it is a Local Master Browser.
450 *
451 * A Local Master Browser MUST periodically synchronize with the Domain
452 * Master Browser (which is the PDC). This synchronization is performed by
453 * making a NetServerEnum2 request to the Domain Master Browser and merging
454 * the results with its list of servers and domains. An entry from the
455 * Domain Master Browser should be marked "non-local", and must not
456 * overwrite an entry with the same name marked "local". The Domain Master
457 * Browser is located as specified in Appendix B.
458 *
459 * A Master Browser MUST participate in browser elections (see section
460 * 6.8).
461 *
462 * A Master Browser MUST, if it receives a HostAnnouncement,
463 * DomainAnnouncement, or LocalMasterAnnouncement frame another system that
464 * claims to be the Master Browser for its domain, demote itself from
465 * Master Browser and force an election. This ensures that there is only
466 * ever one Master Browser in each workgroup or domain.
467 *
468 * A Master Browser SHOULD, if it loses an election, become a Backup
469 * Browser (without being told to do so by the new Master Browser). Since
470 * it has more up-to-date information in its lists than a Potential
471 * Browser, it is more efficient to have it be a Backup Browser than to
472 * promote a Potential Browser.
473 *
474 * 4.4.3.1 Preferred Master Browser
475 *
476 * A Preferred Master Browser supports exactly the same protocol elements
477 * as a Potential Browser, except as follows.
478 *
479 * A Preferred Master Browser MUST always force an election when it starts
480 * up.
481 *
482 * A Preferred Master Browser MUST participate in browser elections (see
483 * section 6.8).
484 *
485 * A Preferred Master Browser MUST set the Preferred Master bit in the
486 * RequestElection frame (see section 6.7) to bias the election in its
487 * favor.
488 *
489 * A Preferred Master Browser SHOULD, if it loses an election,
490 * automatically become a Backup Browser, without being told to do so by
491 * the Master Browser.
492 *
493 * 4.4.4 Domain Master Browser
494 *
495 * Since the Domain Master Browser always runs on the PDC, it must
496 * implement all the protocols required of a PDC in addition to the
497 * browsing protocol, and that is way beyond the scope of this
498 * specification.
499 *
500 * 5. Mailslot Protocol Specification
501 *
502 * The only transaction allowed to a mailslot is a mailslot write. Mailslot
503 * writes requests are encapsulated in TRANSACT SMBs. The following table
504 * shows the interpretation of the TRANSACT SMB parameters for a mailslot
505 * transaction:
506 *
507 *  Name            Value               Description
508 *  Command         SMB_COM_TRANSACTION
509 *  Name            <name>              STRING name of mail slot to write;
510 *                                      must start with "\\MAILSLOT\\"
511 *  SetupCount      3                   Always 3 for mailslot writes
512 *  Setup[0]        1                   Command code == write mailslot
513 *  Setup[1]        Ignored
514 *  Setup[2]        Ignored
515 *  TotalDataCount  n                   Size of data in bytes to write to
516 *                                      the mailslot
517 *  Data[ n ]                           The data to write to the mailslot
518 *
519 */
520
521/*
522 * SMB: C transact, File = \MAILSLOT\BROWSE
523 *   SMB: SMB Status = Error Success
524 *     SMB: Error class = No Error
525 *     SMB: Error code = No Error
526 *   SMB: Header: PID = 0x0000 TID = 0x0000 MID = 0x0000 UID = 0x0000
527 *     SMB: Tree ID   (TID) = 0 (0x0)
528 *     SMB: Process ID  (PID) = 0 (0x0)
529 *     SMB: User ID   (UID) = 0 (0x0)
530 *     SMB: Multiplex ID (MID) = 0 (0x0)
531 *     SMB: Flags Summary = 0 (0x0)
532 *   SMB: Command = C transact
533 *     SMB: Word count = 17
534 *     SMB: Word parameters
535 *     SMB: Total parm bytes = 0
536 *     SMB: Total data bytes = 33
537 *     SMB: Max parm bytes = 0
538 *     SMB: Max data bytes = 0
539 *     SMB: Max setup words = 0
540 *     SMB: Transact Flags Summary = 0 (0x0)
541 *       SMB: ...............0 = Leave session intact
542 *       SMB: ..............0. = Response required
543 *     SMB: Transact timeout = 0 (0x0)
544 *     SMB: Parameter bytes = 0 (0x0)
545 *     SMB: Parameter offset = 0 (0x0)
546 *     SMB: Data bytes = 33 (0x21)
547 *     SMB: Data offset = 86 (0x56)
548 *     SMB: Setup word count = 3
549 *     SMB: Setup words
550 *     SMB: Mailslot opcode = Write mailslot
551 *     SMB: Transaction priority = 1
552 *     SMB: Mailslot class = Unreliable (broadcast)
553 *     SMB: Byte count = 50
554 *     SMB: Byte parameters
555 *     SMB: Path name = \MAILSLOT\BROWSE
556 *     SMB: Transaction data
557 *   SMB: Data: Number of data bytes remaining = 33 (0x0021)
558 *
559 * 5. Mailslot Protocol Specification
560 *
561 * The only transaction allowed to a mailslot is a mailslot write. Mailslot
562 * writes requests are encapsulated in TRANSACT SMBs. The following table
563 * shows the interpretation of the TRANSACT SMB parameters for a mailslot
564 * transaction:
565 *
566 *  Name            Value               Description
567 *  Command         SMB_COM_TRANSACTION
568 *  Name            <name>              STRING name of mail slot to write;
569 *                                      must start with "\MAILSLOT\"
570 *  SetupCount      3                   Always 3 for mailslot writes
571 *  Setup[0]        1                   Command code == write mailslot
572 *  Setup[1]        Ignored
573 *  Setup[2]        Ignored
574 *  TotalDataCount  n                   Size of data in bytes to write to
575 *                                      the mailslot
576 *  Data[ n ]                           The data to write to the mailslot
577 *
578 *	Magic		0xFF 'S' 'M' 'B'
579 *	smb_com 	a byte, the "first" command
580 *	Error		a 4-byte union, ignored in a request
581 *	smb_flg		a one byte set of eight flags
582 *	smb_flg2	a two byte set of 16 flags
583 *	.		twelve reserved bytes, have a role
584 *			in connectionless transports (IPX, UDP?)
585 *	smb_tid		a 16-bit tree ID, a mount point sorta,
586 *			0xFFFF is this command does not have
587 *			or require a tree context
588 *	smb_pid		a 16-bit process ID
589 *	smb_uid		a 16-bit user ID, specific to this "session"
590 *			and mapped to a system (bona-fide) UID
591 *	smb_mid		a 16-bit multiplex ID, used to differentiate
592 *			multiple simultaneous requests from the same
593 *			process (pid) (ref RPC "xid")
594 */
595
596int
597smb_browser_load_transact_header(unsigned char *buffer, int maxcnt,
598    int data_count, int reply, char *mailbox)
599{
600	smb_msgbuf_t mb;
601	int	mailboxlen;
602	char *fmt;
603	int result;
604	short	class = (reply == ONE_WAY_TRANSACTION) ? 2 : 0;
605
606	/*
607	 * If the mailboxlen is an even number we need to pad the
608	 * header so that the data starts on a word boundary.
609	 */
610	fmt = "Mb4.bw20.bwwwwb.wl2.wwwwb.wwwws";
611	mailboxlen = strlen(mailbox) + 1;
612
613	if ((mailboxlen & 0x01) == 0) {
614		++mailboxlen;
615		fmt = "Mb4.bw20.bwwwwb.wl2.wwwwb.wwwws.";
616	}
617
618	bzero(buffer, maxcnt);
619	smb_msgbuf_init(&mb, buffer, maxcnt, 0);
620
621	result = smb_msgbuf_encode(&mb, fmt,
622	    SMB_COM_TRANSACTION,	/* Command */
623	    0x18,
624	    0x3,
625	    17,				/* Count of parameter words */
626	    0,				/* Total Parameter words sent */
627	    data_count,			/* Total Data bytes sent */
628	    2,				/* Max Parameters to return */
629	    0,				/* Max data bytes to return */
630	    0,				/* Max setup bytes to return */
631	    reply,			/* No reply */
632	    0xffffffff,			/* Timeout */
633	    0,				/* Parameter bytes sent */
634	    0,				/* Parameter offset */
635	    data_count,			/* Data bytes sent */
636	    69 + mailboxlen,		/* Data offset */
637	    3,				/* Setup word count */
638	    1,				/* Setup word[0] */
639	    0,				/* Setup word[1] */
640	    class,			/* Setup word[2] */
641	    mailboxlen + data_count,	/* Total request bytes */
642	    mailbox);			/* Mailbox address */
643
644	smb_msgbuf_term(&mb);
645	return (result);
646}
647
648static int
649smb_browser_addr_of_subnet(struct name_entry *name, smb_hostinfo_t *hinfo,
650    struct name_entry *result)
651{
652	uint32_t ipaddr, mask, saddr;
653	addr_entry_t *addr;
654
655	if (name == NULL)
656		return (-1);
657
658	if (hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS)
659		return (-1);
660
661	ipaddr = hinfo->hi_nic.nic_ip.a_ipv4;
662	mask = hinfo->hi_nic.nic_mask;
663
664	*result = *name;
665	addr = &name->addr_list;
666	do {
667		saddr = addr->sin.sin_addr.s_addr;
668		if ((saddr & mask) == (ipaddr & mask)) {
669			*result = *name;
670			result->addr_list = *addr;
671			result->addr_list.forw = result->addr_list.back =
672			    &result->addr_list;
673			return (0);
674		}
675		addr = addr->forw;
676	} while (addr != &name->addr_list);
677
678	return (-1);
679}
680
681
682static int
683smb_browser_bcast_addr_of_subnet(struct name_entry *name, uint32_t bcast,
684    struct name_entry *result)
685{
686	if (name != NULL && name != result)
687		*result = *name;
688
689	result->addr_list.sin.sin_family = AF_INET;
690	result->addr_list.sinlen = sizeof (result->addr_list.sin);
691	result->addr_list.sin.sin_addr.s_addr = bcast;
692	result->addr_list.sin.sin_port = htons(IPPORT_NETBIOS_DGM);
693	result->addr_list.forw = result->addr_list.back = &result->addr_list;
694	return (0);
695}
696
697/*
698 * 6.5 HostAnnouncement Browser Frame
699 *
700 * To advertise its presence, i.e. to publish itself as being available, a
701 * non-browser server sends a HostAnnouncement browser frame. If the server
702 * is a member of domain "D", this frame is sent to the NETBIOS unique name
703 * D(1d) and mailslot "\\MAILSLOT\\BROWSE". The definition of  the
704 * HostAnnouncement frame is:
705 *
706 *     struct {
707 *         unsigned short  Opcode;
708 *         unsigned char   UpdateCount;
709 *         uint32_t   Periodicity;
710 *         unsigned char   ServerName[];
711 *         unsigned char   VersionMajor;
712 *         unsigned char   VersionMinor;
713 *         uint32_t   Type;
714 *         uint32_t   Signature;
715 *         unsigned char   Comment[];
716 *     }
717 *
718 * where:
719 *      Opcode - Identifies this structure as a browser server
720 *          announcement and is defined as HostAnnouncement with a
721 *          value of decimal 1.
722 *
723 *      UpdateCount - must be sent as zero and ignored on receipt.
724 *
725 *      Periodicity - The announcement frequency of the server (in
726 *          seconds). The server will be removed from the browse list
727 *          if it has not been heard from in 3X its announcement
728 *          frequency. In no case will the server be removed from the
729 *          browse list before the period 3X has elapsed. Actual
730 *          implementations may take more than 3X to actually remove
731 *          the server from the browse list.
732 *
733 *      ServerName - Null terminated ASCII server name (up to 16 bytes
734 *          in length).
735 *
736 *      VersionMajor - The major version number of the OS the server
737 *          is running. it will be returned by NetServerEnum2.
738 *
739 *      VersionMinor - The minor version number of the OS the server
740 *          is running. This is entirely informational and does not
741 *          have any significance for the browsing protocol.
742 *
743 *      Type - Specifies the type of the server. The server type bits
744 *          are specified in the NetServerEnum2 section.
745 *
746 *      Signature -  The browser protocol minor version number in the
747 *          low 8 bits, the browser protocol major version number in
748 *          the next higher 8 bits and the signature 0xaa55 in the
749 *          high 16 bits of this field. Thus, for this version of the
750 *          browser protocol (1.15) this field has the value
751 *          0xaa55010f. This may used to isolate browser servers that
752 *          are running out of revision browser software; otherwise,
753 *          it is ignored.
754 *
755 *      Comment - Null terminated ASCII comment for the server.
756 *          Limited to 43 bytes.
757 *
758 * When a non-browser server starts up, it announces itself in the manner
759 * described once every minute. The frequency of these statements is
760 * gradually stretched to once every 12 minutes.
761 *
762 * Note: older non-browser servers in a domain "D" sent HostAnnouncement
763 * frames to the NETBIOS group name D(00). Non-Browser servers supporting
764 * version 1.15 of the browsing protocol SHOULD NOT use this NETBIOS name,
765 * but for backwards compatibility Master Browsers MAY receive and process
766 * HostAnnouncement frames on this name as described above for D(1d).
767 */
768
769static void
770smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
771    uint32_t next_announcement, boolean_t remove,
772    addr_entry_t *addr, char suffix)
773{
774	smb_msgbuf_t mb;
775	int offset, announce_len, data_length;
776	struct name_entry dest_name;
777	unsigned char *buffer;
778	uint32_t type;
779	char resource_domain[SMB_PI_MAX_DOMAIN];
780
781	if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
782		return;
783	(void) smb_strupr(resource_domain);
784
785	if (addr == NULL) {
786		/* Local master Browser */
787		smb_init_name_struct((unsigned char *)resource_domain, suffix,
788		    0, 0, 0, 0, 0, &dest_name);
789		if (smb_browser_bcast_addr_of_subnet(0, hinfo->hi_nic.nic_bcast,
790		    &dest_name) < 0)
791			return;
792	} else {
793		smb_init_name_struct((unsigned char *)resource_domain, suffix,
794		    0, 0, 0, 0, 0, &dest_name);
795		dest_name.addr_list = *addr;
796		dest_name.addr_list.forw = dest_name.addr_list.back =
797		    &dest_name.addr_list;
798	}
799
800	/* give some extra room */
801	buffer = malloc(MAX_DATAGRAM_LENGTH * 2);
802	if (buffer == NULL) {
803		syslog(LOG_DEBUG, "smb browser: HostAnnouncement: %m");
804		return;
805	}
806
807	data_length = 1 + 1 + 4 + 16 + 1 + 1 + 4 + 4 +
808	    strlen(hinfo->hi_nic.nic_cmnt) + 1;
809
810	offset = smb_browser_load_transact_header(buffer,
811	    MAX_DATAGRAM_LENGTH, data_length, ONE_WAY_TRANSACTION,
812	    MAILSLOT_BROWSE);
813
814	if (offset < 0) {
815		free(buffer);
816		return;
817	}
818
819	/*
820	 * A non-browser server SHOULD send a HostAnnouncement browser frame
821	 * specifying a type of 0 just prior to shutting down, to allow it to
822	 * quickly be removed from the list of available servers.
823	 */
824	if (remove || (!smb_netbios_running()))
825		type = 0;
826	else
827		type = hinfo->hi_type;
828
829	smb_msgbuf_init(&mb, buffer + offset, MAX_DATAGRAM_LENGTH - offset, 0);
830
831	announce_len = smb_msgbuf_encode(&mb, "bbl16cbblls",
832	    HOST_ANNOUNCEMENT,
833	    ++hinfo->hi_updatecnt,
834	    next_announcement * 60000,	/* Periodicity in MilliSeconds */
835	    hinfo->hi_nbname,
836	    (uint8_t)hinfo->hi_version.sv_major,
837	    (uint8_t)hinfo->hi_version.sv_minor,
838	    type,
839	    SMB_SERVER_SIGNATURE,
840	    hinfo->hi_nic.nic_cmnt);
841
842	if (announce_len > 0)
843		(void) smb_netbios_datagram_send(&hinfo->hi_netname, &dest_name,
844		    buffer, offset + announce_len);
845
846	free(buffer);
847	smb_msgbuf_term(&mb);
848}
849
850static void
851smb_browser_process_AnnouncementRequest(struct datagram *datagram,
852    char *mailbox)
853{
854	smb_hostinfo_t *hinfo;
855	uint32_t next_announcement;
856	uint32_t delay = random() % 29; /* in seconds */
857	boolean_t h_found = B_FALSE;
858
859	if (strcmp(mailbox, MAILSLOT_LANMAN) != 0) {
860		syslog(LOG_DEBUG, "smb browser: wrong mailbox (%s)", mailbox);
861		return;
862	}
863
864	smb_netbios_sleep(delay);
865
866	(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
867	hinfo = list_head(&smb_binfo.bi_hlist);
868	while (hinfo) {
869		if ((hinfo->hi_nic.nic_ip.a_ipv4 &
870		    hinfo->hi_nic.nic_mask) ==
871		    (datagram->src.addr_list.sin.sin_addr.s_addr &
872		    hinfo->hi_nic.nic_mask)) {
873			h_found = B_TRUE;
874			break;
875		}
876		hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
877	}
878
879	if (h_found) {
880		next_announcement = hinfo->hi_nextannouce * 60 * 1000;
881		smb_browser_send_HostAnnouncement(hinfo, next_announcement,
882		    B_FALSE, &datagram->src.addr_list, NBT_MB);
883	}
884	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
885}
886
887void *
888smb_browser_dispatch(void *arg)
889{
890	struct datagram *datagram = (struct datagram *)arg;
891	smb_msgbuf_t 	mb;
892	int		rc;
893	unsigned char	command;
894	unsigned char	parameter_words;
895	unsigned short	total_parameter_words;
896	unsigned short	total_data_count;
897	unsigned short	max_parameters_to_return;
898	unsigned short	max_data_to_return;
899	unsigned char	max_setup_bytes_to_return;
900	unsigned short	reply;
901	unsigned short	parameter_bytes_sent;
902	unsigned short	parameter_offset;
903	unsigned short	data_bytes_sent;
904	unsigned short	data_offset;
905	unsigned char	setup_word_count;
906	unsigned short	setup_word_0;
907	unsigned short	setup_word_1;
908	unsigned short	setup_word_2;
909	unsigned short	total_request_bytes;
910	char 		*mailbox;
911	unsigned char	message_type;
912	unsigned char 	*data;
913	int		datalen;
914
915	syslog(LOG_DEBUG, "smb browser: packet received");
916
917	smb_msgbuf_init(&mb, datagram->data, datagram->data_length, 0);
918	rc = smb_msgbuf_decode(&mb, "Mb27.bwwwwb.w6.wwwwb.wwwws",
919	    &command,			/* Command */
920	    &parameter_words,		/* Count of parameter words */
921	    &total_parameter_words,	/* Total Parameter words sent */
922	    &total_data_count,		/* Total Data bytes sent */
923	    &max_parameters_to_return,	/* Max Parameters to return */
924	    &max_data_to_return,	/* Max data bytes to return */
925	    &max_setup_bytes_to_return,	/* Max setup bytes to return */
926	    &reply,			/* No reply */
927	    &parameter_bytes_sent,	/* Parameter bytes sent */
928	    &parameter_offset,		/* Parameter offset */
929	    &data_bytes_sent,		/* Data bytes sent */
930	    &data_offset,		/* Data offset */
931	    &setup_word_count,		/* Setup word count */
932	    &setup_word_0,		/* Setup word[0] */
933	    &setup_word_1,		/* Setup word[1] */
934	    &setup_word_2,		/* Setup word[2] */
935	    &total_request_bytes,	/* Total request bytes */
936	    &mailbox);			/* Mailbox address */
937
938	if (rc < 0) {
939		syslog(LOG_ERR, "smb browser: decode error");
940		smb_msgbuf_term(&mb);
941		free(datagram);
942		return (0);
943	}
944
945	data = &datagram->data[data_offset];
946	datalen = datagram->data_length - data_offset;
947
948	/*
949	 * The PDC location protocol, i.e. anything on the \\NET
950	 * mailslot, is handled by the smb_netlogon module.
951	 */
952	if (strncasecmp("\\MAILSLOT\\NET\\", mailbox, 14) == 0) {
953		smb_netlogon_receive(datagram, mailbox, data, datalen);
954		smb_msgbuf_term(&mb);
955		free(datagram);
956		return (0);
957	}
958
959	/*
960	 * If it's not a netlogon message, assume it's a browser request.
961	 * This is not the most elegant way to extract the command byte
962	 * but at least we no longer use it to get the netlogon opcode.
963	 */
964	message_type = datagram->data[data_offset];
965
966	switch (message_type) {
967	case ANNOUNCEMENT_REQUEST :
968		smb_browser_process_AnnouncementRequest(datagram, mailbox);
969		break;
970
971	default:
972		syslog(LOG_DEBUG, "smb browser: invalid message type(%d, %x)",
973		    message_type, message_type);
974		break;
975	}
976
977	smb_msgbuf_term(&mb);
978	free(datagram);
979	return (0);
980}
981
982
983/*
984 * 11.1 Registered unique names
985 *
986 *  <COMPUTER>(00)
987 *     This name is used by all servers and clients to receive second
988 *     class mailslot messages. A system must add this name in order to
989 *     receive mailslot messages. The only browser requests that should
990 *     appear on this name are BecomeBackup, GetBackupListResp,
991 *     MasterAnnouncement, and LocalMasterAnnouncement frames. All other
992 *     datagrams (other than the expected non-browser datagrams) may be
993 *     ignored and an error logged.
994 *
995 *   <DOMAIN>(1d)
996 *     This name is used to identify a master browser server for domain
997 *     "DOMAIN" on a subnet.  A master browser server adds this name as a
998 *     unique NETBIOS name when it becomes master browser. If the attempt
999 *     to add the name fails, the master browser server assumes that there
1000 *     is another master in the domain and will fail to come up. It may
1001 *     log an error if the failure occurs more than 3 times in a row (this
1002 *     either indicates some form of network misconfiguration or a
1003 *     software error). The only requests that should appear on this name
1004 *     are GetBackupListRequest and HostAnnouncement requests. All other
1005 *     datagrams on this name may be ignored (and an error logged). If
1006 *     running a NETBIOS name service (NBNS, such as WINS), this name
1007 *     should not be registered with the NBNS.
1008 *
1009 *   <DOMAIN>(1b)
1010 *     This name is used to identify the Domain Master Browser for domain
1011 *     "DOMAIN" (which is also the primary domain controller). It is a
1012 *     unique name added only by the primary domain controller. The
1013 *     primary domain controller will respond to GetBackupListRequest on
1014 *     this name just as it responds to these requests on the <DOMAIN>(1d)
1015 *     name.
1016 *
1017 * 11.2 Registered group names
1018 *
1019 *   (01)(02)__MSBROWSE__(02)(01)
1020 *     This name is used by Master Browsers to announce themselves to the
1021 *     other Master Browsers on a subnet. It is added as a group name by
1022 *     all Master Browser servers. The only broadcasts that should appear
1023 *     on this name is DomainAnnouncement requests. All other datagrams
1024 *     can be ignored.
1025 *
1026 *   <DOMAIN>(00)
1027 *     This name is used by clients and servers in domain "DOMAIN" to
1028 *     process server announcements. The only requests that should appear
1029 *     on this name that the browser is interested in are
1030 *     AnnouncementRequest and NETLOGON_QUERY (to locate the PDC) packets.
1031 *     All other unidentifiable requests may be ignored (and an error
1032 *     logged).
1033 *
1034 *   <DOMAIN>(1E)
1035 *     This name is used for announcements to browsers for domain "DOMAIN"
1036 *     on a subnet. This name is registered by all the browser servers in
1037 *     the domain. The only requests that should appear on this name are
1038 *     RequestElection and AnnouncementRequest packets. All other
1039 *     datagrams may be ignored (and an error logged).
1040 *
1041 *   <DOMAIN>(1C)
1042 *     This name is registered by Primary Domain Controllers.
1043 */
1044
1045static void
1046smb_browser_config(void)
1047{
1048	smb_hostinfo_t *hinfo;
1049	struct name_entry	name;
1050	struct name_entry	master;
1051	struct name_entry	dest;
1052	struct name_entry	*entry;
1053	char resource_domain[SMB_PI_MAX_DOMAIN];
1054	int rc;
1055
1056	if (smb_browser_init() != 0)
1057		return;
1058
1059	if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
1060		return;
1061	(void) smb_strupr(resource_domain);
1062
1063	/* domain<00> */
1064	smb_init_name_struct((unsigned char *)resource_domain, NBT_WKSTA,
1065	    0, 0, 0, 0, 0, &name);
1066	entry = smb_name_find_name(&name);
1067	smb_name_unlock_name(entry);
1068
1069	(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1070	hinfo = list_head(&smb_binfo.bi_hlist);
1071	while (hinfo) {
1072		smb_init_name_struct((unsigned char *)resource_domain,
1073		    NBT_WKSTA, 0, hinfo->hi_nic.nic_ip.a_ipv4,
1074		    htons(IPPORT_NETBIOS_DGM), NAME_ATTR_GROUP,
1075		    NAME_ATTR_LOCAL, &name);
1076		(void) smb_name_add_name(&name);
1077
1078		hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1079	}
1080	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1081
1082	/* All our local master browsers */
1083	smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
1084	    0, 0, 0, 0, 0, &dest);
1085	entry = smb_name_find_name(&dest);
1086
1087	if (entry) {
1088		(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1089		hinfo = list_head(&smb_binfo.bi_hlist);
1090		while (hinfo) {
1091			rc = smb_browser_addr_of_subnet(entry, hinfo, &master);
1092			if (rc == 0) {
1093				syslog(LOG_DEBUG,
1094				    "smb browser: master browser found at %s",
1095				    inet_ntoa(master.addr_list.sin.sin_addr));
1096			}
1097			hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1098		}
1099		(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1100
1101		smb_name_unlock_name(entry);
1102	}
1103
1104	/* Domain master browser */
1105	smb_init_name_struct((unsigned char *)resource_domain,
1106	    NBT_DMB, 0, 0, 0, 0, 0, &dest);
1107
1108	if ((entry = smb_name_find_name(&dest)) != 0) {
1109		syslog(LOG_DEBUG,
1110		    "smb browser: domain master browser for %s is %s",
1111		    resource_domain,
1112		    inet_ntoa(entry->addr_list.sin.sin_addr));
1113		smb_name_unlock_name(entry);
1114	}
1115}
1116
1117static int
1118smb_browser_init(void)
1119{
1120	smb_hostinfo_t *hinfo;
1121	smb_niciter_t ni;
1122	uint32_t type;
1123	smb_version_t version;
1124
1125	smb_config_get_version(&version);
1126
1127	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
1128	smb_browser_infofree();
1129
1130	if (smb_nic_getfirst(&ni) != SMB_NIC_SUCCESS) {
1131		(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1132		return (-1);
1133	}
1134
1135	type = MY_SERVER_TYPE;
1136	if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN)
1137		type |= SV_DOMAIN_MEMBER;
1138
1139	do {
1140		if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
1141		    (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS))
1142			continue;
1143
1144		hinfo = malloc(sizeof (smb_hostinfo_t));
1145		if (hinfo == NULL) {
1146			smb_browser_infofree();
1147			(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1148			return (-1);
1149		}
1150
1151		hinfo->hi_nic = ni.ni_nic;
1152		/* One Minute announcements for first five */
1153		hinfo->hi_nextannouce = 1;
1154		hinfo->hi_interval = 1;
1155		hinfo->hi_reps = 5;
1156		hinfo->hi_updatecnt = 0;
1157		hinfo->hi_type = type;
1158		hinfo->hi_version = version;
1159
1160		/* This is the name used for HostAnnouncement */
1161		(void) strlcpy(hinfo->hi_nbname, hinfo->hi_nic.nic_host,
1162		    NETBIOS_NAME_SZ);
1163		(void) smb_strupr(hinfo->hi_nbname);
1164		/* 0x20: file server service  */
1165		smb_init_name_struct((unsigned char *)hinfo->hi_nbname,
1166		    NBT_SERVER, 0, hinfo->hi_nic.nic_ip.a_ipv4,
1167		    htons(IPPORT_NETBIOS_DGM),
1168		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL,
1169		    &hinfo->hi_netname);
1170
1171		list_insert_tail(&smb_binfo.bi_hlist, hinfo);
1172		smb_binfo.bi_hcnt++;
1173	} while (smb_nic_getnext(&ni) == SMB_NIC_SUCCESS);
1174
1175	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1176	return (0);
1177}
1178
1179/*
1180 * smb_browser_non_master_duties
1181 *
1182 * To advertise its presence, i.e. to publish itself as being available, a
1183 * non-browser server sends a HostAnnouncement browser frame. If the server
1184 * is a member of domain "D", this frame is sent to the NETBIOS unique name
1185 * D(1d) and mailslot "\\MAILSLOT\\BROWSE".
1186 */
1187static void
1188smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
1189{
1190	struct name_entry name;
1191	struct name_entry *dest;
1192	addr_entry_t addr;
1193	char resource_domain[SMB_PI_MAX_DOMAIN];
1194
1195	smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
1196	    remove, 0, NBT_MB);
1197	if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
1198		return;
1199
1200	(void) smb_strupr(resource_domain);
1201
1202	smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
1203	    0, 0, 0, 0, 0, &name);
1204
1205	if ((dest = smb_name_find_name(&name))) {
1206		addr = dest->addr_list;
1207		addr.forw = addr.back = &addr;
1208		smb_name_unlock_name(dest);
1209		smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
1210		    remove, &addr, NBT_MB);
1211	} else {
1212		smb_init_name_struct((unsigned char *)resource_domain,
1213		    NBT_DMB, 0, 0, 0, 0, 0, &name);
1214		if ((dest = smb_name_find_name(&name))) {
1215			addr = dest->addr_list;
1216			addr.forw = addr.back = &addr;
1217			smb_name_unlock_name(dest);
1218			smb_browser_send_HostAnnouncement(hinfo,
1219			    remove, hinfo->hi_interval, &addr, NBT_DMB);
1220		}
1221	}
1222
1223	/*
1224	 * One Minute announcements for first five
1225	 * minutes, one minute longer each round
1226	 * until 12 minutes and every 12 minutes
1227	 * thereafter.
1228	 */
1229	if (--hinfo->hi_reps == 0) {
1230		if (hinfo->hi_interval < 12)
1231			hinfo->hi_interval++;
1232
1233		hinfo->hi_reps = 1;
1234	}
1235
1236	hinfo->hi_nextannouce = hinfo->hi_interval;
1237}
1238
1239
1240/*
1241 * SMB NetBIOS Browser Service
1242 */
1243/*ARGSUSED*/
1244void *
1245smb_browser_service(void *arg)
1246{
1247	smb_hostinfo_t *hinfo;
1248
1249	smb_browser_infoinit();
1250	smb_browser_config();
1251
1252	smb_netbios_event(NETBIOS_EVENT_BROWSER_START);
1253
1254restart:
1255	do {
1256		(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1257		hinfo = list_head(&smb_binfo.bi_hlist);
1258
1259		while (hinfo) {
1260			if (--hinfo->hi_nextannouce > 0 ||
1261			    hinfo->hi_nic.nic_bcast == 0) {
1262				hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1263				continue;
1264			}
1265
1266			smb_browser_non_master_duties(hinfo, B_FALSE);
1267
1268			/* Check to see whether reconfig is needed */
1269			(void) mutex_lock(&smb_binfo.bi_mtx);
1270			if (smb_binfo.bi_changed) {
1271				smb_binfo.bi_changed = B_FALSE;
1272				(void) mutex_unlock(&smb_binfo.bi_mtx);
1273				(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1274				smb_browser_config();
1275				goto restart;
1276			}
1277			(void) mutex_unlock(&smb_binfo.bi_mtx);
1278
1279			hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1280		}
1281
1282		(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1283		smb_netbios_sleep(SECSPERMIN);	/* 1 minute */
1284	} while (smb_netbios_running());
1285
1286	smb_browser_infoterm();
1287	smb_netbios_event(NETBIOS_EVENT_BROWSER_STOP);
1288	return (0);
1289}
1290
1291/*
1292 * smb_browser_netlogon
1293 *
1294 * Sends SAMLOGON/NETLOGON request for all host/ips, except
1295 * aliases, to find a domain controller.
1296 *
1297 * The dc argument will be set if a DC is found.
1298 */
1299boolean_t
1300smb_browser_netlogon(char *domain, char *dc, uint32_t dc_len)
1301{
1302	smb_hostinfo_t *hinfo;
1303	boolean_t found = B_FALSE;
1304	timestruc_t to;
1305	int err;
1306
1307	(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1308	hinfo = list_head(&smb_binfo.bi_hlist);
1309	while (hinfo) {
1310		if ((hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS) == 0)
1311			smb_netlogon_request(&hinfo->hi_netname, domain);
1312		hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1313	}
1314	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1315
1316	bzero(dc, dc_len);
1317	to.tv_sec = 30;
1318	to.tv_nsec = 0;
1319	(void) mutex_lock(&ntdomain_mtx);
1320	while (ntdomain_info.n_ipaddr == 0) {
1321		err = cond_reltimedwait(&ntdomain_cv, &ntdomain_mtx, &to);
1322		if (err == ETIME)
1323			break;
1324	}
1325
1326	if (ntdomain_info.n_ipaddr != 0) {
1327		(void) strlcpy(dc, ntdomain_info.n_name, dc_len);
1328		found = B_TRUE;
1329	}
1330	(void) mutex_unlock(&ntdomain_mtx);
1331
1332	return (found);
1333}
1334
1335/*
1336 * smb_browser_infoinit
1337 *
1338 * This function is called only once when the browser starts
1339 * to initialize the global smb_binfo structure.
1340 */
1341static void
1342smb_browser_infoinit(void)
1343{
1344	(void) mutex_lock(&ntdomain_mtx);
1345	bzero(&ntdomain_info, sizeof (ntdomain_info));
1346	(void) mutex_unlock(&ntdomain_mtx);
1347
1348	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
1349	list_create(&smb_binfo.bi_hlist, sizeof (smb_hostinfo_t),
1350	    offsetof(smb_hostinfo_t, hi_lnd));
1351	smb_binfo.bi_hcnt = 0;
1352	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1353
1354	(void) mutex_lock(&smb_binfo.bi_mtx);
1355	smb_binfo.bi_changed = B_FALSE;
1356	(void) mutex_unlock(&smb_binfo.bi_mtx);
1357}
1358
1359/*
1360 * smb_browser_infoterm
1361 *
1362 * This function is called only once when the browser stops
1363 * to destroy the smb_binfo structure.
1364 */
1365static void
1366smb_browser_infoterm(void)
1367{
1368	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
1369	smb_browser_infofree();
1370	list_destroy(&smb_binfo.bi_hlist);
1371	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1372}
1373
1374/*
1375 * smb_browser_infofree
1376 *
1377 * Removes all the hostinfo structures from the browser list
1378 * and frees the allocated memory
1379 */
1380static void
1381smb_browser_infofree(void)
1382{
1383	smb_hostinfo_t *hinfo;
1384
1385	while ((hinfo = list_head(&smb_binfo.bi_hlist)) != NULL) {
1386		list_remove(&smb_binfo.bi_hlist, hinfo);
1387		free(hinfo);
1388	}
1389
1390	smb_binfo.bi_hcnt = 0;
1391}
1392