Audit usage of get_dyn_STATEDIR() and replace with state_path()
[samba.git] / source3 / nmbd / nmbd_winsserver.c
index 736bbf4068e3fb96814b749759e8b3d90b4b0a8e..70118063b40828664cc801befeac45293ddd2308 100644 (file)
@@ -124,7 +124,7 @@ static struct name_record *wins_record_to_name_record(TDB_DATA key, TDB_DATA dat
        namerec->data.refresh_time = (time_t)refresh_time;
        namerec->data.id = id_low;
 #if defined(HAVE_LONGLONG)
-       namerec->data.id |= ((SMB_BIG_UINT)id_high << 32);
+       namerec->data.id |= ((uint64_t)id_high << 32);
 #endif
        namerec->data.wins_ip.s_addr = saddr;
        namerec->data.wins_flags = wins_flags,
@@ -412,14 +412,14 @@ static void update_wins_flag(struct name_record *namerec, int flags)
  Return the general ID value and increase it if requested.
 *****************************************************************************/
 
-static void get_global_id_and_update(SMB_BIG_UINT *current_id, bool update)
+static void get_global_id_and_update(uint64_t *current_id, bool update)
 {
        /*
         * it's kept as a static here, to prevent people from messing
         * with the value directly
         */
 
-       static SMB_BIG_UINT general_id = 1;
+       static uint64_t general_id = 1;
 
        DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
        
@@ -437,10 +437,11 @@ static void get_global_id_and_update(SMB_BIG_UINT *current_id, bool update)
 
 static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
 {
-       pstring command;
+       char *command = NULL;
        char *cmd = lp_wins_hook();
        char *p, *namestr;
        int i;
+       TALLOC_CTX *ctx = talloc_tos();
 
        wins_store_changed_namerec(namerec);
 
@@ -462,20 +463,29 @@ static void wins_hook(const char *operation, struct name_record *namerec, int tt
                *p = 0;
        }
 
-       p = command;
-       p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d", 
-                     cmd,
-                     operation, 
-                     namestr,
-                     namerec->name.name_type,
-                     ttl);
+       command = talloc_asprintf(ctx,
+                               "%s %s %s %02x %d",
+                               cmd,
+                               operation,
+                               namestr,
+                               namerec->name.name_type,
+                               ttl);
+       if (!command) {
+               return;
+       }
 
        for (i=0;i<namerec->data.num_ips;i++) {
-               p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
+               command = talloc_asprintf_append(command,
+                                               " %s",
+                                               inet_ntoa(namerec->data.ip[i]));
+               if (!command) {
+                       return;
+               }
        }
 
        DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
        smbrun(command, NULL);
+       TALLOC_FREE(command);
 }
 
 /****************************************************************************
@@ -566,7 +576,7 @@ bool initialise_wins(void)
 {
        time_t time_now = time(NULL);
        XFILE *fp;
-       pstring line;
+       char line[1024];
 
        if(!lp_we_are_a_wins_server()) {
                return True;
@@ -591,28 +601,33 @@ bool initialise_wins(void)
        }
 
        while (!x_feof(fp)) {
-               pstring name_str, ip_str, ttl_str, nb_flags_str;
+               char *name_str = NULL;
+               char *ip_str = NULL;
+               char *ttl_str = NULL, *nb_flags_str = NULL;
                unsigned int num_ips;
-               pstring name;
-               struct in_addr *ip_list;
+               char *name = NULL;
+               struct in_addr *ip_list = NULL;
                int type = 0;
                int nb_flags;
                int ttl;
                const char *ptr;
-               char *p;
+               char *p = NULL;
                bool got_token;
                bool was_ip;
                int i;
                unsigned int hash;
                int version;
+               TALLOC_CTX *frame = NULL;
 
                /* Read a line from the wins.dat file. Strips whitespace
                        from the beginning and end of the line.  */
-               if (!fgets_slash(line,sizeof(pstring),fp))
+               if (!fgets_slash(line,sizeof(line),fp)) {
                        continue;
-      
-               if (*line == '#')
+               }
+
+               if (*line == '#') {
                        continue;
+               }
 
                if (strncmp(line,"VERSION ", 8) == 0) {
                        if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
@@ -626,20 +641,23 @@ bool initialise_wins(void)
 
                ptr = line;
 
-               /* 
+               /*
                 * Now we handle multiple IP addresses per name we need
                 * to iterate over the line twice. The first time to
                 * determine how many IP addresses there are, the second
                 * time to actually parse them into the ip_list array.
                 */
 
-               if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
+               frame = talloc_stackframe();
+               if (!next_token_talloc(frame,&ptr,&name_str,NULL)) {
                        DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
+                       TALLOC_FREE(frame);
                        continue;
                }
 
-               if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
+               if (!next_token_talloc(frame,&ptr,&ttl_str,NULL)) {
                        DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
+                       TALLOC_FREE(frame);
                        continue;
                }
 
@@ -648,22 +666,24 @@ bool initialise_wins(void)
                 */
                num_ips = 0;
                do {
-                       got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
+                       got_token = next_token_talloc(frame,&ptr,&ip_str,NULL);
                        was_ip = False;
 
                        if(got_token && strchr(ip_str, '.')) {
                                num_ips++;
                                was_ip = True;
                        }
-               } while( got_token && was_ip);
+               } while(got_token && was_ip);
 
                if(num_ips == 0) {
                        DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
+                       TALLOC_FREE(frame);
                        continue;
                }
 
                if(!got_token) {
                        DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
+                       TALLOC_FREE(frame);
                        continue;
                }
 
@@ -671,20 +691,21 @@ bool initialise_wins(void)
                if((ip_list = SMB_MALLOC_ARRAY( struct in_addr, num_ips)) == NULL) {
                        DEBUG(0,("initialise_wins: Malloc fail !\n"));
                        x_fclose(fp);
+                       TALLOC_FREE(frame);
                        return False;
                }
+
                /* Reset and re-parse the line. */
                ptr = line;
-               next_token(&ptr,name_str,NULL,sizeof(name_str)); 
-               next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
+               next_token_talloc(frame,&ptr,&name_str,NULL);
+               next_token_talloc(frame,&ptr,&ttl_str,NULL);
                for(i = 0; i < num_ips; i++) {
-                       next_token(&ptr, ip_str, NULL, sizeof(ip_str));
-                       ip_list[i] = *interpret_addr2(ip_str);
+                       next_token_talloc(frame,&ptr, &ip_str, NULL);
+                       ip_list[i] = interpret_addr2(ip_str);
                }
-               next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
+               next_token_talloc(frame,&ptr,&nb_flags_str,NULL);
 
-               /* 
+               /*
                 * Deal with SELF or REGISTER name encoding. Default is REGISTER
                 * for compatibility with old nmbds.
                 */
@@ -692,21 +713,22 @@ bool initialise_wins(void)
                if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
                        DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
                        SAFE_FREE(ip_list);
+                       TALLOC_FREE(frame);
                        continue;
                }
-      
+
                if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') {
                        nb_flags_str[strlen(nb_flags_str)-1] = '\0';
                }
-      
+
                /* Netbios name. # divides the name from the type (hex): netbios#xx */
-               pstrcpy(name,name_str);
-      
+               name = name_str;
+
                if((p = strchr(name,'#')) != NULL) {
                        *p = 0;
                        sscanf(p+1,"%x",&type);
                }
-      
+
                /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
                sscanf(nb_flags_str,"%x",&nb_flags);
                sscanf(ttl_str,"%d",&ttl);
@@ -716,7 +738,7 @@ bool initialise_wins(void)
                        if(ttl != PERMANENT_TTL) {
                                ttl -= time_now;
                        }
-    
+
                        DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
                                name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
 
@@ -728,9 +750,10 @@ bool initialise_wins(void)
                                name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
                }
 
+               TALLOC_FREE(frame);
                SAFE_FREE(ip_list);
-       } 
-    
+       }
+
        x_fclose(fp);
        return True;
 }
@@ -810,8 +833,9 @@ void wins_process_name_refresh_request( struct subnet_record *subrec,
        struct name_record *namerec = NULL;
        int ttl = get_ttl_from_packet(nmb);
        struct in_addr from_ip;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        putip( (char *)&from_ip, &nmb->additional->rdata[2] );
 
        if(bcast) {
@@ -1116,8 +1140,9 @@ void wins_process_name_registration_request(struct subnet_record *subrec,
        struct name_record *namerec = NULL;
        struct in_addr from_ip;
        bool registering_group_name = (nb_flags & NB_GROUP) ? True : False;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        putip((char *)&from_ip,&nmb->additional->rdata[2]);
 
        if(bcast) {
@@ -1192,7 +1217,7 @@ to register name %s. Name already exists in WINS with source type %d.\n",
         */
 
        if(registering_group_name && (question->name_type != 0x1c)) {
-               from_ip = *interpret_addr2("255.255.255.255");
+               from_ip = interpret_addr2("255.255.255.255");
        }
 
        /*
@@ -1397,8 +1422,9 @@ static void wins_multihomed_register_query_success(struct subnet_record *subrec,
        struct name_record *namerec = NULL;
        struct in_addr from_ip;
        int ttl;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
 
        nmb = &orig_reg_packet->packet.nmb;
@@ -1486,9 +1512,10 @@ void wins_process_multihomed_name_registration_request( struct subnet_record *su
        struct name_record *namerec = NULL;
        struct in_addr from_ip;
        bool group = (nb_flags & NB_GROUP) ? True : False;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
        unstring qname;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        putip((char *)&from_ip,&nmb->additional->rdata[2]);
 
        if(bcast) {
@@ -2112,8 +2139,9 @@ static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA
        time_t t = *(time_t *)state;
        bool store_record = False;
        struct name_record *namerec = NULL;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        if (kbuf.dsize != sizeof(unstring) + 1) {
                return 0;
        }
@@ -2305,10 +2333,11 @@ static int wins_writedb_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA db
 void wins_write_database(time_t t, bool background)
 {
        static time_t last_write_time = 0;
-       pstring fname, fnamenew;
+       char *fname = NULL;
+       char *fnamenew = NULL;
 
        XFILE *fp;
-   
+
        if (background) {
                if (!last_write_time) {
                        last_write_time = t;
@@ -2337,28 +2366,37 @@ void wins_write_database(time_t t, bool background)
                }
        }
 
-       slprintf(fname,sizeof(fname)-1,"%s/%s", dyn_STATEDIR(), WINS_LIST);
+       if (!(fname = state_path(WINS_LIST))) {
+               goto err_exit;
+       }
+       /* This is safe as the 0 length means "don't expand". */
        all_string_sub(fname,"//", "/", 0);
-       slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
+
+       if (asprintf(&fnamenew, "%s.%u", fname, (unsigned int)sys_getpid()) < 0) {
+               goto err_exit;
+       }
 
        if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
                DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
-               if (background) {
-                       _exit(0);
-               }
-               return;
+               goto err_exit;
        }
 
        DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
 
        x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
+
        tdb_traverse(wins_tdb, wins_writedb_traverse_fn, fp);
 
        x_fclose(fp);
        chmod(fnamenew,0644);
        unlink(fname);
        rename(fnamenew,fname);
+
+  err_exit:
+
+       SAFE_FREE(fnamenew);
+       /* fname is talloced and doesn't need to be freed */
+
        if (background) {
                _exit(0);
        }
@@ -2381,9 +2419,10 @@ void nmbd_wins_new_entry(struct messaging_context *msg,
        struct name_record *new_namerec = NULL;
        struct nmb_name question;
        bool overwrite=False;
-       struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+       struct in_addr our_fake_ip;
        int i;
 
+       our_fake_ip = interpret_addr2("0.0.0.0");
        if (buf==NULL) {
                return;
        }