Home | History | Annotate | Download | only in common
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/tzfile.h>
     27 #include <errno.h>
     28 #include <stdlib.h>
     29 #include <stdio.h>
     30 #include <unistd.h>
     31 #include <syslog.h>
     32 #include <string.h>
     33 #include <strings.h>
     34 #include <time.h>
     35 #include <synch.h>
     36 #include <netdb.h>
     37 #include <sys/socket.h>
     38 #include <arpa/inet.h>
     39 
     40 #include <smbsrv/libsmb.h>
     41 #include <smbsrv/libsmbns.h>
     42 #include <smbsrv/smb.h>
     43 #include <smbsrv/mailslot.h>
     44 #include <smbns_browser.h>
     45 #include <smbns_netbios.h>
     46 
     47 /*
     48  * ntdomain_info
     49  * Temporary. It should be removed once NBTD is integrated.
     50  */
     51 smb_ntdomain_t ntdomain_info;
     52 mutex_t ntdomain_mtx;
     53 cond_t ntdomain_cv;
     54 
     55 #define	SMB_SERVER_SIGNATURE		0xaa550415
     56 
     57 typedef struct smb_hostinfo {
     58 	list_node_t	hi_lnd;
     59 	smb_nic_t	hi_nic;
     60 	char		hi_nbname[NETBIOS_NAME_SZ];
     61 	name_entry_t	hi_netname;
     62 	uint32_t	hi_nextannouce;
     63 	int		hi_reps;
     64 	int		hi_interval;
     65 	uint8_t		hi_updatecnt;
     66 	uint32_t	hi_type;
     67 } smb_hostinfo_t;
     68 
     69 typedef 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 
     77 static smb_browserinfo_t smb_binfo;
     78 
     79 static int smb_browser_init(void);
     80 static void smb_browser_infoinit(void);
     81 static void smb_browser_infoterm(void);
     82 static void smb_browser_infofree(void);
     83 
     84 
     85 void
     86 smb_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 
    596 int
    597 smb_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 
    648 static int
    649 smb_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 
    682 static int
    683 smb_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 
    769 static void
    770 smb_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 	    SMB_VERSION_MAJOR,
    837 	    SMB_VERSION_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 
    850 static void
    851 smb_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 
    887 void *
    888 smb_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 
   1045 static void
   1046 smb_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 
   1117 static int
   1118 smb_browser_init(void)
   1119 {
   1120 	smb_hostinfo_t *hinfo;
   1121 	smb_niciter_t ni;
   1122 	uint32_t type;
   1123 
   1124 	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
   1125 	smb_browser_infofree();
   1126 
   1127 	if (smb_nic_getfirst(&ni) != 0) {
   1128 		(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1129 		return (-1);
   1130 	}
   1131 
   1132 	type = MY_SERVER_TYPE;
   1133 	if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN)
   1134 		type |= SV_DOMAIN_MEMBER;
   1135 
   1136 	do {
   1137 		if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
   1138 		    (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS))
   1139 			continue;
   1140 
   1141 		hinfo = malloc(sizeof (smb_hostinfo_t));
   1142 		if (hinfo == NULL) {
   1143 			smb_browser_infofree();
   1144 			(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1145 			return (-1);
   1146 		}
   1147 
   1148 		hinfo->hi_nic = ni.ni_nic;
   1149 		/* One Minute announcements for first five */
   1150 		hinfo->hi_nextannouce = 1;
   1151 		hinfo->hi_interval = 1;
   1152 		hinfo->hi_reps = 5;
   1153 		hinfo->hi_updatecnt = 0;
   1154 		hinfo->hi_type = type;
   1155 
   1156 		/* This is the name used for HostAnnouncement */
   1157 		(void) strlcpy(hinfo->hi_nbname, hinfo->hi_nic.nic_host,
   1158 		    NETBIOS_NAME_SZ);
   1159 		(void) smb_strupr(hinfo->hi_nbname);
   1160 		/* 0x20: file server service  */
   1161 		smb_init_name_struct((unsigned char *)hinfo->hi_nbname,
   1162 		    NBT_SERVER, 0, hinfo->hi_nic.nic_ip.a_ipv4,
   1163 		    htons(IPPORT_NETBIOS_DGM),
   1164 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL,
   1165 		    &hinfo->hi_netname);
   1166 
   1167 		list_insert_tail(&smb_binfo.bi_hlist, hinfo);
   1168 		smb_binfo.bi_hcnt++;
   1169 	} while (smb_nic_getnext(&ni) == 0);
   1170 
   1171 	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1172 	return (0);
   1173 }
   1174 
   1175 /*
   1176  * smb_browser_non_master_duties
   1177  *
   1178  * To advertise its presence, i.e. to publish itself as being available, a
   1179  * non-browser server sends a HostAnnouncement browser frame. If the server
   1180  * is a member of domain "D", this frame is sent to the NETBIOS unique name
   1181  * D(1d) and mailslot "\\MAILSLOT\\BROWSE".
   1182  */
   1183 static void
   1184 smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
   1185 {
   1186 	struct name_entry name;
   1187 	struct name_entry *dest;
   1188 	addr_entry_t addr;
   1189 	char resource_domain[SMB_PI_MAX_DOMAIN];
   1190 
   1191 	smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
   1192 	    remove, 0, NBT_MB);
   1193 	if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
   1194 		return;
   1195 
   1196 	(void) smb_strupr(resource_domain);
   1197 
   1198 	smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
   1199 	    0, 0, 0, 0, 0, &name);
   1200 
   1201 	if ((dest = smb_name_find_name(&name))) {
   1202 		addr = dest->addr_list;
   1203 		addr.forw = addr.back = &addr;
   1204 		smb_name_unlock_name(dest);
   1205 		smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
   1206 		    remove, &addr, NBT_MB);
   1207 	} else {
   1208 		smb_init_name_struct((unsigned char *)resource_domain,
   1209 		    NBT_DMB, 0, 0, 0, 0, 0, &name);
   1210 		if ((dest = smb_name_find_name(&name))) {
   1211 			addr = dest->addr_list;
   1212 			addr.forw = addr.back = &addr;
   1213 			smb_name_unlock_name(dest);
   1214 			smb_browser_send_HostAnnouncement(hinfo,
   1215 			    remove, hinfo->hi_interval, &addr, NBT_DMB);
   1216 		}
   1217 	}
   1218 
   1219 	/*
   1220 	 * One Minute announcements for first five
   1221 	 * minutes, one minute longer each round
   1222 	 * until 12 minutes and every 12 minutes
   1223 	 * thereafter.
   1224 	 */
   1225 	if (--hinfo->hi_reps == 0) {
   1226 		if (hinfo->hi_interval < 12)
   1227 			hinfo->hi_interval++;
   1228 
   1229 		hinfo->hi_reps = 1;
   1230 	}
   1231 
   1232 	hinfo->hi_nextannouce = hinfo->hi_interval;
   1233 }
   1234 
   1235 
   1236 /*
   1237  * SMB NetBIOS Browser Service
   1238  */
   1239 /*ARGSUSED*/
   1240 void *
   1241 smb_browser_service(void *arg)
   1242 {
   1243 	smb_hostinfo_t *hinfo;
   1244 
   1245 	smb_browser_infoinit();
   1246 	smb_browser_config();
   1247 
   1248 	smb_netbios_event(NETBIOS_EVENT_BROWSER_START);
   1249 
   1250 restart:
   1251 	do {
   1252 		(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
   1253 		hinfo = list_head(&smb_binfo.bi_hlist);
   1254 
   1255 		while (hinfo) {
   1256 			if (--hinfo->hi_nextannouce > 0 ||
   1257 			    hinfo->hi_nic.nic_bcast == 0) {
   1258 				hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
   1259 				continue;
   1260 			}
   1261 
   1262 			smb_browser_non_master_duties(hinfo, B_FALSE);
   1263 
   1264 			/* Check to see whether reconfig is needed */
   1265 			(void) mutex_lock(&smb_binfo.bi_mtx);
   1266 			if (smb_binfo.bi_changed) {
   1267 				smb_binfo.bi_changed = B_FALSE;
   1268 				(void) mutex_unlock(&smb_binfo.bi_mtx);
   1269 				(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1270 				smb_browser_config();
   1271 				goto restart;
   1272 			}
   1273 			(void) mutex_unlock(&smb_binfo.bi_mtx);
   1274 
   1275 			hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
   1276 		}
   1277 
   1278 		(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1279 		smb_netbios_sleep(SECSPERMIN);	/* 1 minute */
   1280 	} while (smb_netbios_running());
   1281 
   1282 	smb_browser_infoterm();
   1283 	smb_netbios_event(NETBIOS_EVENT_BROWSER_STOP);
   1284 	return (0);
   1285 }
   1286 
   1287 /*
   1288  * smb_browser_netlogon
   1289  *
   1290  * Sends SAMLOGON/NETLOGON request for all host/ips, except
   1291  * aliases, to find a domain controller.
   1292  *
   1293  * The dc argument will be set if a DC is found.
   1294  */
   1295 boolean_t
   1296 smb_browser_netlogon(char *domain, char *dc, uint32_t dc_len)
   1297 {
   1298 	smb_hostinfo_t *hinfo;
   1299 	boolean_t found = B_FALSE;
   1300 	timestruc_t to;
   1301 	int err;
   1302 
   1303 	(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
   1304 	hinfo = list_head(&smb_binfo.bi_hlist);
   1305 	while (hinfo) {
   1306 		if ((hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS) == 0)
   1307 			smb_netlogon_request(&hinfo->hi_netname, domain);
   1308 		hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
   1309 	}
   1310 	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1311 
   1312 	bzero(dc, dc_len);
   1313 	to.tv_sec = 30;
   1314 	to.tv_nsec = 0;
   1315 	(void) mutex_lock(&ntdomain_mtx);
   1316 	while (ntdomain_info.n_ipaddr == 0) {
   1317 		err = cond_reltimedwait(&ntdomain_cv, &ntdomain_mtx, &to);
   1318 		if (err == ETIME)
   1319 			break;
   1320 	}
   1321 
   1322 	if (ntdomain_info.n_ipaddr != 0) {
   1323 		(void) strlcpy(dc, ntdomain_info.n_name, dc_len);
   1324 		found = B_TRUE;
   1325 	}
   1326 	(void) mutex_unlock(&ntdomain_mtx);
   1327 
   1328 	return (found);
   1329 }
   1330 
   1331 /*
   1332  * smb_browser_infoinit
   1333  *
   1334  * This function is called only once when the browser starts
   1335  * to initialize the global smb_binfo structure.
   1336  */
   1337 static void
   1338 smb_browser_infoinit(void)
   1339 {
   1340 	(void) mutex_lock(&ntdomain_mtx);
   1341 	bzero(&ntdomain_info, sizeof (ntdomain_info));
   1342 	(void) mutex_unlock(&ntdomain_mtx);
   1343 
   1344 	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
   1345 	list_create(&smb_binfo.bi_hlist, sizeof (smb_hostinfo_t),
   1346 	    offsetof(smb_hostinfo_t, hi_lnd));
   1347 	smb_binfo.bi_hcnt = 0;
   1348 	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1349 
   1350 	(void) mutex_lock(&smb_binfo.bi_mtx);
   1351 	smb_binfo.bi_changed = B_FALSE;
   1352 	(void) mutex_unlock(&smb_binfo.bi_mtx);
   1353 }
   1354 
   1355 /*
   1356  * smb_browser_infoterm
   1357  *
   1358  * This function is called only once when the browser stops
   1359  * to destroy the smb_binfo structure.
   1360  */
   1361 static void
   1362 smb_browser_infoterm(void)
   1363 {
   1364 	(void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
   1365 	smb_browser_infofree();
   1366 	list_destroy(&smb_binfo.bi_hlist);
   1367 	(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
   1368 }
   1369 
   1370 /*
   1371  * smb_browser_infofree
   1372  *
   1373  * Removes all the hostinfo structures from the browser list
   1374  * and frees the allocated memory
   1375  */
   1376 static void
   1377 smb_browser_infofree(void)
   1378 {
   1379 	smb_hostinfo_t *hinfo;
   1380 
   1381 	while ((hinfo = list_head(&smb_binfo.bi_hlist)) != NULL) {
   1382 		list_remove(&smb_binfo.bi_hlist, hinfo);
   1383 		free(hinfo);
   1384 	}
   1385 
   1386 	smb_binfo.bi_hcnt = 0;
   1387 }
   1388