comparison usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c @ 10717:fe0545fc3cdd

6612607 CIFS ADS client should use ldap_sasl_interactive_bind_s API 6877755 smbd should not route stderr, stdout to /dev/null 6882701 Wrong error message for attempt to map local user to Windows group, or vice versa 6885105 Potential for deadlock in smb_node_set_delete_on_close() 6881928 smbd core generated when running a script to join domain, set abe properties 6885538 Reduce dependencies on libsmbrdr 6820325 cifs service can't start on multi vlan+ipmp configuration
author Alan Wright <amw@Sun.COM>
date Mon, 05 Oct 2009 11:03:34 -0700
parents 3569b6c7f56c
children 37e5dcdf36d3
comparison
equal deleted inserted replaced
10716:b17df522be57 10717:fe0545fc3cdd
21 /* 21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms. 23 * Use is subject to license terms.
24 */ 24 */
25 25
26 #include <sys/tzfile.h>
26 #include <errno.h> 27 #include <errno.h>
27 #include <stdlib.h> 28 #include <stdlib.h>
28 #include <stdio.h> 29 #include <stdio.h>
29 #include <unistd.h> 30 #include <unistd.h>
30 #include <syslog.h> 31 #include <syslog.h>
36 #include <sys/socket.h> 37 #include <sys/socket.h>
37 #include <arpa/inet.h> 38 #include <arpa/inet.h>
38 39
39 #include <smbsrv/libsmb.h> 40 #include <smbsrv/libsmb.h>
40 #include <smbsrv/libsmbns.h> 41 #include <smbsrv/libsmbns.h>
41
42 #include <smbsrv/cifs.h> 42 #include <smbsrv/cifs.h>
43 #include <smbsrv/mailslot.h> 43 #include <smbsrv/mailslot.h>
44
45 #include <smbns_browser.h> 44 #include <smbns_browser.h>
46 #include <smbns_netbios.h> 45 #include <smbns_netbios.h>
47 46
48 /* 47 /*
49 * ntdomain_info 48 * ntdomain_info
79 78
80 static int smb_browser_init(void); 79 static int smb_browser_init(void);
81 static void smb_browser_infoinit(void); 80 static void smb_browser_infoinit(void);
82 static void smb_browser_infoterm(void); 81 static void smb_browser_infoterm(void);
83 static void smb_browser_infofree(void); 82 static void smb_browser_infofree(void);
84
85
86 83
87 84
88 void 85 void
89 smb_browser_reconfig(void) 86 smb_browser_reconfig(void)
90 { 87 {
651 static int 648 static int
652 smb_browser_addr_of_subnet(struct name_entry *name, smb_hostinfo_t *hinfo, 649 smb_browser_addr_of_subnet(struct name_entry *name, smb_hostinfo_t *hinfo,
653 struct name_entry *result) 650 struct name_entry *result)
654 { 651 {
655 uint32_t ipaddr, mask, saddr; 652 uint32_t ipaddr, mask, saddr;
656 struct addr_entry *addr; 653 addr_entry_t *addr;
657 654
658 if (name == NULL) 655 if (name == NULL)
659 return (-1); 656 return (-1);
660 657
661 if (hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS) 658 if (hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS)
690 *result = *name; 687 *result = *name;
691 688
692 result->addr_list.sin.sin_family = AF_INET; 689 result->addr_list.sin.sin_family = AF_INET;
693 result->addr_list.sinlen = sizeof (result->addr_list.sin); 690 result->addr_list.sinlen = sizeof (result->addr_list.sin);
694 result->addr_list.sin.sin_addr.s_addr = bcast; 691 result->addr_list.sin.sin_addr.s_addr = bcast;
695 result->addr_list.sin.sin_port = htons(DGM_SRVC_UDP_PORT); 692 result->addr_list.sin.sin_port = htons(IPPORT_NETBIOS_DGM);
696 result->addr_list.forw = result->addr_list.back = &result->addr_list; 693 result->addr_list.forw = result->addr_list.back = &result->addr_list;
697 return (0); 694 return (0);
698 } 695 }
699 696
700 /* 697 /*
770 */ 767 */
771 768
772 static void 769 static void
773 smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo, 770 smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
774 uint32_t next_announcement, boolean_t remove, 771 uint32_t next_announcement, boolean_t remove,
775 struct addr_entry *addr, char suffix) 772 addr_entry_t *addr, char suffix)
776 { 773 {
777 smb_msgbuf_t mb; 774 smb_msgbuf_t mb;
778 int offset, announce_len, data_length; 775 int offset, announce_len, data_length;
779 struct name_entry dest_name; 776 struct name_entry dest_name;
780 unsigned char *buffer; 777 unsigned char *buffer;
799 dest_name.addr_list.forw = dest_name.addr_list.back = 796 dest_name.addr_list.forw = dest_name.addr_list.back =
800 &dest_name.addr_list; 797 &dest_name.addr_list;
801 } 798 }
802 799
803 /* give some extra room */ 800 /* give some extra room */
804 buffer = (unsigned char *)malloc(MAX_DATAGRAM_LENGTH * 2); 801 buffer = malloc(MAX_DATAGRAM_LENGTH * 2);
805 if (buffer == 0) { 802 if (buffer == NULL) {
806 syslog(LOG_ERR, "HostAnnouncement: resource shortage"); 803 syslog(LOG_DEBUG, "smb browser: HostAnnouncement: %m");
807 return; 804 return;
808 } 805 }
809 806
810 data_length = 1 + 1 + 4 + 16 + 1 + 1 + 4 + 4 + 807 data_length = 1 + 1 + 4 + 16 + 1 + 1 + 4 + 4 +
811 strlen(hinfo->hi_nic.nic_cmnt) + 1; 808 strlen(hinfo->hi_nic.nic_cmnt) + 1;
822 /* 819 /*
823 * A non-browser server SHOULD send a HostAnnouncement browser frame 820 * A non-browser server SHOULD send a HostAnnouncement browser frame
824 * specifying a type of 0 just prior to shutting down, to allow it to 821 * specifying a type of 0 just prior to shutting down, to allow it to
825 * quickly be removed from the list of available servers. 822 * quickly be removed from the list of available servers.
826 */ 823 */
827 if (remove || (nb_status.state & NETBIOS_SHUTTING_DOWN)) 824 if (remove || (!smb_netbios_running()))
828 type = 0; 825 type = 0;
829 else 826 else
830 type = hinfo->hi_type; 827 type = hinfo->hi_type;
831 828
832 smb_msgbuf_init(&mb, buffer + offset, MAX_DATAGRAM_LENGTH - offset, 0); 829 smb_msgbuf_init(&mb, buffer + offset, MAX_DATAGRAM_LENGTH - offset, 0);
858 uint32_t next_announcement; 855 uint32_t next_announcement;
859 uint32_t delay = random() % 29; /* in seconds */ 856 uint32_t delay = random() % 29; /* in seconds */
860 boolean_t h_found = B_FALSE; 857 boolean_t h_found = B_FALSE;
861 858
862 if (strcmp(mailbox, MAILSLOT_LANMAN) != 0) { 859 if (strcmp(mailbox, MAILSLOT_LANMAN) != 0) {
863 syslog(LOG_DEBUG, "smb_browse: Wrong Mailbox (%s)", mailbox); 860 syslog(LOG_DEBUG, "smb browser: wrong mailbox (%s)", mailbox);
864 return; 861 return;
865 } 862 }
866 863
867 (void) sleep(delay); 864 smb_netbios_sleep(delay);
868 865
869 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl); 866 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
870 hinfo = list_head(&smb_binfo.bi_hlist); 867 hinfo = list_head(&smb_binfo.bi_hlist);
871 while (hinfo) { 868 while (hinfo) {
872 if ((hinfo->hi_nic.nic_ip.a_ipv4 & 869 if ((hinfo->hi_nic.nic_ip.a_ipv4 &
880 } 877 }
881 878
882 if (h_found) { 879 if (h_found) {
883 next_announcement = hinfo->hi_nextannouce * 60 * 1000; 880 next_announcement = hinfo->hi_nextannouce * 60 * 1000;
884 smb_browser_send_HostAnnouncement(hinfo, next_announcement, 881 smb_browser_send_HostAnnouncement(hinfo, next_announcement,
885 B_FALSE, &datagram->src.addr_list, 0x1D); 882 B_FALSE, &datagram->src.addr_list, NBT_MB);
886 } 883 }
887 (void) rw_unlock(&smb_binfo.bi_hlist_rwl); 884 (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
888 } 885 }
889 886
890 void * 887 void *
913 char *mailbox; 910 char *mailbox;
914 unsigned char message_type; 911 unsigned char message_type;
915 unsigned char *data; 912 unsigned char *data;
916 int datalen; 913 int datalen;
917 914
918 syslog(LOG_DEBUG, "smb_browse: packet_received"); 915 syslog(LOG_DEBUG, "smb browser: packet received");
919 916
920 smb_msgbuf_init(&mb, datagram->data, datagram->data_length, 0); 917 smb_msgbuf_init(&mb, datagram->data, datagram->data_length, 0);
921 rc = smb_msgbuf_decode(&mb, "Mb27.bwwwwb.w6.wwwwb.wwwws", 918 rc = smb_msgbuf_decode(&mb, "Mb27.bwwwwb.w6.wwwwb.wwwws",
922 &command, /* Command */ 919 &command, /* Command */
923 &parameter_words, /* Count of parameter words */ 920 &parameter_words, /* Count of parameter words */
937 &setup_word_2, /* Setup word[2] */ 934 &setup_word_2, /* Setup word[2] */
938 &total_request_bytes, /* Total request bytes */ 935 &total_request_bytes, /* Total request bytes */
939 &mailbox); /* Mailbox address */ 936 &mailbox); /* Mailbox address */
940 937
941 if (rc < 0) { 938 if (rc < 0) {
942 syslog(LOG_ERR, "smb_browser_dispatch: decode error"); 939 syslog(LOG_ERR, "smb browser: decode error");
943 smb_msgbuf_term(&mb); 940 smb_msgbuf_term(&mb);
944 free(datagram); 941 free(datagram);
945 return (0); 942 return (0);
946 } 943 }
947 944
970 case ANNOUNCEMENT_REQUEST : 967 case ANNOUNCEMENT_REQUEST :
971 smb_browser_process_AnnouncementRequest(datagram, mailbox); 968 smb_browser_process_AnnouncementRequest(datagram, mailbox);
972 break; 969 break;
973 970
974 default: 971 default:
975 syslog(LOG_DEBUG, "smb_browse: invalid message_type(%d, %x)", 972 syslog(LOG_DEBUG, "smb browser: invalid message type(%d, %x)",
976 message_type, message_type); 973 message_type, message_type);
977 break; 974 break;
978 } 975 }
979 976
980 smb_msgbuf_term(&mb); 977 smb_msgbuf_term(&mb);
1062 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0) 1059 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
1063 return; 1060 return;
1064 (void) utf8_strupr(resource_domain); 1061 (void) utf8_strupr(resource_domain);
1065 1062
1066 /* domain<00> */ 1063 /* domain<00> */
1067 smb_init_name_struct((unsigned char *)resource_domain, 0x00, 1064 smb_init_name_struct((unsigned char *)resource_domain, NBT_WKSTA,
1068 0, 0, 0, 0, 0, &name); 1065 0, 0, 0, 0, 0, &name);
1069 entry = smb_name_find_name(&name); 1066 entry = smb_name_find_name(&name);
1070 smb_name_unlock_name(entry); 1067 smb_name_unlock_name(entry);
1071 1068
1072 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl); 1069 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1073 hinfo = list_head(&smb_binfo.bi_hlist); 1070 hinfo = list_head(&smb_binfo.bi_hlist);
1074 while (hinfo) { 1071 while (hinfo) {
1075 smb_init_name_struct((unsigned char *)resource_domain, 0x00, 0, 1072 smb_init_name_struct((unsigned char *)resource_domain,
1076 hinfo->hi_nic.nic_ip.a_ipv4, 1073 NBT_WKSTA, 0, hinfo->hi_nic.nic_ip.a_ipv4,
1077 htons(DGM_SRVC_UDP_PORT), NAME_ATTR_GROUP, 1074 htons(IPPORT_NETBIOS_DGM), NAME_ATTR_GROUP,
1078 NAME_ATTR_LOCAL, &name); 1075 NAME_ATTR_LOCAL, &name);
1079 (void) smb_name_add_name(&name); 1076 (void) smb_name_add_name(&name);
1080 1077
1081 hinfo = list_next(&smb_binfo.bi_hlist, hinfo); 1078 hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1082 } 1079 }
1083 (void) rw_unlock(&smb_binfo.bi_hlist_rwl); 1080 (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1084 1081
1085 /* All our local master browsers */ 1082 /* All our local master browsers */
1086 smb_init_name_struct((unsigned char *)resource_domain, 0x1D, 1083 smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
1087 0, 0, 0, 0, 0, &dest); 1084 0, 0, 0, 0, 0, &dest);
1088 entry = smb_name_find_name(&dest); 1085 entry = smb_name_find_name(&dest);
1089 1086
1090 if (entry) { 1087 if (entry) {
1091 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl); 1088 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1092 hinfo = list_head(&smb_binfo.bi_hlist); 1089 hinfo = list_head(&smb_binfo.bi_hlist);
1093 while (hinfo) { 1090 while (hinfo) {
1094 rc = smb_browser_addr_of_subnet(entry, hinfo, &master); 1091 rc = smb_browser_addr_of_subnet(entry, hinfo, &master);
1095 if (rc == 0) { 1092 if (rc == 0) {
1096 syslog(LOG_DEBUG, 1093 syslog(LOG_DEBUG,
1097 "smbd: Master browser found at %s", 1094 "smb browser: master browser found at %s",
1098 inet_ntoa(master.addr_list.sin.sin_addr)); 1095 inet_ntoa(master.addr_list.sin.sin_addr));
1099 } 1096 }
1100 hinfo = list_next(&smb_binfo.bi_hlist, hinfo); 1097 hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1101 } 1098 }
1102 (void) rw_unlock(&smb_binfo.bi_hlist_rwl); 1099 (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1104 smb_name_unlock_name(entry); 1101 smb_name_unlock_name(entry);
1105 } 1102 }
1106 1103
1107 /* Domain master browser */ 1104 /* Domain master browser */
1108 smb_init_name_struct((unsigned char *)resource_domain, 1105 smb_init_name_struct((unsigned char *)resource_domain,
1109 0x1B, 0, 0, 0, 0, 0, &dest); 1106 NBT_DMB, 0, 0, 0, 0, 0, &dest);
1110 1107
1111 if ((entry = smb_name_find_name(&dest)) != 0) { 1108 if ((entry = smb_name_find_name(&dest)) != 0) {
1112 syslog(LOG_DEBUG, "smbd: Domain Master browser for %s is %s", 1109 syslog(LOG_DEBUG,
1110 "smb browser: domain master browser for %s is %s",
1113 resource_domain, 1111 resource_domain,
1114 inet_ntoa(entry->addr_list.sin.sin_addr)); 1112 inet_ntoa(entry->addr_list.sin.sin_addr));
1115 smb_name_unlock_name(entry); 1113 smb_name_unlock_name(entry);
1116 } 1114 }
1117 } 1115 }
1159 (void) strlcpy(hinfo->hi_nbname, hinfo->hi_nic.nic_host, 1157 (void) strlcpy(hinfo->hi_nbname, hinfo->hi_nic.nic_host,
1160 NETBIOS_NAME_SZ); 1158 NETBIOS_NAME_SZ);
1161 (void) utf8_strupr(hinfo->hi_nbname); 1159 (void) utf8_strupr(hinfo->hi_nbname);
1162 /* 0x20: file server service */ 1160 /* 0x20: file server service */
1163 smb_init_name_struct((unsigned char *)hinfo->hi_nbname, 1161 smb_init_name_struct((unsigned char *)hinfo->hi_nbname,
1164 0x20, 0, hinfo->hi_nic.nic_ip.a_ipv4, 1162 NBT_SERVER, 0, hinfo->hi_nic.nic_ip.a_ipv4,
1165 htons(DGM_SRVC_UDP_PORT), NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, 1163 htons(IPPORT_NETBIOS_DGM),
1164 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL,
1166 &hinfo->hi_netname); 1165 &hinfo->hi_netname);
1167 1166
1168 list_insert_tail(&smb_binfo.bi_hlist, hinfo); 1167 list_insert_tail(&smb_binfo.bi_hlist, hinfo);
1169 smb_binfo.bi_hcnt++; 1168 smb_binfo.bi_hcnt++;
1170 } while (smb_nic_getnext(&ni) == 0); 1169 } while (smb_nic_getnext(&ni) == 0);
1184 static void 1183 static void
1185 smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove) 1184 smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
1186 { 1185 {
1187 struct name_entry name; 1186 struct name_entry name;
1188 struct name_entry *dest; 1187 struct name_entry *dest;
1189 struct addr_entry addr; 1188 addr_entry_t addr;
1190 char resource_domain[SMB_PI_MAX_DOMAIN]; 1189 char resource_domain[SMB_PI_MAX_DOMAIN];
1191 1190
1192 smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval, 1191 smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
1193 remove, 0, 0x1D); 1192 remove, 0, NBT_MB);
1194 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0) 1193 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
1195 return; 1194 return;
1196 1195
1197 (void) utf8_strupr(resource_domain); 1196 (void) utf8_strupr(resource_domain);
1198 1197
1199 smb_init_name_struct((unsigned char *)resource_domain, 0x1D, 1198 smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
1200 0, 0, 0, 0, 0, &name); 1199 0, 0, 0, 0, 0, &name);
1201 1200
1202 if ((dest = smb_name_find_name(&name))) { 1201 if ((dest = smb_name_find_name(&name))) {
1203 addr = dest->addr_list; 1202 addr = dest->addr_list;
1204 addr.forw = addr.back = &addr; 1203 addr.forw = addr.back = &addr;
1205 smb_name_unlock_name(dest); 1204 smb_name_unlock_name(dest);
1206 smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval, 1205 smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
1207 remove, &addr, 0x1D); 1206 remove, &addr, NBT_MB);
1208 } else { 1207 } else {
1209 smb_init_name_struct((unsigned char *)resource_domain, 0x1B, 1208 smb_init_name_struct((unsigned char *)resource_domain,
1210 0, 0, 0, 0, 0, &name); 1209 NBT_DMB, 0, 0, 0, 0, 0, &name);
1211 if ((dest = smb_name_find_name(&name))) { 1210 if ((dest = smb_name_find_name(&name))) {
1212 addr = dest->addr_list; 1211 addr = dest->addr_list;
1213 addr.forw = addr.back = &addr; 1212 addr.forw = addr.back = &addr;
1214 smb_name_unlock_name(dest); 1213 smb_name_unlock_name(dest);
1215 smb_browser_send_HostAnnouncement(hinfo, 1214 smb_browser_send_HostAnnouncement(hinfo,
1216 remove, hinfo->hi_interval, &addr, 0x1B); 1215 remove, hinfo->hi_interval, &addr, NBT_DMB);
1217 } 1216 }
1218 } 1217 }
1219 1218
1220 /* 1219 /*
1221 * One Minute announcements for first five 1220 * One Minute announcements for first five
1233 hinfo->hi_nextannouce = hinfo->hi_interval; 1232 hinfo->hi_nextannouce = hinfo->hi_interval;
1234 } 1233 }
1235 1234
1236 1235
1237 /* 1236 /*
1238 * smb_browser_sleep 1237 * SMB NetBIOS Browser Service
1239 *
1240 * Put browser in 1 minute sleep if netbios services are not
1241 * shutting down and both name and datagram services are still
1242 * running. It'll wake up after 1 minute or if one of the above
1243 * conditions go false. It checks the conditions again and return
1244 * 1 if everything is ok or 0 if browser shouldn't continue
1245 * running.
1246 */
1247 static boolean_t
1248 smb_browser_sleep(void)
1249 {
1250 boolean_t slept = B_FALSE;
1251 timestruc_t to;
1252
1253 (void) mutex_lock(&nb_status.mtx);
1254 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) &&
1255 (nb_status.state & NETBIOS_NAME_SVC_RUNNING) &&
1256 (nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING)) {
1257
1258 if (slept) {
1259 (void) mutex_unlock(&nb_status.mtx);
1260 return (B_TRUE);
1261 }
1262
1263 to.tv_sec = 60; /* 1 minute */
1264 to.tv_nsec = 0;
1265 (void) cond_reltimedwait(&nb_status.cv, &nb_status.mtx, &to);
1266 slept = B_TRUE;
1267 }
1268 (void) mutex_unlock(&nb_status.mtx);
1269
1270 return (B_FALSE);
1271 }
1272
1273 /*
1274 * smb_browser_daemon
1275 *
1276 * Smb Netbios browser daemon.
1277 */ 1238 */
1278 /*ARGSUSED*/ 1239 /*ARGSUSED*/
1279 void * 1240 void *
1280 smb_browser_daemon(void *arg) 1241 smb_browser_service(void *arg)
1281 { 1242 {
1282 smb_hostinfo_t *hinfo; 1243 smb_hostinfo_t *hinfo;
1283 1244
1284 smb_browser_infoinit(); 1245 smb_browser_infoinit();
1285 smb_browser_config(); 1246 smb_browser_config();
1286 1247
1287 smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 1); 1248 smb_netbios_event(NETBIOS_EVENT_BROWSER_START);
1288 1249
1289 restart: 1250 restart:
1290 do { 1251 do {
1291 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl); 1252 (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
1292 hinfo = list_head(&smb_binfo.bi_hlist); 1253 hinfo = list_head(&smb_binfo.bi_hlist);
1254
1293 while (hinfo) { 1255 while (hinfo) {
1294 if (--hinfo->hi_nextannouce > 0 || 1256 if (--hinfo->hi_nextannouce > 0 ||
1295 hinfo->hi_nic.nic_bcast == 0) { 1257 hinfo->hi_nic.nic_bcast == 0) {
1296 hinfo = list_next(&smb_binfo.bi_hlist, hinfo); 1258 hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1297 continue; 1259 continue;
1310 } 1272 }
1311 (void) mutex_unlock(&smb_binfo.bi_mtx); 1273 (void) mutex_unlock(&smb_binfo.bi_mtx);
1312 1274
1313 hinfo = list_next(&smb_binfo.bi_hlist, hinfo); 1275 hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
1314 } 1276 }
1277
1315 (void) rw_unlock(&smb_binfo.bi_hlist_rwl); 1278 (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
1316 } while (smb_browser_sleep()); 1279 smb_netbios_sleep(SECSPERMIN); /* 1 minute */
1280 } while (smb_netbios_running());
1317 1281
1318 smb_browser_infoterm(); 1282 smb_browser_infoterm();
1319 smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 0); 1283 smb_netbios_event(NETBIOS_EVENT_BROWSER_STOP);
1320 return (0); 1284 return (0);
1321 } 1285 }
1322 1286
1323 /* 1287 /*
1324 * smb_browser_netlogon 1288 * smb_browser_netlogon
1365 } 1329 }
1366 1330
1367 /* 1331 /*
1368 * smb_browser_infoinit 1332 * smb_browser_infoinit
1369 * 1333 *
1370 * This function is called only once when browser daemon starts 1334 * This function is called only once when the browser starts
1371 * to initialize global smb_binfo structure 1335 * to initialize the global smb_binfo structure.
1372 */ 1336 */
1373 static void 1337 static void
1374 smb_browser_infoinit(void) 1338 smb_browser_infoinit(void)
1375 { 1339 {
1376 (void) mutex_lock(&ntdomain_mtx); 1340 (void) mutex_lock(&ntdomain_mtx);
1389 } 1353 }
1390 1354
1391 /* 1355 /*
1392 * smb_browser_infoterm 1356 * smb_browser_infoterm
1393 * 1357 *
1394 * This function is called only once when browser daemon stops 1358 * This function is called only once when the browser stops
1395 * to destruct smb_binfo structure 1359 * to destroy the smb_binfo structure.
1396 */ 1360 */
1397 static void 1361 static void
1398 smb_browser_infoterm(void) 1362 smb_browser_infoterm(void)
1399 { 1363 {
1400 (void) rw_wrlock(&smb_binfo.bi_hlist_rwl); 1364 (void) rw_wrlock(&smb_binfo.bi_hlist_rwl);