From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/client/clientutil.c | 21 +++--- source3/include/local.h | 2 + source3/lib/system.c | 4 +- source3/lib/time.c | 4 +- source3/lib/username.c | 4 +- source3/lib/util.c | 114 +++++++++++++++++++++-------- source3/libsmb/nmblib.c | 4 +- source3/locking/locking.c | 2 +- source3/nameannounce.c | 4 +- source3/namedbname.c | 8 +- source3/namedbsubnet.c | 4 +- source3/nameelect.c | 2 +- source3/namelogon.c | 6 +- source3/nmbd/nmbd.c | 22 +++--- source3/nmbsync.c | 4 +- source3/param/loadparm.c | 8 +- source3/printing/pcap.c | 4 +- source3/printing/printing.c | 36 ++++----- source3/smbd/chgpasswd.c | 12 +-- source3/smbd/dir.c | 2 +- source3/smbd/ipc.c | 29 +++++--- source3/smbd/mangle.c | 8 +- source3/smbd/message.c | 14 ++-- source3/smbd/pipes.c | 4 +- source3/smbd/reply.c | 175 +++++++++++++++++++++++++------------------- source3/smbd/server.c | 36 ++++----- source3/smbd/trans2.c | 28 ++++--- source3/smbd/vt_mode.c | 12 +-- source3/utils/nmblookup.c | 6 +- 29 files changed, 340 insertions(+), 239 deletions(-) (limited to 'source3') diff --git a/source3/client/clientutil.c b/source3/client/clientutil.c index 07c340ccac..d16e5a471f 100644 --- a/source3/client/clientutil.c +++ b/source3/client/clientutil.c @@ -171,7 +171,8 @@ BOOL cli_send_session_request(char *inbuf, char *outbuf) int len = 4; /* send a session request (RFC 8002) */ - strcpy(dest,desthost); + fstrcpy(dest,desthost); + p = strchr(dest,'.'); if (p) *p = 0; @@ -302,11 +303,11 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); } - strcpy(dev,"A:"); + pstrcpy(dev,"A:"); if (connect_as_printer) - strcpy(dev,"LPT1:"); + pstrcpy(dev,"LPT1:"); if (connect_as_ipc) - strcpy(dev,"IPC"); + pstrcpy(dev,"IPC"); if (start_session && !cli_send_session_request(inbuf,outbuf)) @@ -438,7 +439,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu { fstring pword; int passlen = strlen(pass)+1; - strcpy(pword,pass); + fstrcpy(pword,pass); if (doencrypt && *pass) { DEBUG(5,("Using encrypted passwords\n")); @@ -447,7 +448,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu } /* if in share level security then don't send a password now */ - if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;} + if (!(sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} /* send a session setup command */ bzero(outbuf,smb_size); @@ -553,7 +554,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu { int passlen = strlen(pass)+1; fstring pword; - strcpy(pword,pass); + fstrcpy(pword,pass); if (doencrypt && *pass) { passlen=24; @@ -562,7 +563,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu /* if in user level security then don't send a password now */ if ((sec_mode & 1)) { - strcpy(pword, ""); passlen=1; + fstrcpy(pword, ""); passlen=1; } set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True); @@ -811,9 +812,9 @@ BOOL cli_open_sockets(int port) } else { - strcpy(service2,service); + pstrcpy(service2,service); host = strtok(service2,"\\/"); - strcpy(desthost,host); + pstrcpy(desthost,host); } DEBUG(5,("Opening sockets\n")); diff --git a/source3/include/local.h b/source3/include/local.h index fc589d7ac0..9548bf74b6 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -42,6 +42,8 @@ #define WORDMAX 0xFFFF +/* the maximum password length before we declare a likely attack */ +#define MAX_PASSWORD_LENGTH 200 /* separators for lists */ #define LIST_SEP " \t,;:\n\r" diff --git a/source3/lib/system.c b/source3/lib/system.c index c539b25883..fe8e8004d0 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -310,8 +310,8 @@ int sys_rename(char *from, char *to) int rcode; pstring zfrom, zto; - strcpy (zfrom, dos_to_unix (from, False)); - strcpy (zto, dos_to_unix (to, False)); + pstrcpy (zfrom, dos_to_unix (from, False)); + pstrcpy (zto, dos_to_unix (to, False)); rcode = rename (zfrom, zto); if (errno == EXDEV) diff --git a/source3/lib/time.c b/source3/lib/time.c index d16552b61e..4f688d2214 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -469,12 +469,12 @@ BOOL set_filetime(char *fname,time_t mtime) ****************************************************************************/ char *timestring(void ) { - static char TimeBuf[100]; + static fstring TimeBuf; time_t t = time(NULL); struct tm *tm = LocalTime(&t); #ifdef NO_STRFTIME - strcpy(TimeBuf, asctime(tm)); + fstrcpy(TimeBuf, asctime(tm)); #elif defined(CLIX) || defined(CONVEX) strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",tm); #elif defined(AMPM) diff --git a/source3/lib/username.c b/source3/lib/username.c index a78a344eb8..a9f6425991 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -65,7 +65,7 @@ void map_username(char *user) if (strequal(user,last_from)) { DEBUG(3,("Mapped user %s to %s\n",user,last_to)); - strcpy(user,last_to); + fstrcpy(user,last_to); return; } @@ -191,7 +191,7 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change) if (ret) return(ret); if (allow_change) - strcpy(user,user2); + fstrcpy(user,user2); return(NULL); } diff --git a/source3/lib/util.c b/source3/lib/util.c index 812e59769e..8ffc11068a 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1117,7 +1117,7 @@ void unix_format(char *fname) if (*fname == '/') { - strcpy(namecopy,fname); + pstrcpy(namecopy,fname); strcpy(fname,"."); strcat(fname,namecopy); } @@ -1328,7 +1328,7 @@ void dos_clean_name(char *s) pstring s1; *p = 0; - strcpy(s1,p+3); + pstrcpy(s1,p+3); if ((p=strrchr(s,'\\')) != NULL) *p = 0; @@ -1366,7 +1366,7 @@ void unix_clean_name(char *s) pstring s1; *p = 0; - strcpy(s1,p+3); + pstrcpy(s1,p+3); if ((p=strrchr(s,'/')) != NULL) *p = 0; @@ -1393,7 +1393,7 @@ int ChDir(char *path) DEBUG(3,("chdir to %s\n",path)); res = sys_chdir(path); if (!res) - strcpy(LastDir,path); + pstrcpy(LastDir,path); return(res); } @@ -1553,7 +1553,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) /* remove any double slashes */ string_sub(s,"//","/"); - strcpy(basename,s); + pstrcpy(basename,s); p = strrchr(basename,'/'); if (!p) @@ -1623,12 +1623,12 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) if (relative) { if (newname[l] == '/') - strcpy(s,newname + l + 1); + pstrcpy(s,newname + l + 1); else - strcpy(s,newname+l); + pstrcpy(s,newname+l); } else - strcpy(s,newname); + pstrcpy(s,newname); } ChDir(wd); @@ -1652,10 +1652,10 @@ static void expand_one(char *Mask,int len) int lfill = (len+1) - strlen(Mask); int l1= (p1 - Mask); pstring tmp; - strcpy(tmp,Mask); + pstrcpy(tmp,Mask); memset(tmp+l1,'?',lfill); - strcpy(tmp + l1 + lfill,Mask + l1 + 1); - strcpy(Mask,tmp); + pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); + pstrcpy(Mask,tmp); } } @@ -1679,20 +1679,20 @@ void expand_mask(char *Mask,BOOL doext) filename_dos(Mask,filepart); - strcpy(mbeg,filepart); + pstrcpy(mbeg,filepart); if ((p1 = strchr(mbeg,'.')) != NULL) { hasdot = True; *p1 = 0; p1++; - strcpy(mext,p1); + pstrcpy(mext,p1); } else { strcpy(mext,""); if (strlen(mbeg) > 8) { - strcpy(mext,mbeg + 8); + pstrcpy(mext,mbeg + 8); mbeg[8] = 0; } } @@ -1710,7 +1710,7 @@ void expand_mask(char *Mask,BOOL doext) if (*mext) expand_one(mext,3); - strcpy(Mask,dirpart); + pstrcpy(Mask,dirpart); if (*dirpart || absolute) strcat(Mask,"\\"); strcat(Mask,mbeg); strcat(Mask,"."); @@ -1839,7 +1839,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode char *p; pstring mask2; - strcpy(mask2,mask); + pstrcpy(mask2,mask); if ((mode & aDIR) != 0) size = 0; @@ -2569,7 +2569,12 @@ BOOL string_init(char **dest,char *src) } else { - *dest = (char *)malloc(l+1); + (*dest) = (char *)malloc(l+1); + if ((*dest) == NULL) { + DEBUG(0,("Out of memory in string_init\n")); + return False; + } + strcpy(*dest,src); } return(True); @@ -2741,25 +2746,25 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); if (trans2) { - strcpy(ebase,p1); - strcpy(sbase,p2); + fstrcpy(ebase,p1); + fstrcpy(sbase,p2); } else { if ((p=strrchr(p1,'.'))) { *p = 0; - strcpy(ebase,p1); - strcpy(eext,p+1); + fstrcpy(ebase,p1); + fstrcpy(eext,p+1); } else { - strcpy(ebase,p1); + fstrcpy(ebase,p1); eext[0] = 0; } if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) { *p = 0; - strcpy(sbase,p2); - strcpy(sext,p+1); + fstrcpy(sbase,p2); + fstrcpy(sext,p+1); } else { - strcpy(sbase,p2); - strcpy(sext,""); + fstrcpy(sbase,p2); + fstrcpy(sext,""); } } @@ -3075,7 +3080,7 @@ BOOL get_myname(char *my_name,struct in_addr *ip) char *p = strchr(hostname,'.'); if (p) *p = 0; - strcpy(my_name,hostname); + fstrcpy(my_name,hostname); } if (ip) @@ -3443,7 +3448,7 @@ char *client_addr(void) return addr_buf; } - strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); global_client_addr_done = True; return addr_buf; @@ -3700,7 +3705,7 @@ char *readdirname(void *p) { static pstring buf; - strcpy(buf, dname); + pstrcpy(buf, dname); unix_to_dos(buf, True); dname = buf; } @@ -4055,3 +4060,54 @@ enum remote_arch_types get_remote_arch() { return ra_type; } + + +/******************************************************************* +safe string copy into a fstring +********************************************************************/ +void fstrcpy(char *dest, char *src) +{ + int maxlength = sizeof(fstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); + return; + } + + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", + strlen(src))); + } +} + +/******************************************************************* +safe string copy into a pstring +********************************************************************/ +void pstrcpy(char *dest, char *src) +{ + int maxlength = sizeof(pstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); + return; + } + + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", + strlen(src))); + } +} diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 456a8218d8..48f988de2a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -616,10 +616,10 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - strcpy(n->name,name); + fstrcpy(n->name,name); strupper(n->name); n->name_type = type; - strcpy(n->scope,this_scope); + fstrcpy(n->scope,this_scope); } diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7604676394..64f24fb242 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -108,7 +108,7 @@ BOOL start_share_mode_mgmt(void) { pstring shmem_file_name; - strcpy(shmem_file_name,lp_lockdir()); + pstrcpy(shmem_file_name,lp_lockdir()); if (!directory_exist(shmem_file_name,NULL)) mkdir(shmem_file_name,0755); trim_string(shmem_file_name,"","/"); diff --git a/source3/nameannounce.c b/source3/nameannounce.c index 96641c2d77..d3344ebd47 100644 --- a/source3/nameannounce.c +++ b/source3/nameannounce.c @@ -174,11 +174,11 @@ void do_announce_host(int command, SSVAL(p,27,BROWSER_ELECTION_VERSION); SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */ - strcpy(p+31,server_comment); + pstrcpy(p+31,server_comment); p += 31; p = skip_string(p,1); - debug_browse_data(outbuf, PTR_DIFF(p,outbuf)); + debug_browse_data(outbuf, PTR_DIFF(p,outbuf)); /* send the announcement */ send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf, diff --git a/source3/namedbname.c b/source3/namedbname.c index a45a749f14..51571d786a 100644 --- a/source3/namedbname.c +++ b/source3/namedbname.c @@ -226,11 +226,11 @@ void dump_names(void) if(lp_wins_support() == False || wins_subnet == 0) return; - strcpy(fname,lp_lockdir()); + fstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,WINS_LIST); - strcpy(fnamenew,fname); + fstrcpy(fnamenew,fname); strcat(fnamenew,"."); f = fopen(fnamenew,"w"); @@ -306,7 +306,7 @@ void load_netbios_names(void) if (!d) return; - strcpy(fname,lp_lockdir()); + fstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,WINS_LIST); @@ -366,7 +366,7 @@ void load_netbios_names(void) nb_flags_str[strlen(nb_flags_str)-1] = '\0'; /* netbios name. # divides the name from the type (hex): netbios#xx */ - strcpy(name,name_str); + pstrcpy(name,name_str); p = strchr(name,'#'); diff --git a/source3/namedbsubnet.c b/source3/namedbsubnet.c index 6364ebba54..4f0b647996 100644 --- a/source3/namedbsubnet.c +++ b/source3/namedbsubnet.c @@ -308,11 +308,11 @@ void write_browse_list(time_t t) dump_names(); dump_workgroups(); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,SERVER_LIST); - strcpy(fnamenew,fname); + pstrcpy(fnamenew,fname); strcat(fnamenew,"."); f = fopen(fnamenew,"w"); diff --git a/source3/nameelect.c b/source3/nameelect.c index 2ec3f505f8..5fd1a4bdf2 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -182,7 +182,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion, SIVAL(p,1,criterion); SIVAL(p,5,timeup*1000); /* ms - despite the spec */ p += 13; - strcpy(p,name); + pstrcpy(p,name); strupper(p); p = skip_string(p,1); diff --git a/source3/namelogon.c b/source3/namelogon.c index 1c118c8541..1f57139d56 100644 --- a/source3/namelogon.c +++ b/source3/namelogon.c @@ -74,7 +74,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) token = SVAL(tmp,3); reply_code = 0x6; - strcpy(reply_name,myname); + fstrcpy(reply_name,myname); strupper(reply_name); add_slashes = True; DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n", @@ -87,11 +87,11 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) logname = skip_string(machine,1); token = SVAL(skip_string(logname,1),0); - strcpy(reply_name,lp_domain_controller()); + fstrcpy(reply_name,lp_domain_controller()); if (!*reply_name) { /* oo! no domain controller. must be us, then */ - strcpy(reply_name,myname); + fstrcpy(reply_name,myname); reply_code = 0xC; } else diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 925f975ffe..3f0279908d 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -121,7 +121,7 @@ static BOOL dump_core(void) { char *p; pstring dname; - strcpy(dname,debugf); + pstrcpy(dname,debugf); if ((p=strrchr(dname,'/'))) *p=0; strcat(dname,"/corefiles"); mkdir(dname,0700); @@ -188,10 +188,10 @@ BOOL reload_services(BOOL test) if (lp_loaded()) { pstring fname; - strcpy(fname,lp_configfile()); + pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { - strcpy(servicesf,fname); + pstrcpy(servicesf,fname); test = False; } } @@ -276,7 +276,7 @@ static void load_hosts_file(char *fname) if (strchr(flags,'M')) { source = SELF; - strcpy(myname,name); + pstrcpy(myname,name); } ipaddr = *interpret_addr2(ip); @@ -371,7 +371,7 @@ static BOOL init_structs() pstring nbname; if (! *myname) { - strcpy(myname,myhostname); + fstrcpy(myname,myhostname); p = strchr(myname,'.'); if (p) *p = 0; } @@ -422,7 +422,7 @@ static BOOL init_structs() /* Terminate name list */ my_netbios_names[namecount++]=NULL; - strcpy(local_machine,myname); + fstrcpy(local_machine,myname); trim_string(local_machine," "," "); p = strchr(local_machine,' '); if (p) @@ -501,7 +501,7 @@ static void usage(char *pname) strncpy(pidFile, optarg, sizeof(pidFile)); break; case 's': - strcpy(servicesf,optarg); + pstrcpy(servicesf,optarg); break; case 'N': case 'B': @@ -511,17 +511,17 @@ static void usage(char *pname) DEBUG(0,("Obsolete option '%c' used\n",opt)); break; case 'H': - strcpy(host_file,optarg); + pstrcpy(host_file,optarg); break; case 'n': - strcpy(myname,optarg); + pstrcpy(myname,optarg); strupper(myname); break; case 'l': sprintf(debugf,"%s.nmb",optarg); break; case 'i': - strcpy(scope,optarg); + pstrcpy(scope,optarg); strupper(scope); break; case 'D': @@ -564,7 +564,7 @@ static void usage(char *pname) reload_services(True); - strcpy(myworkgroup, lp_workgroup()); + pstrcpy(myworkgroup, lp_workgroup()); if (strequal(myworkgroup,"*")) { DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n")); diff --git a/source3/nmbsync.c b/source3/nmbsync.c index f2161f631a..de2f7aa00f 100644 --- a/source3/nmbsync.c +++ b/source3/nmbsync.c @@ -82,7 +82,7 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv SIVAL(p,0,servertype); p += 4; - strcpy(p, work->work_group); + pstrcpy(p, work->work_group); p = skip_string(p,1); if (cli_call_api(PTR_DIFF(p,param),0, 8,BUFFER_SIZE - SAFETY_MARGIN, @@ -162,7 +162,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, name, work->work_group, inet_ntoa(ip))); strcpy(workgroup,work->work_group); - strcpy(desthost,name); + fstrcpy(desthost,name); dest_ip = ip; if (zero_ip(dest_ip)) return; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 9eb6bfab68..1a9771df22 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1381,7 +1381,7 @@ static void add_to_file_list(char *fname) { pstring n2; - strcpy(n2,fname); + pstrcpy(n2,fname); standard_sub_basic(n2); f->modtime = file_modtime(n2); } @@ -1401,7 +1401,7 @@ BOOL lp_file_list_changed(void) pstring n2; time_t mod_time; - strcpy(n2,f->name); + pstrcpy(n2,f->name); standard_sub_basic(n2); DEBUG(6,("file %s -> %s last mod_time: %s\n", @@ -1529,7 +1529,7 @@ handle the include operation static BOOL handle_include(char *pszParmValue,char **ptr) { pstring fname; - strcpy(fname,pszParmValue); + pstrcpy(fname,pszParmValue); add_to_file_list(fname); @@ -2127,7 +2127,7 @@ BOOL lp_load(char *pszFname,BOOL global_only) init_globals(); - strcpy(n2,pszFname); + pstrcpy(n2,pszFname); standard_sub_basic(n2); /* We get sections first, so have to start 'behind' to make up */ diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 549ebcd70d..65195ab1af 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -358,8 +358,8 @@ void pcap_printer_fn(void (*fn)()) if (strlen(p) <= 8 && strlen(p)>strlen(name) && !has_punctuation) { - if (!*comment) strcpy(comment,name); - strcpy(name,p); + if (!*comment) pstrcpy(comment,name); + pstrcpy(name,p); continue; } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c83d216989..51fd3a992e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -85,7 +85,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi strcat(filename,filename1); } else - strcpy(filename,filename1); + pstrcpy(filename,filename1); string_sub(syscmd, "%s", filename); } @@ -258,7 +258,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) if (p) { strcpy(tmp,p+1); - strcpy(tok[FILETOK],tmp); + fstrcpy(tok[FILETOK],tmp); } } @@ -404,8 +404,8 @@ A long spool-path will just waste significant chars of the file name. char *p = strrchr(tok[LPRNG_FILETOK],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[LPRNG_FILETOK],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[LPRNG_FILETOK],tmp); } } @@ -472,8 +472,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[2],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } } @@ -506,8 +506,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[4],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[4],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[4],tmp); } } @@ -666,8 +666,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) if ((p=strchr(tok[2],'!'))) { string tmp; - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } @@ -731,8 +731,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -795,8 +795,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -863,7 +863,7 @@ static BOOL parse_lpq_entry(int snum,char *line, /* change guest entries to the current logged in user to make them appear deletable to windows */ if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum))) - strcpy(buf->user,sesssetup_user); + pstrcpy(buf->user,sesssetup_user); } #endif @@ -940,7 +940,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, return(0); } - strcpy(syscmd,lpq_command); + pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); standard_sub(cnum,syscmd); @@ -1031,7 +1031,7 @@ void del_printqueue(int cnum,int snum,int jobid) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lprm_command); + pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); @@ -1069,7 +1069,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lpstatus_command); + pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 6063f2aac8..bed81138b2 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -212,8 +212,8 @@ static int expect(int master,char *expected,char *buf) { pstring s1,s2; - strcpy(s1,buf); - strcpy(s2,expected); + pstrcpy(s1,buf); + pstrcpy(s2,expected); if (do_match(s1, s2, False)) return(True); } @@ -364,11 +364,11 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass) } #if (defined(PASSWD_PROGRAM) && defined(PASSWD_CHAT)) - strcpy(passwordprogram,PASSWD_PROGRAM); - strcpy(chatsequence,PASSWD_CHAT); + pstrcpy(passwordprogram,PASSWD_PROGRAM); + pstrcpy(chatsequence,PASSWD_CHAT); #else - strcpy(passwordprogram,lp_passwd_program()); - strcpy(chatsequence,lp_passwd_chat()); + pstrcpy(passwordprogram,lp_passwd_program()); + pstrcpy(chatsequence,lp_passwd_chat()); #endif if (!*chatsequence) { diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 06ee6ae8ed..567bc14424 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -461,7 +461,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo matched = False; - strcpy(filename,dname); + pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || (name_map_mangle(filename,True,SNUM(cnum)) && diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index ced3a2009d..b9355c4ec0 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -774,7 +774,7 @@ static int get_server_info(uint32 servertype, pstring line; BOOL local_list_only; - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,SERVER_LIST); @@ -1363,7 +1363,7 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, fstring user; fstring pass1,pass2; - strcpy(user,p); + fstrcpy(user,p); p = skip_string(p,1); @@ -1698,14 +1698,14 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data, pstring comment; uint32 servertype= lp_default_server_announce(); - strcpy(comment,lp_serverstring()); + pstrcpy(comment,lp_serverstring()); if ((count=get_server_info(SV_TYPE_ALL,&servers,myworkgroup))>0) { for (i=0;i 0) { @@ -2043,9 +2043,9 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, strcpy(p2,"UserComment"); p2 = skip_string(p2,1); - /* EEK! the cifsrap.txt doesn't have this in!!!! */ + /* EEK! the cifsrap.txt doesn't have this in!!!! */ SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */ - strcpy(p2,vuser->real_name); /* simeon */ + strcpy(p2,vuser->real_name); /* simeon */ p2 = skip_string(p2,1); } @@ -2062,7 +2062,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, else { #if (defined(NETGROUP) && defined(AUTOMOUNT)) - strcpy(p2, vuser->home_share); + strcpy(p2, vuser->home_share); #else strcpy(p2,"\\\\%L\\%U"); #endif @@ -2469,7 +2469,8 @@ static void fill_printdest_info(int cnum, int snum, int uLevel, struct pack_desc* desc) { char buf[100]; - strcpy(buf,SERVICE(snum)); + strncpy(buf,SERVICE(snum),sizeof(buf)-1); + buf[sizeof(buf)-1] = 0; strupper(buf); if (uLevel <= 1) { PACKS(desc,"B9",buf); /* szName */ @@ -3026,7 +3027,11 @@ int reply_trans(char *inbuf,char *outbuf) int dsoff = SVAL(inbuf,smb_vwv12); int suwcnt = CVAL(inbuf,smb_vwv13); - StrnCpy(name,smb_buf(inbuf),sizeof(name)-1); + fstrcpy(name,smb_buf(inbuf)); + + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } if (tdscnt) { @@ -3088,6 +3093,10 @@ int reply_trans(char *inbuf,char *outbuf) pscnt += pcnt; dscnt += dcnt; + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } + if (pcnt) memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt); if (dcnt) diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index 3f753cf855..b0a45ffb47 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -273,7 +273,7 @@ BOOL check_mangled_stack(char *s) } if (check_extension && !strchr(mangled_stack[i],'.')) { - strcpy(tmpname,mangled_stack[i]); + pstrcpy(tmpname,mangled_stack[i]); strcat(tmpname,extension); mangle_name_83(tmpname); if (strequal(tmpname,s)) @@ -307,7 +307,7 @@ static char *map_filename(char *s, /* This is null terminated */ pstring pat; StrnCpy(pat, pattern, len); /* Get pattern into a proper string! */ - strcpy(matching_bit,""); /* Match but no star gets this. */ + pstrcpy(matching_bit,""); /* Match but no star gets this. */ pp = pat; /* Initialise the pointers. */ sp = s; if ((len == 1) && (*pattern == '*')) { @@ -446,7 +446,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) continue; /* Always check for the end. */ } if (*end == '*') { - strcpy(np, match_string); + pstrcpy(np, match_string); np += strlen(match_string); end++; /* Skip the '*' */ while ((*end) /* Not the end of string. */ @@ -460,7 +460,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) } *np++ = '\0'; /* NULL terminate it. */ DEBUG(5,("End of second in pair '%s'\n", end)); - strcpy(s, new_string); /* Substitute with the new name. */ + pstrcpy(s, new_string); /* Substitute with the new name. */ DEBUG(5,("s is now '%s'\n", s)); } start = end; /* Skip a bit which cannot be wanted */ diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 93a2d9d850..64253932ab 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -54,7 +54,7 @@ static void msg_deliver(void) /* put it in a temporary file */ sprintf(s,"%s/msg.XXXXXX",tmpdir()); - strcpy(name,(char *)mktemp(s)); + fstrcpy(name,(char *)mktemp(s)); fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600); if (fd == -1) { @@ -74,7 +74,7 @@ static void msg_deliver(void) /* run the command */ if (*lp_msg_command()) { - strcpy(s,lp_msg_command()); + pstrcpy(s,lp_msg_command()); string_sub(s,"%s",name); string_sub(s,"%f",msgfrom); string_sub(s,"%t",msgto); @@ -108,8 +108,8 @@ int reply_sends(char *inbuf,char *outbuf) dest = skip_string(orig,1)+1; msg = skip_string(dest,1)+1; - strcpy(msgfrom,orig); - strcpy(msgto,dest); + fstrcpy(msgfrom,orig); + fstrcpy(msgto,dest); len = SVAL(msg,0); len = MIN(len,1600-msgpos); @@ -143,10 +143,10 @@ int reply_sendstrt(char *inbuf,char *outbuf) orig = smb_buf(inbuf)+1; dest = skip_string(orig,1)+1; - strcpy(msgfrom,orig); - strcpy(msgto,dest); + fstrcpy(msgfrom,orig); + fstrcpy(msgto,dest); - DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),orig,dest)); + DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),msgfrom,msgto)); return(outsize); } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index afab7e1d91..feb8d91a5b 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -87,7 +87,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) BOOL bad_path = False; /* XXXX we need to handle passed times, sattr and flags */ - strcpy(fname,smb_buf(inbuf)); + pstrcpy(fname,smb_buf(inbuf)); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ @@ -98,7 +98,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(4,("Opening pipe %s.\n", fname)); /* Strip \PIPE\ off the name. */ - strcpy(fname,smb_buf(inbuf) + PIPELEN); + pstrcpy(fname,smb_buf(inbuf) + PIPELEN); /* See if it is one we want to handle. */ for( i = 0; known_pipes[i] ; i++ ) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8117685637..c1422bbcf6 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -48,6 +48,18 @@ a packet to ensure chaining works correctly */ #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) +/**************************************************************************** +report a possible attack via the password buffer overflow bug +****************************************************************************/ +static void overflow_attack(int len) +{ + DEBUG(0,("ERROR: Invalid password length %d\n", len)); + DEBUG(0,("you're machine may be under attack by a user exploiting an old bug\n")); + DEBUG(0,("Attack was from IP=%s\n", client_addr())); + exit_server("possible attack"); +} + + /**************************************************************************** reply to an special message ****************************************************************************/ @@ -66,36 +78,36 @@ int reply_special(char *inbuf,char *outbuf) smb_setlen(outbuf,0); switch (msg_type) { - case 0x81: /* session request */ - CVAL(outbuf,0) = 0x82; - CVAL(outbuf,3) = 0; - if (name_len(inbuf+4) > 50) { - DEBUG(0,("Invalid name length in session request\n")); - return(0); - } - name_extract(inbuf,4,name1); - name_extract(inbuf,4 + name_len(inbuf + 4),name2); + case 0x81: /* session request */ + CVAL(outbuf,0) = 0x82; + CVAL(outbuf,3) = 0; + if (name_len(inbuf+4) > 50 || name_len(inbuf+4 + name_len(inbuf + 4)) > 50) { + DEBUG(0,("Invalid name length in session request\n")); + return(0); + } + name_extract(inbuf,4,name1); + name_extract(inbuf,4 + name_len(inbuf + 4),name2); DEBUG(2,("netbios connect: name1=%s name2=%s\n", name1,name2)); - - strcpy(remote_machine,name2); - trim_string(remote_machine," "," "); - p = strchr(remote_machine,' '); - strlower(remote_machine); - if (p) *p = 0; - - strcpy(local_machine,name1); - trim_string(local_machine," "," "); - p = strchr(local_machine,' '); - strlower(local_machine); - if (p) *p = 0; - - add_session_user(remote_machine); - - reload_services(True); - reopen_logs(); - - break; + + fstrcpy(remote_machine,name2); + trim_string(remote_machine," "," "); + p = strchr(remote_machine,' '); + strlower(remote_machine); + if (p) *p = 0; + + fstrcpy(local_machine,name1); + trim_string(local_machine," "," "); + p = strchr(local_machine,' '); + strlower(local_machine); + if (p) *p = 0; + + add_session_user(remote_machine); + + reload_services(True); + reopen_logs(); + + break; case 0x89: /* session keepalive request (some old clients produce this?) */ @@ -160,25 +172,25 @@ static void parse_connect(char *p,char *service,char *user, p2 = strrchr(p,'\\'); if (p2 == NULL) - strcpy(service,p); + fstrcpy(service,p); else - strcpy(service,p2+1); + fstrcpy(service,p2+1); p += strlen(p) + 2; - strcpy(password,p); + fstrcpy(password,p); *pwlen = strlen(password); p += strlen(p) + 2; - strcpy(dev,p); + fstrcpy(dev,p); *user = 0; p = strchr(service,'%'); if (p != NULL) { *p = 0; - strcpy(user,p+1); + fstrcpy(user,p+1); } } @@ -238,6 +250,10 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* we might have to close an old one */ if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0) close_cnum(SVAL(inbuf,smb_tid),vuid); + + if (passlen > MAX_PASSWORD_LENGTH) { + overflow_attack(passlen); + } { char *path; @@ -252,18 +268,17 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) passlen = strlen(password); } - DEBUG(4,("parsing net-path %s, passlen=%d\n",path,passlen)); - strcpy(service,path+2); + fstrcpy(service,path+2); p = strchr(service,'\\'); if (!p) return(ERROR(ERRSRV,ERRinvnetname)); *p = 0; - strcpy(service,p+1); + fstrcpy(service,p+1); p = strchr(service,'%'); if (p) { *p++ = 0; - strcpy(user,p); + fstrcpy(user,p); } StrnCpy(devicename,path + strlen(path) + 1,6); DEBUG(4,("Got device type %s\n",devicename)); @@ -372,11 +387,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); + if (smb_apasslen > MAX_PASSWORD_LENGTH) + overflow_attack(smb_apasslen); + memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); - StrnCpy(user,smb_buf(inbuf)+smb_apasslen,sizeof(user)-1); + pstrcpy(user,smb_buf(inbuf)+smb_apasslen); - if (lp_security() != SEC_SERVER && !doencrypt) - smb_apasslen = strlen(smb_apasswd); + if (lp_security() != SEC_SERVER && !doencrypt) { + smb_apasslen = strlen(smb_apasswd); + } } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); uint16 passlen2 = SVAL(inbuf,smb_vwv8); @@ -401,6 +420,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 != 24 && passlen2 != 24) doencrypt = False; + if (passlen1 > MAX_PASSWORD_LENGTH) { + overflow_attack(passlen1); + } + + passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); + passlen2 = MIN(passlen2, MAX_PASSWORD_LENGTH); + if(doencrypt) { /* Save the lanman2 password and the NT md4 password. */ smb_apasslen = passlen1; @@ -438,7 +464,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) } p += passlen1 + passlen2; - strcpy(user,p); p = skip_string(p,1); + fstrcpy(user,p); p = skip_string(p,1); DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", p,skip_string(p,1),skip_string(p,2))); } @@ -591,7 +617,7 @@ int reply_chkpth(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf) + 1); + pstrcpy(name,smb_buf(inbuf) + 1); unix_convert(name,cnum,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); @@ -639,7 +665,7 @@ int reply_getatr(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(fname,smb_buf(inbuf) + 1); + pstrcpy(fname,smb_buf(inbuf) + 1); unix_convert(fname,cnum,0,&bad_path); /* dos smetimes asks for a stat of "" - it returns a "hidden directory" @@ -714,7 +740,7 @@ int reply_setatr(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(fname,smb_buf(inbuf) + 1); + pstrcpy(fname,smb_buf(inbuf) + 1); unix_convert(fname,cnum,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); @@ -825,8 +851,8 @@ int reply_search(char *inbuf,char *outbuf) { pstring dir2; - strcpy(directory,smb_buf(inbuf)+1); - strcpy(dir2,smb_buf(inbuf)+1); + pstrcpy(directory,smb_buf(inbuf)+1); + pstrcpy(dir2,smb_buf(inbuf)+1); unix_convert(directory,cnum,0,&bad_path); unix_format(dir2); @@ -842,7 +868,7 @@ int reply_search(char *inbuf,char *outbuf) else { *p = 0; - strcpy(mask,p+1); + pstrcpy(mask,p+1); } p = strrchr(directory,'/'); @@ -876,7 +902,7 @@ int reply_search(char *inbuf,char *outbuf) if ((p = strrchr(mask,' '))) { fstring ext; - strcpy(ext,p+1); + fstrcpy(ext,p+1); *p = 0; trim_string(mask,NULL," "); strcat(mask,"."); @@ -898,7 +924,7 @@ int reply_search(char *inbuf,char *outbuf) if (!strchr(mask,'.') && strlen(mask)>8) { fstring tmp; - strcpy(tmp,&mask[8]); + fstrcpy(tmp,&mask[8]); mask[8] = '.'; mask[9] = 0; strcat(mask,tmp); @@ -1078,7 +1104,7 @@ int reply_open(char *inbuf,char *outbuf) share_mode = SVAL(inbuf,smb_vwv0); - strcpy(fname,smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); unix_convert(fname,cnum,0,&bad_path); fnum = find_free_file(); @@ -1168,7 +1194,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* XXXX we need to handle passed times, sattr and flags */ - strcpy(fname,smb_buf(inbuf)); + pstrcpy(fname,smb_buf(inbuf)); unix_convert(fname,cnum,0,&bad_path); fnum = find_free_file(); @@ -1281,7 +1307,7 @@ int reply_mknew(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); - strcpy(fname,smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); unix_convert(fname,cnum,0,&bad_path); if (createmode & aVOLID) @@ -1359,7 +1385,8 @@ int reply_ctemp(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); - sprintf(fname,"%s/TMXXXXXX",smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); + strcat(fname,"/TMXXXXXX"); unix_convert(fname,cnum,0,&bad_path); unixmode = unix_mode(cnum,createmode); @@ -1455,7 +1482,7 @@ int reply_unlink(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); dirtype = SVAL(inbuf,smb_vwv0); - strcpy(name,smb_buf(inbuf) + 1); + pstrcpy(name,smb_buf(inbuf) + 1); DEBUG(3,("reply_unlink : %s\n",name)); @@ -1503,7 +1530,7 @@ int reply_unlink(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; @@ -2381,7 +2408,7 @@ int reply_printopen(char *inbuf,char *outbuf) { pstring s; char *p; - StrnCpy(s,smb_buf(inbuf)+1,sizeof(pstring)-1); + pstrcpy(s,smb_buf(inbuf)+1); p = s; while (*p) { @@ -2583,7 +2610,7 @@ int reply_mkdir(char *inbuf,char *outbuf) int outsize,ret= -1; BOOL bad_path = False; - strcpy(directory,smb_buf(inbuf) + 1); + pstrcpy(directory,smb_buf(inbuf) + 1); cnum = SVAL(inbuf,smb_tid); unix_convert(directory,cnum,0,&bad_path); @@ -2680,7 +2707,7 @@ int reply_rmdir(char *inbuf,char *outbuf) BOOL bad_path = False; cnum = SVAL(inbuf,smb_tid); - strcpy(directory,smb_buf(inbuf) + 1); + pstrcpy(directory,smb_buf(inbuf) + 1); unix_convert(directory,cnum,0,&bad_path); if (check_name(directory,cnum)) @@ -2728,7 +2755,7 @@ int reply_rmdir(char *inbuf,char *outbuf) errno = ENOMEM; break; } - strcpy(fullname, directory); + pstrcpy(fullname, directory); strcat(fullname, "/"); strcat(fullname, dname); @@ -2795,21 +2822,21 @@ static BOOL resolve_wildcards(char *name1,char *name2) if (!name1 || !name2) return(False); - strcpy(root1,name1); - strcpy(root2,name2); + fstrcpy(root1,name1); + fstrcpy(root2,name2); p = strrchr(root1,'.'); if (p) { *p = 0; - strcpy(ext1,p+1); + fstrcpy(ext1,p+1); } else { - strcpy(ext1,""); + fstrcpy(ext1,""); } p = strrchr(root2,'.'); if (p) { *p = 0; - strcpy(ext2,p+1); + fstrcpy(ext2,p+1); } else { - strcpy(ext2,""); + fstrcpy(ext2,""); } p = root1; @@ -2883,8 +2910,8 @@ int reply_mv(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf) + 1); - strcpy(newname,smb_buf(inbuf) + 3 + strlen(name)); + pstrcpy(name,smb_buf(inbuf) + 1); + pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name)); DEBUG(3,("reply_mv : %s -> %s\n",name,newname)); @@ -2998,14 +3025,14 @@ int reply_mv(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; error = ERRnoaccess; sprintf(fname,"%s/%s",directory,dname); if (!can_rename(fname,cnum)) continue; - strcpy(destname,newname); + pstrcpy(destname,newname); if (!resolve_wildcards(fname,destname)) continue; @@ -3051,7 +3078,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, int fnum1,fnum2; pstring dest; - strcpy(dest,dest1); + pstrcpy(dest,dest1); if (target_is_directory) { char *p = strrchr(src,'/'); if (p) @@ -3128,8 +3155,8 @@ int reply_copy(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf)); - strcpy(newname,smb_buf(inbuf) + 1 + strlen(name)); + pstrcpy(name,smb_buf(inbuf)); + pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name)); DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); @@ -3198,7 +3225,7 @@ int reply_copy(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; @@ -3252,7 +3279,7 @@ int reply_setdir(char *inbuf,char *outbuf) if (!CAN_SETDIR(snum)) return(ERROR(ERRDOS,ERRnoaccess)); - strcpy(newdir,smb_buf(inbuf) + 1); + pstrcpy(newdir,smb_buf(inbuf) + 1); strlower(newdir); if (strlen(newdir) == 0) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 3b24ba5ce9..22c8448dde 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -399,7 +399,7 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) (strequal(dname,".") || strequal(dname,".."))) continue; - strcpy(name2,dname); + pstrcpy(name2,dname); if (!name_map_mangle(name2,False,SNUM(cnum))) continue; if ((mangled && mangled_equal(name,name2)) @@ -545,7 +545,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa /* remember the rest of the pathname so it can be restored later */ - if (end) strcpy(rest,end+1); + if (end) pstrcpy(rest,end+1); /* try to find this part of the path in the directory */ if (strchr(start,'?') || strchr(start,'*') || @@ -1057,7 +1057,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct Files[fnum].fd_ptr = 0; errno = EPERM; - strcpy(fname,fname1); + pstrcpy(fname,fname1); /* check permissions */ if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer) @@ -1186,7 +1186,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct pstring dname; int dum1,dum2,dum3; char *p; - strcpy(dname,fname); + pstrcpy(dname,fname); p = strrchr(dname,'/'); if (p) *p = 0; if (sys_disk_free(dname,&dum1,&dum2,&dum3) < @@ -1321,10 +1321,10 @@ static void check_magic(int fnum,int cnum) int ret; pstring magic_output; pstring fname; - strcpy(fname,Files[fnum].name); + pstrcpy(fname,Files[fnum].name); if (*lp_magicoutput(SNUM(cnum))) - strcpy(magic_output,lp_magicoutput(SNUM(cnum))); + pstrcpy(magic_output,lp_magicoutput(SNUM(cnum))); else sprintf(magic_output,"%s.out",fname); @@ -2355,10 +2355,10 @@ BOOL reload_services(BOOL test) if (lp_loaded()) { pstring fname; - strcpy(fname,lp_configfile()); + pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { - strcpy(servicesf,fname); + pstrcpy(servicesf,fname); test = False; } } @@ -2651,13 +2651,13 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de { struct passwd *pass2; fstring fuser; - strcpy(fuser,lp_force_user(snum)); + fstrcpy(fuser,lp_force_user(snum)); pass2 = (struct passwd *)Get_Pwnam(fuser,True); if (pass2) { pcon->uid = pass2->pw_uid; string_set(&pcon->user,fuser); - strcpy(user,fuser); + fstrcpy(user,fuser); pcon->force_user = True; DEBUG(3,("Forced user %s\n",fuser)); } @@ -2667,7 +2667,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de { pstring s; - strcpy(s,lp_pathname(snum)); + pstrcpy(s,lp_pathname(snum)); standard_sub(cnum,s); string_set(&pcon->connectpath,s); DEBUG(3,("Connect path is %s\n",s)); @@ -2703,7 +2703,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de if (*lp_rootpreexec(SNUM(cnum))) { pstring cmd; - strcpy(cmd,lp_rootpreexec(SNUM(cnum))); + pstrcpy(cmd,lp_rootpreexec(SNUM(cnum))); standard_sub(cnum,cmd); DEBUG(5,("cmd=%s\n",cmd)); smbrun(cmd,NULL,False); @@ -2743,7 +2743,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de /* resolve any soft links early */ { pstring s; - strcpy(s,pcon->connectpath); + pstrcpy(s,pcon->connectpath); GetWd(s); string_set(&pcon->connectpath,s); ChDir(pcon->connectpath); @@ -2757,7 +2757,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de if (*lp_preexec(SNUM(cnum))) { pstring cmd; - strcpy(cmd,lp_preexec(SNUM(cnum))); + pstrcpy(cmd,lp_preexec(SNUM(cnum))); standard_sub(cnum,cmd); smbrun(cmd,NULL,False); } @@ -3216,7 +3216,7 @@ static int reply_negprot(char *inbuf,char *outbuf) SSVAL(outbuf,smb_vwv0,choice); if(choice != -1) { extern fstring remote_proto; - strcpy(remote_proto,supported_protocols[protocol].short_name); + fstrcpy(remote_proto,supported_protocols[protocol].short_name); reload_services(True); outsize = supported_protocols[protocol].proto_reply_fn(outbuf); DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name)); @@ -3335,7 +3335,7 @@ BOOL yield_connection(int cnum,char *name,int max_connections) bzero(&crec,sizeof(crec)); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); standard_sub(cnum,fname); trim_string(fname,"","/"); @@ -3407,7 +3407,7 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear) DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections)); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); standard_sub(cnum,fname); trim_string(fname,"","/"); @@ -3503,7 +3503,7 @@ static BOOL dump_core(void) { char *p; pstring dname; - strcpy(dname,debugf); + pstrcpy(dname,debugf); if ((p=strrchr(dname,'/'))) *p=0; strcat(dname,"/corefiles"); mkdir(dname,0700); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index c8e726d36e..59e9ef21b0 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -306,10 +306,10 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if(p[1] == '\0') strcpy(mask,"*.*"); else - strcpy(mask, p+1); + pstrcpy(mask, p+1); } else - strcpy(mask, path_mask); + pstrcpy(mask, path_mask); while (!found) { @@ -327,7 +327,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l matched = False; - strcpy(fname,dname); + pstrcpy(fname,dname); if(mask_match(fname, mask, case_sensitive, True)) { @@ -338,7 +338,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if (isrootdir && isdots) continue; - strcpy(pathreal,Connections[cnum].dirpath); + pstrcpy(pathreal,Connections[cnum].dirpath); if(needslash) strcat(pathreal,"/"); strcat(pathreal,dname); @@ -595,7 +595,7 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum return(ERROR(ERRDOS,ERRunknownlevel)); } - strcpy(directory, params + 12); /* Complete directory path with + pstrcpy(directory, params + 12); /* Complete directory path with wildcard mask appended */ DEBUG(5,("path=%s\n",directory)); @@ -1057,7 +1057,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, /* qpathinfo */ info_level = SVAL(params,0); fname = &fname1[0]; - strcpy(fname,¶ms[6]); + pstrcpy(fname,¶ms[6]); unix_convert(fname,cnum,0,&bad_path); if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); @@ -1163,7 +1163,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_QUERY_FILE_ALT_NAME_INFO: data_size = 4 + l; SIVAL(pdata,0,l); - strcpy(pdata+4,fname); + pstrcpy(pdata+4,fname); break; case SMB_QUERY_FILE_ALLOCATION_INFO: case SMB_QUERY_FILE_END_OF_FILEINFO: @@ -1197,7 +1197,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, pdata += 4; pdata += 4; /* alignment */ SIVAL(pdata,0,l); - strcpy(pdata+4,fname); + pstrcpy(pdata+4,fname); pdata += 4 + l; data_size = PTR_DIFF(pdata,(*ppdata)); break; @@ -1208,7 +1208,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, SIVAL(pdata,4,size); SIVAL(pdata,12,size); SIVAL(pdata,20,l); - strcpy(pdata+24,fname); + pstrcpy(pdata+24,fname); break; default: return(ERROR(ERRDOS,ERRunknownlevel)); @@ -1260,7 +1260,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, /* set path info */ info_level = SVAL(params,0); fname = fname1; - strcpy(fname,¶ms[6]); + pstrcpy(fname,¶ms[6]); unix_convert(fname,cnum,0,&bad_path); if(!check_name(fname, cnum)) { @@ -1443,7 +1443,7 @@ static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize, if (!CAN_WRITE(cnum)) return(ERROR(ERRSRV,ERRaccess)); - strcpy(directory, ¶ms[4]); + pstrcpy(directory, ¶ms[4]); DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); @@ -1645,6 +1645,9 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize) num_params = num_params_sofar = SVAL(inbuf,smb_pscnt); num_data = num_data_sofar = SVAL(inbuf, smb_dscnt); + if (num_params > total_params || num_data > total_data) + exit_server("invalid params in reply_trans2"); + memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params); memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data); @@ -1672,6 +1675,9 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize) total_data = SVAL(inbuf, smb_tdscnt); num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt)); num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt)); + if (num_params_sofar > total_params || num_data_sofar > total_data) + exit_server("data overflow in trans2"); + memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)], smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params); memcpy( &data[SVAL(inbuf, smb_sdsdisp)], diff --git a/source3/smbd/vt_mode.c b/source3/smbd/vt_mode.c index 0a4d50c217..07558274a5 100644 --- a/source3/smbd/vt_mode.c +++ b/source3/smbd/vt_mode.c @@ -81,7 +81,7 @@ int VT_Start_utmp(void) setutent(); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_line, VT_Line); if((v = getutline(&u)) == NULL) { if(strncmp(VT_Line, "tty", 3) == 0) @@ -91,12 +91,12 @@ int VT_Start_utmp(void) else tt = VT_Line; - strcpy(u.ut_id, tt); + fstrcpy(u.ut_id, tt); u.ut_time = time((time_t*)0); } - strcpy(u.ut_user, "LOGIN"); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_user, "LOGIN"); + fstrcpy(u.ut_line, VT_Line); u.ut_pid = getpid(); u.ut_type = LOGIN_PROCESS; pututline(&u); @@ -118,10 +118,10 @@ int VT_Stop_utmp(void) if(VT_Line != NULL) { setutent(); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_line, VT_Line); if((v = getutline(&u)) != NULL) { - strcpy(v->ut_user, ""); + fstrcpy(v->ut_user, ""); v->ut_type = DEAD_PROCESS; v->ut_time = time((time_t*)0); pututline(v); diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index 25c94dcd6a..aebbc4292c 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -122,7 +122,7 @@ int main(int argc,char *argv[]) got_bcast = True; break; case 'i': - strcpy(scope,optarg); + fstrcpy(scope,optarg); strupper(scope); break; case 'M': @@ -135,7 +135,7 @@ int main(int argc,char *argv[]) DEBUGLEVEL = atoi(optarg); break; case 's': - strcpy(servicesf, optarg); + pstrcpy(servicesf, optarg); break; case 'h': usage(); @@ -172,7 +172,7 @@ int main(int argc,char *argv[]) char *p; struct in_addr ip; - strcpy(lookup,argv[i]); + fstrcpy(lookup,argv[i]); if (find_master) { if (*lookup == '-') { -- cgit