lib: Remove unused serverid.tdb
[samba.git] / source3 / nmbd / nmbd_browsesync.c
index 6cde88651f9cbd3f9877bf02242b674f08d0a79f..b1517f89c9f27a6941e4cef43cc981fff8caee01 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */
 
 #include "includes.h"
+#include "nmbd/nmbd.h"
 
 /* This is our local master browser list database. */
-extern ubi_dlList lmb_browserlist[];
+extern struct browse_cache_record *lmb_browserlist;
 
 /****************************************************************************
 As a domain master browser, do a sync with a local master browser.
@@ -87,9 +87,7 @@ void dmb_expire_and_sync_browser_lists(time_t t)
 
        expire_lmb_browsers(t);
 
-       for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
-                       browc;
-                       browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) {
+       for( browc = lmb_browserlist; browc; browc = browc->next ) {
                if (browc->sync_time < t)
                        sync_with_lmb(browc);
        }
@@ -101,11 +99,12 @@ As a local master browser, send an announce packet to the domain master browser.
 
 static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
 {
-       pstring outbuf;
-       fstring myname;
+       char outbuf[1024];
+       unstring myname;
+       unstring dmb_name;
        char *p;
 
-       if(ismyip(work->dmb_addr)) {
+       if(ismyip_v4(work->dmb_addr)) {
                if( DEBUGLVL( 2 ) ) {
                        dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
                        dbgtext( "We are both a domain and a local master browser for " );
@@ -120,13 +119,16 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
        SCVAL(p,0,ANN_MasterAnnouncement);
        p++;
 
-       fstrcpy(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';
        /* The call below does CH_UNIX -> CH_DOS conversion. JRA */
-       push_pstring_base(p, myname, outbuf);
+       push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
 
-       p = skip_string(p,1);
+       p = skip_string(outbuf,sizeof(outbuf),p);
 
        if( DEBUGLVL( 4 ) ) {
                dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
@@ -135,8 +137,10 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
                                        work->work_group );
        }
 
+       /* Target name for send_mailslot must be in UNIX charset. */
+       pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
        send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
-               global_myname(), 0x0, work->dmb_name.name, 0x0, 
+               lp_netbios_name(), 0x0, dmb_name, 0x0,
                work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
 }
 
@@ -146,7 +150,7 @@ As a local master browser, do a sync with a domain master browser.
 
 static void sync_with_dmb(struct work_record *work)
 {
-       nstring dmb_name;
+       unstring dmb_name;
 
        if( DEBUGLVL( 2 ) ) {
                dbgtext( "sync_with_dmb:\n" );
@@ -156,7 +160,7 @@ static void sync_with_dmb(struct work_record *work)
                dbgtext( "for workgroup %s\n", work->work_group );
        }
 
-       pull_ascii_nstring(dmb_name, work->dmb_name.name);
+       pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
        sync_browse_lists(work, dmb_name, work->dmb_name.name_type, 
                work->dmb_addr, False, True);
 }
@@ -190,18 +194,18 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
   /* Go through the list of names found at answers->rdata and look for
      the first SERVER<0x20> name. */
 
-       if(answers->rdata != NULL) {
+       if (answers->rdlength > 0) {
                char *p = answers->rdata;
                int numnames = CVAL(p, 0);
 
                p += 1;
 
                while (numnames--) {
-                       nstring qname;
-                       uint16 nb_flags;
+                       unstring qname;
+                       uint16_t nb_flags;
                        int name_type;
 
-                       pull_ascii_nstring(qname, p);
+                       pull_ascii_nstring(qname, sizeof(qname), p);
                        name_type = CVAL(p,15);
                        nb_flags = get_nb_flags(&p[16]);
                        trim_char(qname,'\0',' ');
@@ -278,9 +282,9 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
        struct nmb_name nmbname;
        struct userdata_struct *userdata;
        size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
-       nstring qname;
+       unstring qname;
 
-       pull_ascii_nstring(qname, q_name->name);
+       pull_ascii_nstring(qname, sizeof(qname), q_name->name);
        if( !(work = find_workgroup_on_subnet(subrec, qname)) ) {
                if( DEBUGLVL( 0 ) ) {
                        dbgtext( "find_domain_master_name_query_success:\n" );
@@ -291,7 +295,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
 
   /* First check if we already have a dmb for this workgroup. */
 
-       if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+       if(!is_zero_ip_v4(work->dmb_addr) && ip_equal_v4(work->dmb_addr, answer_ip)) {
                /* Do the local master browser announcement to the domain
                        master browser name and IP. */
                announce_local_master_browser_to_domain_master_browser( work );
@@ -300,7 +304,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
                sync_with_dmb(work);
                return;
        } else {
-               zero_ip(&work->dmb_addr);
+               zero_ip_v4(&work->dmb_addr);
        }
 
        /* Now initiate the node status request. */
@@ -321,7 +325,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
        /* Setup the userdata_struct - this is copied so we can use
        a stack variable for this. */
 
-       if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
+       if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) {
                DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
                return;
        }
@@ -329,7 +333,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
        userdata->copy_fn = NULL;
        userdata->free_fn = NULL;
        userdata->userdata_len = strlen(work->work_group)+1;
-       overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+       strlcpy(userdata->data, work->work_group, size - sizeof(*userdata));
 
        node_status( subrec, &nmbname, answer_ip, 
                domain_master_node_status_success,
@@ -398,8 +402,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
                                               struct res_rec *answers,
                                               struct in_addr from_ip)
 {
-       struct work_record *work;
-       fstring server_name;
+       unstring server_name;
 
        server_name[0] = 0;
 
@@ -413,18 +416,18 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
         * the first WORKGROUP<0x1b> name.
         */
 
-       if(answers->rdata != NULL) {
+       if (answers->rdlength > 0) {
                char *p = answers->rdata;
                int numnames = CVAL(p, 0);
 
                p += 1;
 
                while (numnames--) {
-                       nstring qname;
-                       uint16 nb_flags;
+                       unstring qname;
+                       uint16_t nb_flags;
                        int name_type;
 
-                       pull_ascii_nstring(qname, p);
+                       pull_ascii_nstring(qname, sizeof(qname), p);
                        name_type = CVAL(p,15);
                        nb_flags = get_nb_flags(&p[16]);
                        trim_char(qname,'\0',' ');
@@ -434,11 +437,13 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
                        if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && 
                                        server_name[0] == 0) {
                                /* this is almost certainly the server netbios name */
-                               fstrcpy(server_name, qname);
+                               strlcpy(server_name, qname, sizeof(server_name));
                                continue;
                        }
 
                        if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) {
+                               struct work_record *work;
+
                                if( DEBUGLVL( 5 ) ) {
                                        dbgtext( "get_domain_master_name_node_status_success:\n" );
                                        dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
@@ -451,16 +456,21 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
                                 * to the workgroup list on the unicast_subnet.
                                 */
 
-                               if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) {
+                               work = find_workgroup_on_subnet( subrec, qname);
+                               if (work == NULL) {
                                        struct nmb_name nmbname;
                                        /* 
                                         * Add it - with an hour in the cache.
                                         */
-                                       if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
+                                       work = create_workgroup_on_subnet(subrec, qname, 60*60);
+                                       if (work == NULL) {
                                                return;
+                                       }
 
                                        /* remember who the master is */
-                                       nstrcpy(work->local_master_browser_name, server_name);
+                                       strlcpy(work->local_master_browser_name,
+                                               server_name,
+                                               sizeof(work->local_master_browser_name));
                                        make_nmb_name(&nmbname, server_name, 0x20);
                                        work->dmb_name = nmbname;
                                        work->dmb_addr = from_ip;
@@ -468,7 +478,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
                                break;
                        }
                }
-       } else if( DEBUGLVL( 0 ) ) {
+       } else if( DEBUGLVL( 1 ) ) {
                dbgtext( "get_domain_master_name_node_status_success:\n" );
                dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
                dbgtext( "%s.\n", inet_ntoa(from_ip) );
@@ -482,7 +492,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
 static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
                        struct response_record *rrec)
 {
-       if( DEBUGLVL( 0 ) ) {
+       if( DEBUGLVL( 2 ) ) {
                dbgtext( "get_domain_master_name_node_status_fail:\n" );
                dbgtext( "Doing a node status request to the domain master browser " );
                dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
@@ -526,7 +536,7 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
                 * Don't send node status requests to ourself.
                 */
 
-               if(ismyip( send_ip )) {
+               if(ismyip_v4( send_ip )) {
                        if( DEBUGLVL( 5 ) ) {
                                dbgtext( "find_all_domain_master_names_query_succes:\n" );
                                dbgtext( "Not sending node status to our own IP " );
@@ -639,15 +649,20 @@ void sync_all_dmbs(time_t t)
      
        /* count how many syncs we might need to do */
        for (work=unicast_subnet->workgrouplist; work; work = work->next) {
-               if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) {
+               if (strcmp(lp_workgroup(), work->work_group)) {
                        count++;
                }
        }
 
+       /* leave if we don't have to do any syncs */
+       if (count == 0) {
+               return;
+       }
+
        /* sync with a probability of 1/count */
        for (work=unicast_subnet->workgrouplist; work; work = work->next) {
-               if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) {
-                       nstring dmb_name;
+               if (strcmp(lp_workgroup(), work->work_group)) {
+                       unstring dmb_name;
 
                        if (((unsigned)sys_random()) % count != 0)
                                continue;
@@ -662,7 +677,7 @@ void sync_all_dmbs(time_t t)
                                              0x20);
                        }
 
-                       pull_ascii_nstring(dmb_name, work->dmb_name.name);
+                       pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
 
                        DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
                                 dmb_name, inet_ntoa(work->dmb_addr)));