diff options
-rw-r--r-- | source3/libsmb/namequery.c | 46 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 10 | ||||
-rw-r--r-- | source3/nmbd/nmbd_browsesync.c | 6 | ||||
-rw-r--r-- | source3/nmbd/nmbd_elections.c | 6 | ||||
-rw-r--r-- | source3/nmbd/nmbd_incomingdgrams.c | 12 | ||||
-rw-r--r-- | source3/nmbd/nmbd_lmhosts.c | 16 | ||||
-rw-r--r-- | source3/nmbd/nmbd_processlogon.c | 24 | ||||
-rw-r--r-- | source3/nmbd/nmbd_sendannounce.c | 24 | ||||
-rw-r--r-- | source3/nmbd/nmbd_serverlistdb.c | 50 | ||||
-rw-r--r-- | source3/nmbd/nmbd_synclists.c | 31 | ||||
-rw-r--r-- | source3/nmbd/nmbd_winsserver.c | 86 |
11 files changed, 188 insertions, 123 deletions
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dde758b41c..f4f9f84b00 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -783,20 +783,25 @@ XFILE *startlmhosts(const char *fname) Parse the next line in the lmhosts file. *********************************************************/ -bool getlmhostsent(XFILE *fp, pstring name, int *name_type, +bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, struct sockaddr_storage *pss) { - pstring line; + char line[1024]; + + *pp_name = NULL; while(!x_feof(fp) && !x_ferror(fp)) { - pstring ip,flags,extra; + char ip[INET6_ADDRSTRLEN]; + fstring flags; + fstring extra; + fstring name; const char *ptr; char *ptr1; int count = 0; *name_type = -1; - if (!fgets_slash(line,sizeof(pstring),fp)) { + if (!fgets_slash(line,sizeof(line),fp)) { continue; } @@ -804,15 +809,15 @@ bool getlmhostsent(XFILE *fp, pstring name, int *name_type, continue; } - pstrcpy(ip,""); - pstrcpy(name,""); - pstrcpy(flags,""); + ip[0] = '\0'; + name[0] = '\0'; + flags[0] = '\0'; ptr = line; if (next_token(&ptr,ip ,NULL,sizeof(ip))) ++count; - if (next_token(&ptr,name ,NULL, sizeof(pstring))) + if (next_token(&ptr,name ,NULL, sizeof(name))) ++count; if (next_token(&ptr,flags,NULL, sizeof(flags))) ++count; @@ -864,6 +869,10 @@ bool getlmhostsent(XFILE *fp, pstring name, int *name_type, *(--ptr1) = '\0'; /* Truncate at the '#' */ } + *pp_name = talloc_strdup(ctx, name); + if (!*pp_name) { + return false; + } return true; } @@ -1135,10 +1144,11 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, */ XFILE *fp; - pstring lmhost_name; + char *lmhost_name = NULL; int name_type2; struct sockaddr_storage return_ss; NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + TALLOC_CTX *ctx = NULL; *return_iplist = NULL; *return_count = 0; @@ -1152,19 +1162,30 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, if ( fp == NULL ) return NT_STATUS_NO_SUCH_FILE; - while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ss)) { + ctx = talloc_init("resolve_lmhosts"); + if (!ctx) { + endlmhosts(fp); + return NT_STATUS_NO_MEMORY; + } + + while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { - if (!strequal(name, lmhost_name)) + if (!strequal(name, lmhost_name)) { + TALLOC_FREE(lmhost_name); continue; + } - if ((name_type2 != -1) && (name_type != name_type2)) + if ((name_type2 != -1) && (name_type != name_type2)) { + TALLOC_FREE(lmhost_name); continue; + } *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service, (*return_count)+1); if ((*return_iplist) == NULL) { + TALLOC_FREE(ctx); endlmhosts(fp); DEBUG(3,("resolve_lmhosts: malloc fail !\n")); return NT_STATUS_NO_MEMORY; @@ -1182,6 +1203,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, break; } + TALLOC_FREE(ctx); endlmhosts(fp); return status; } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index beb178e59c..17e56b0756 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -287,8 +287,7 @@ static bool reload_nmbd_services(bool test) set_remote_machine_name("nmbd", False); if ( lp_loaded() ) { - pstring fname; - pstrcpy( fname,lp_configfile()); + const char *fname = lp_configfile(); if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE,fname); test = False; @@ -710,7 +709,6 @@ static bool open_sockets(bool isdaemon, int port) static bool Fork = true; static bool no_process_group; static bool log_stdout; - pstring logfile; poptContext pc; static char *p_lmhosts = dyn_LMHOSTSFILE; int opt; @@ -773,8 +771,12 @@ static bool open_sockets(bool isdaemon, int port) sys_srandom(time(NULL) ^ sys_getpid()); if (!override_logfile) { - slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE); + char *logfile = NULL; + if (asprintf(&logfile, "%s/log.nmbd", dyn_LOGFILEBASE) < 0) { + exit(1); + } lp_set_logfile(logfile); + SAFE_FREE(logfile); } fault_setup((void (*)(void *))fault_continue ); diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c index 4effce0722..b630fd234d 100644 --- a/source3/nmbd/nmbd_browsesync.c +++ b/source3/nmbd/nmbd_browsesync.c @@ -98,7 +98,7 @@ 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; + char outbuf[1024]; unstring myname; unstring dmb_name; char *p; @@ -122,7 +122,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_ strupper_m(myname); 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(outbuf,sizeof(outbuf),p); @@ -136,7 +136,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_ /* 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, dmb_name, 0x0, + global_myname(), 0x0, dmb_name, 0x0, work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT); } diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index db32461f06..bafe87c044 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -32,7 +32,7 @@ extern time_t StartupTime; static void send_election_dgram(struct subnet_record *subrec, const char *workgroup_name, uint32 criterion, int timeup,const char *server_name) { - pstring outbuf; + char outbuf[1024]; unstring srv_name; char *p; @@ -51,9 +51,9 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr unstrcpy(srv_name, server_name); strupper_m(srv_name); /* The following call does UNIX -> DOS charset conversion. */ - pstrcpy_base(p, srv_name, outbuf); + push_ascii(p, srv_name, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE); p = skip_string(outbuf,sizeof(outbuf),p); - + send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf), global_myname(), 0, workgroup_name, 0x1e, diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index 9fe344c39b..c0aa385ff6 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -534,13 +534,13 @@ done: Send a backup list response. *****************************************************************************/ -static void send_backup_list_response(struct subnet_record *subrec, +static void send_backup_list_response(struct subnet_record *subrec, struct work_record *work, struct nmb_name *send_to_name, unsigned char max_number_requested, uint32 token, struct in_addr sendto_ip, int port) -{ +{ char outbuf[1024]; char *p, *countptr; unsigned int count = 0; @@ -554,9 +554,9 @@ static void send_backup_list_response(struct subnet_record *subrec, DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n", work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip))); - + p = outbuf; - + SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */ p++; @@ -565,13 +565,13 @@ static void send_backup_list_response(struct subnet_record *subrec, SIVAL(p,0,token); /* The sender's unique info. */ p += 4; - + /* We always return at least one name - our own. */ count = 1; unstrcpy(myname, global_myname()); strupper_m(myname); myname[15]='\0'; - push_pstring_base(p, myname, outbuf); + push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE); p = skip_string(outbuf,sizeof(outbuf),p); diff --git a/source3/nmbd/nmbd_lmhosts.c b/source3/nmbd/nmbd_lmhosts.c index 51e4858f32..75c03bb398 100644 --- a/source3/nmbd/nmbd_lmhosts.c +++ b/source3/nmbd/nmbd_lmhosts.c @@ -29,24 +29,27 @@ Load a lmhosts file. ****************************************************************************/ void load_lmhosts_file(const char *fname) -{ - pstring name; +{ + char *name = NULL; int name_type; struct sockaddr_storage ss; + TALLOC_CTX *ctx = talloc_init("load_lmhosts_file"); XFILE *fp = startlmhosts( fname ); if (!fp) { DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n", fname, strerror(errno))); + TALLOC_FREE(ctx); return; } - - while (getlmhostsent(fp, name, &name_type, &ss) ) { + + while (getlmhostsent(ctx, fp, &name, &name_type, &ss) ) { struct in_addr ipaddr; struct subnet_record *subrec = NULL; enum name_source source = LMHOSTS_NAME; if (ss.ss_family != AF_INET) { + TALLOC_FREE(name); continue; } @@ -58,7 +61,7 @@ void load_lmhosts_file(const char *fname) if(same_net_v4(ipaddr, subrec->bcast_ip, subrec->mask_ip)) break; } - + /* If none match add the name to the remote_broadcast_subnet. */ if(subrec == NULL) subrec = remote_broadcast_subnet; @@ -72,7 +75,8 @@ void load_lmhosts_file(const char *fname) (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr); } } - + + TALLOC_FREE(ctx); endlmhosts(fp); } diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 8cbb87355a..0ff0afd12d 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -39,9 +39,9 @@ void process_logon_packet(struct packet_struct *p, char *buf,int len, const char *mailslot) { struct dgram_packet *dgram = &p->packet.dgram; - pstring my_name; + fstring my_name; fstring reply_name; - pstring outbuf; + char outbuf[1024]; int code; uint16 token = 0; uint32 ntversion = 0; @@ -51,7 +51,7 @@ void process_logon_packet(struct packet_struct *p, char *buf,int len, bool short_request = False; char *getdc; char *uniuser; /* Unicode user name. */ - pstring ascuser; + fstring ascuser; char *unicomp; /* Unicode computer name. */ size_t size; struct sockaddr_storage ss; @@ -76,7 +76,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); return; } - pstrcpy(my_name, global_myname()); + fstrcpy(my_name, global_myname()); code = get_safe_SVAL(buf,len,buf,0,-1); DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code)); @@ -107,7 +107,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); } token = SVAL(q,3); - fstrcpy(reply_name,my_name); + fstrcpy(reply_name,my_name); pull_ascii_fstring(mach_str, machine); pull_ascii_fstring(user_str, user); @@ -237,12 +237,12 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); q = ALIGN2(q, outbuf); q += dos_PutUniCode(q, my_name, - sizeof(pstring) - PTR_DIFF(q, outbuf), + sizeof(outbuf) - PTR_DIFF(q, outbuf), True); /* PDC name */ q += dos_PutUniCode(q, lp_workgroup(), - sizeof(pstring) - PTR_DIFF(q, outbuf), + sizeof(outbuf) - PTR_DIFF(q, outbuf), True); /* Domain name*/ - if (sizeof(pstring) - PTR_DIFF(q, outbuf) < 8) { + if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) { return; } SIVAL(q, 0, 1); /* our nt version */ @@ -355,7 +355,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", * database. If it isn't then we let smbd send an appropriate error. * Let's ignore the SID. */ - pull_ucs2_pstring(ascuser, uniuser); + pull_ucs2_fstring(ascuser, uniuser); pull_ucs2_fstring(asccomp, unicomp); DEBUG(5,("process_logon_packet: SAMLOGON user %s\n", ascuser)); @@ -381,13 +381,13 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", q += 2; q += dos_PutUniCode(q, reply_name, - sizeof(pstring) - PTR_DIFF(q, outbuf), + sizeof(outbuf) - PTR_DIFF(q, outbuf), True); q += dos_PutUniCode(q, ascuser, - sizeof(pstring) - PTR_DIFF(q, outbuf), + sizeof(outbuf) - PTR_DIFF(q, outbuf), True); q += dos_PutUniCode(q, lp_workgroup(), - sizeof(pstring) - PTR_DIFF(q, outbuf), + sizeof(outbuf) - PTR_DIFF(q, outbuf), True); } #ifdef HAVE_ADS diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c index 56cd497568..73c875d248 100644 --- a/source3/nmbd/nmbd_sendannounce.c +++ b/source3/nmbd/nmbd_sendannounce.c @@ -457,7 +457,7 @@ void announce_remote(time_t t) char *s; const char *ptr; static time_t last_time = 0; - pstring s2; + fstring s2; struct in_addr addr; char *comment; int stype = lp_default_server_announce(); @@ -474,7 +474,7 @@ void announce_remote(time_t t) comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH); for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) { - /* The entries are of the form a.b.c.d/WORKGROUP with + /* The entries are of the form a.b.c.d/WORKGROUP with WORKGROUP being optional */ const char *wgroup; char *pwgroup; @@ -489,7 +489,7 @@ void announce_remote(time_t t) wgroup = pwgroup; (void)interpret_addr2(&addr,s2); - + /* Announce all our names including aliases */ /* Give the ip address as the address of our first broadcast subnet. */ @@ -518,20 +518,20 @@ void announce_remote(time_t t) **************************************************************************/ void browse_sync_remote(time_t t) -{ +{ char *s; const char *ptr; - static time_t last_time = 0; - pstring s2; + static time_t last_time = 0; + fstring s2; struct in_addr addr; struct work_record *work; - pstring outbuf; + char outbuf[1024]; char *p; unstring myname; - + if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; - + last_time = t; s = lp_remote_browse_sync(); @@ -548,12 +548,12 @@ void browse_sync_remote(time_t t) lp_workgroup(), FIRST_SUBNET->subnet_name )); return; } - + if(!AM_LOCAL_MASTER_BROWSER(work)) { DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name )); return; - } + } memset(outbuf,'\0',sizeof(outbuf)); p = outbuf; @@ -563,7 +563,7 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name )); unstrcpy(myname, global_myname()); strupper_m(myname); myname[15]='\0'; - push_pstring_base(p, myname, outbuf); + push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE); p = skip_string(outbuf,sizeof(outbuf),p); diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c index 5ac4888365..349c3f4df3 100644 --- a/source3/nmbd/nmbd_serverlistdb.c +++ b/source3/nmbd/nmbd_serverlistdb.c @@ -289,17 +289,19 @@ void write_browse_list_entry(XFILE *fp, const char *name, uint32 rec_type, } void write_browse_list(time_t t, bool force_write) -{ +{ struct subnet_record *subrec; struct work_record *work; struct server_record *servrec; - pstring fname,fnamenew; + char *fname; + char *fnamenew; uint32 stype; int i; XFILE *fp; bool list_changed = force_write; static time_t lasttime = 0; - + TALLOC_CTX *ctx = talloc_tos(); + /* Always dump if we're being told to by a signal. */ if(force_write == False) { if (!lasttime) @@ -311,7 +313,7 @@ void write_browse_list(time_t t, bool force_write) lasttime = t; dump_workgroups(force_write); - + for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) { if(subrec->work_changed) { list_changed = True; @@ -323,22 +325,32 @@ void write_browse_list(time_t t, bool force_write) return; updatecount++; - - pstrcpy(fname,lp_lockdir()); + + fname = talloc_strdup(ctx, lp_lockdir()); + if (!fname) { + return; + } trim_char(fname,'\0' ,'/'); - pstrcat(fname,"/"); - pstrcat(fname,SERVER_LIST); - pstrcpy(fnamenew,fname); - pstrcat(fnamenew,"."); - + fname = talloc_asprintf_append(fname, + "/%s", + SERVER_LIST); + if (!fname) { + return; + } + fnamenew = talloc_asprintf(ctx, "%s.", + fname); + if (!fnamenew) { + return; + } + fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644); - + if (!fp) { DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n", fnamenew,strerror(errno))); return; - } - + } + /* * Write out a record for our workgroup. Use the record from the first * subnet. @@ -355,7 +367,7 @@ void write_browse_list(time_t t, bool force_write) SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY, work->local_master_browser_name, work->work_group); - /* + /* * We need to do something special for our own names. * This is due to the fact that we may be a local master browser on * one of our broadcast subnets, and a domain master on the unicast @@ -378,7 +390,7 @@ void write_browse_list(time_t t, bool force_write) write_browse_list_entry(fp, my_netbios_names(i), stype, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_workgroup()); } - + for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) { subrec->work_changed = False; @@ -399,7 +411,7 @@ void write_browse_list(time_t t, bool force_write) /* We have already written our names here. */ if(is_myname(servrec->serv.name)) - continue; + continue; serv_type = write_this_server_name(subrec, work, servrec); if(serv_type) { @@ -409,8 +421,8 @@ void write_browse_list(time_t t, bool force_write) } } } - } - + } + x_fclose(fp); unlink(fname); chmod(fnamenew,0644); diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c index 300368cd60..8abf60c8ce 100644 --- a/source3/nmbd/nmbd_synclists.c +++ b/source3/nmbd/nmbd_synclists.c @@ -32,7 +32,7 @@ struct sync_record { struct sync_record *next, *prev; unstring workgroup; unstring server; - pstring fname; + char *fname; struct in_addr ip; pid_t pid; }; @@ -159,15 +159,18 @@ done: if (!s) goto done; ZERO_STRUCTP(s); - + unstrcpy(s->workgroup, work->work_group); unstrcpy(s->server, name); s->ip = ip; - slprintf(s->fname, sizeof(pstring)-1, - "%s/sync.%d", lp_lockdir(), counter++); + if (asprintf(&s->fname, "%s/sync.%d", lp_lockdir(), counter++) < 0) { + SAFE_FREE(s); + goto done; + } + /* Safe to use as 0 means no size change. */ all_string_sub(s->fname,"//", "/", 0); - + DLIST_ADD(syncs, s); /* the parent forks and returns, leaving the child to do the @@ -183,7 +186,7 @@ done: fp = x_fopen(s->fname,O_WRONLY|O_CREAT|O_TRUNC, 0644); if (!fp) { END_PROFILE(sync_browse_lists); - _exit(1); + _exit(1); } sync_child(name, nm_type, work->work_group, ip, local, servers, @@ -247,7 +250,7 @@ static void complete_one(struct sync_record *s, /* Create the server in the workgroup. */ create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment); } - + /********************************************************************** Read the completed sync info. **********************************************************************/ @@ -257,8 +260,8 @@ static void complete_sync(struct sync_record *s) XFILE *f; unstring server, type_str; unsigned type; - pstring comment; - pstring line; + fstring comment; + char line[1024]; const char *ptr; int count=0; @@ -266,12 +269,12 @@ static void complete_sync(struct sync_record *s) if (!f) return; - + while (!x_feof(f)) { - - if (!fgets_slash(line,sizeof(pstring),f)) + + if (!fgets_slash(line,sizeof(line),f)) continue; - + ptr = line; if (!next_token(&ptr,server,NULL,sizeof(server)) || @@ -309,7 +312,7 @@ void sync_check_completion(void) /* it has completed - grab the info */ complete_sync(s); DLIST_REMOVE(syncs, s); - ZERO_STRUCTP(s); + SAFE_FREE(s->fname); SAFE_FREE(s); } } diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index d4a2c8346e..88cc395af4 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -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,9 +601,11 @@ bool initialise_wins(void) } while (!x_feof(fp)) { - pstring name_str, ip_str, ttl_str, nb_flags_str; + fstring name_str; + char ip_str[1024]; + fstring ttl_str, nb_flags_str; unsigned int num_ips; - pstring name; + char *name; struct in_addr *ip_list; int type = 0; int nb_flags; @@ -608,9 +620,9 @@ bool initialise_wins(void) /* 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 == '#') continue; @@ -626,7 +638,7 @@ 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 @@ -673,10 +685,10 @@ bool initialise_wins(void) x_fclose(fp); return False; } - + /* Reset and re-parse the line. */ ptr = line; - next_token(&ptr,name_str,NULL,sizeof(name_str)); + next_token(&ptr,name_str,NULL,sizeof(name_str)); next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)); for(i = 0; i < num_ips; i++) { next_token(&ptr, ip_str, NULL, sizeof(ip_str)); @@ -694,19 +706,19 @@ bool initialise_wins(void) SAFE_FREE(ip_list); 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 +728,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)); @@ -2310,10 +2322,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; @@ -2342,28 +2355,37 @@ void wins_write_database(time_t t, bool background) } } - slprintf(fname,sizeof(fname)-1,"%s/%s", dyn_STATEDIR(), WINS_LIST); + if (asprintf(&fname, "%s/%s", dyn_STATEDIR(), WINS_LIST) < 0) { + 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(fname); + SAFE_FREE(fnamenew); + if (background) { _exit(0); } |