diff options
author | Jeremy Allison <jra@samba.org> | 1997-09-26 18:55:29 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1997-09-26 18:55:29 +0000 |
commit | cef59090bb2fd3f8a9efd1a453cb90264b891d58 (patch) | |
tree | 694593e9501de3a8aa6966d7e0f9118c29b28447 /source3/smbd | |
parent | 5a7b3294dbbe88f0d5da25a74b8112fc6c70af1f (diff) | |
download | samba-cef59090bb2fd3f8a9efd1a453cb90264b891d58.tar.gz samba-cef59090bb2fd3f8a9efd1a453cb90264b891d58.tar.bz2 samba-cef59090bb2fd3f8a9efd1a453cb90264b891d58.zip |
Adding Andrews buffer overflow fixes into the main branch.
Jeremy (jallison@whistle.com)
(This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 12 | ||||
-rw-r--r-- | source3/smbd/dir.c | 2 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 29 | ||||
-rw-r--r-- | source3/smbd/mangle.c | 8 | ||||
-rw-r--r-- | source3/smbd/message.c | 14 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 4 | ||||
-rw-r--r-- | source3/smbd/reply.c | 175 | ||||
-rw-r--r-- | source3/smbd/server.c | 36 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 28 | ||||
-rw-r--r-- | source3/smbd/vt_mode.c | 12 |
10 files changed, 181 insertions, 139 deletions
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<count;i++) if (strequal(servers[i].name,local_machine)) { servertype = servers[i].type; - strcpy(comment,servers[i].comment); + pstrcpy(comment,servers[i].comment); } } if (servers) free(servers); @@ -2026,7 +2026,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, p2 = p + usri11_end; memset(p,0,21); - strcpy(p+usri11_name,UserName); /* 21 bytes - user name */ + fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */ if (uLevel > 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 @@ -49,6 +49,18 @@ a packet to ensure chaining works correctly */ /**************************************************************************** +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 ****************************************************************************/ int reply_special(char *inbuf,char *outbuf) @@ -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); |