s3: nmbd: Stop nmbd network announce storm.
[samba.git] / source3 / nmbd / nmbd_sendannounce.c
index 4140040b2b8ccc0e1b9f6206ed4a4c16545fe7eb..a9cdf1c5a5833a8bd146ea084be9ed3cfc8fa75c 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "includes.h"
 #include "../librpc/gen_ndr/svcctl.h"
+#include "nmbd/nmbd.h"
 
 extern int  updatecount;
 extern bool found_lm_clients;
@@ -49,7 +50,7 @@ void send_browser_reset(int reset_type, const char *to_name, int to_type, struct
        p++;
 
        send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
-               global_myname(), 0x0, to_name, to_type, to_ip, 
+               lp_netbios_name(), 0x0, to_name, to_type, to_ip,
                FIRST_SUBNET->myip, DGRAM_PORT);
 }
 
@@ -75,10 +76,10 @@ to subnet %s\n", work->work_group, subrec->subnet_name));
 
        SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
        p++;
-       p +=  push_string_check(p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+       p +=  push_string_check(p+1, lp_netbios_name(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
   
        send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
-               global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip, 
+               lp_netbios_name(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
                subrec->myip, DGRAM_PORT);
 }
 
@@ -104,12 +105,15 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
        SCVAL(p,0,updatecount);
        SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
 
-       safe_strcpy(upper_server_name, server_name, sizeof(upper_server_name)-1);
-       strupper_m(upper_server_name);
+       strlcpy(upper_server_name, server_name ? server_name : "", sizeof(upper_server_name));
+       if (!strupper_m(upper_server_name)) {
+               DEBUG(2,("strupper_m %s failed\n", upper_server_name));
+               return;
+       }
        push_string_check(p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE);
 
-       SCVAL(p,21,lp_major_announce_version()); /* Major version. */
-       SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
+       SCVAL(p,21,SAMBA_MAJOR_NBT_ANNOUNCE_VERSION); /* Major version. */
+       SCVAL(p,22,SAMBA_MINOR_NBT_ANNOUNCE_VERSION); /* Minor version. */
 
        SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
        /* Browse version: got from NT/AS 4.00  - Value defined in smb.h (JHT). */
@@ -139,8 +143,8 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
 
        SSVAL(p,0,announce_type);
        SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
-       SCVAL(p,6,lp_major_announce_version()); /* Major version. */
-       SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
+       SCVAL(p,6,SAMBA_MAJOR_NBT_ANNOUNCE_VERSION); /* Major version. */
+       SCVAL(p,7,SAMBA_MINOR_NBT_ANNOUNCE_VERSION); /* Minor version. */
        SSVAL(p,8,announce_interval);            /* In seconds - according to spec. */
 
        p += 10;
@@ -160,17 +164,17 @@ static void send_local_master_announcement(struct subnet_record *subrec, struct
                                            struct server_record *servrec)
 {
        /* Ensure we don't have the prohibited bit set. */
-       uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+       uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 
        DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
-               type, global_myname(), subrec->subnet_name, work->work_group));
+               type, lp_netbios_name(), subrec->subnet_name, work->work_group));
 
        send_announcement(subrec, ANN_LocalMasterAnnouncement,
-                       global_myname(),                 /* From nbt name. */
+                       lp_netbios_name(),                 /* From nbt name. */
                        work->work_group, 0x1e,          /* To nbt name. */
                        subrec->bcast_ip,                /* To ip. */
                        work->announce_interval,         /* Time until next announce. */
-                       global_myname(),                 /* Name to announce. */
+                       lp_netbios_name(),                 /* Name to announce. */
                        type,                            /* Type field. */
                        servrec->serv.comment);
 }
@@ -185,13 +189,13 @@ static void send_workgroup_announcement(struct subnet_record *subrec, struct wor
                subrec->subnet_name, work->work_group));
 
        send_announcement(subrec, ANN_DomainAnnouncement,
-                       global_myname(),                 /* From nbt name. */
+                       lp_netbios_name(),                 /* From nbt name. */
                        MSBROWSE, 0x1,                   /* To nbt name. */
                        subrec->bcast_ip,                /* To ip. */
                        work->announce_interval,         /* Time until next announce. */
                        work->work_group,                /* Name to announce. */
                        SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT,  /* workgroup announce flags. */
-                       global_myname());                /* From name as comment. */
+                       lp_netbios_name());                /* From name as comment. */
 }
 
 /****************************************************************************
@@ -202,7 +206,7 @@ static void send_host_announcement(struct subnet_record *subrec, struct work_rec
                                    struct server_record *servrec)
 {
        /* Ensure we don't have the prohibited bits set. */
-       uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+       uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 
        DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
                type, servrec->serv.name, subrec->subnet_name, work->work_group));
@@ -225,7 +229,7 @@ static void send_lm_host_announcement(struct subnet_record *subrec, struct work_
                                    struct server_record *servrec, int lm_interval)
 {
        /* Ensure we don't have the prohibited bits set. */
-       uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+       uint32_t type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 
        DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
                type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
@@ -250,7 +254,7 @@ static void announce_server(struct subnet_record *subrec, struct work_record *wo
        /* Only do domain announcements if we are a master and it's
                our primary name we're being asked to announce. */
 
-       if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name)) {
+       if (AM_LOCAL_MASTER_BROWSER(work) && strequal(lp_netbios_name(),servrec->serv.name)) {
                send_local_master_announcement(subrec, work, servrec);
                send_workgroup_announcement(subrec, work);
        } else {
@@ -284,8 +288,10 @@ void announce_my_server_names(time_t t)
                        }
 
                        /* Announce every minute at first then progress to every 12 mins */
-                       if ((t - work->lastannounce_time) < work->announce_interval)
+                       if (t >= work->lastannounce_time &&
+                           (t - work->lastannounce_time) < work->announce_interval) {
                                continue;
+                       }
 
                        if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
                                work->announce_interval += 60;
@@ -469,11 +475,12 @@ void announce_remote(time_t t)
 
        last_time = t;
 
-       s = lp_remote_announce();
+       s = lp_remote_announce(talloc_tos());
        if (!*s)
                return;
 
-       comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
+       comment = string_truncate(lp_server_string(talloc_tos()),
+                                 MAX_SERVER_STRING_LENGTH);
 
        frame = talloc_stackframe();
        for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) {
@@ -539,7 +546,7 @@ void browse_sync_remote(time_t t)
 
        last_time = t;
 
-       s = lp_remote_browse_sync();
+       s = lp_remote_browse_sync(talloc_tos());
        if (!*s)
                return;
 
@@ -565,8 +572,11 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
        SCVAL(p,0,ANN_MasterAnnouncement);
        p++;
 
-       unstrcpy(myname, global_myname());
-       strupper_m(myname);
+       unstrcpy(myname, lp_netbios_name());
+       if (!strupper_m(myname)) {
+               DEBUG(2,("strupper_m %s failed\n", myname));
+               return;
+       }
        myname[15]='\0';
        push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
 
@@ -578,10 +588,10 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
                addr = interpret_addr2(s2);
 
                DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
-                       global_myname(), inet_ntoa(addr) ));
+                       lp_netbios_name(), inet_ntoa(addr) ));
 
                send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
-                       global_myname(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
+                       lp_netbios_name(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
        }
        TALLOC_FREE(frame);
 }