summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1997-09-26 12:39:45 +0000
committerAndrew Tridgell <tridge@samba.org>1997-09-26 12:39:45 +0000
commite8dd34b0d3ba704deff696c1683297536a494893 (patch)
treea53f2b1b66285c18b7696df87e0b1e3f520006bb
parentc701db19e14d1b53103acbb8f7abe4c8bc2c3614 (diff)
downloadsamba-e8dd34b0d3ba704deff696c1683297536a494893.tar.gz
This commit fixes the security hole due to buffer overflows.
The main fix is just a couple of lines long, but I have now also put precautionary checks on a large number of other places in the code where unchecked string copies were being performed. An exploit via one of these copies is unlikely, but is is better to be safe. I also added a routine to log possible exploit attempts using the code that was posted for obtaining root access on a Samba server.
-rw-r--r--source/client/clientutil.c21
-rw-r--r--source/include/local.h2
-rw-r--r--source/include/proto.h2
-rw-r--r--source/lib/system.c4
-rw-r--r--source/lib/time.c4
-rw-r--r--source/lib/username.c4
-rw-r--r--source/lib/util.c114
-rw-r--r--source/libsmb/nmblib.c4
-rw-r--r--source/locking/locking.c2
-rw-r--r--source/nameannounce.c4
-rw-r--r--source/namedbname.c8
-rw-r--r--source/namedbsubnet.c4
-rw-r--r--source/nameelect.c2
-rw-r--r--source/namelogon.c6
-rw-r--r--source/nmbd/nmbd.c22
-rw-r--r--source/nmbsync.c4
-rw-r--r--source/param/loadparm.c8
-rw-r--r--source/printing/pcap.c4
-rw-r--r--source/printing/printing.c36
-rw-r--r--source/smbd/chgpasswd.c12
-rw-r--r--source/smbd/dir.c2
-rw-r--r--source/smbd/ipc.c29
-rw-r--r--source/smbd/mangle.c8
-rw-r--r--source/smbd/message.c14
-rw-r--r--source/smbd/pipes.c4
-rw-r--r--source/smbd/reply.c131
-rw-r--r--source/smbd/server.c36
-rw-r--r--source/smbd/trans2.c28
-rw-r--r--source/smbd/vt_mode.c12
-rw-r--r--source/utils/nmblookup.c6
30 files changed, 320 insertions, 217 deletions
diff --git a/source/client/clientutil.c b/source/client/clientutil.c
index b4f0849c5fe..1b59946ff5b 100644
--- a/source/client/clientutil.c
+++ b/source/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);
#ifdef SMB_PASSWD
if (doencrypt && *pass) {
@@ -451,7 +452,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu
#endif
/* 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);
@@ -557,7 +558,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);
#ifdef SMB_PASSWD
if (doencrypt && *pass) {
@@ -568,7 +569,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);
@@ -817,9 +818,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/source/include/local.h b/source/include/local.h
index fc589d7ac0d..9548bf74b6b 100644
--- a/source/include/local.h
+++ b/source/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/source/include/proto.h b/source/include/proto.h
index 01afb7cad95..ffa2f251cca 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -976,6 +976,8 @@ void file_unlock(int fd);
BOOL is_myname(const char *s);
void set_remote_arch(enum remote_arch_types type);
enum remote_arch_types get_remote_arch();
+void fstrcpy(char *dest, char *src);
+void pstrcpy(char *dest, char *src);
/*The following definitions come from vt_mode.c */
diff --git a/source/lib/system.c b/source/lib/system.c
index 447a4f88aca..df24691512f 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -311,8 +311,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/source/lib/time.c b/source/lib/time.c
index d16552b61e2..4f688d2214a 100644
--- a/source/lib/time.c
+++ b/source/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/source/lib/username.c b/source/lib/username.c
index b8d152c83fd..46b8f4cb332 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -62,7 +62,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;
}
@@ -173,7 +173,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/source/lib/util.c b/source/lib/util.c
index 7f922def7e3..0c4999c789c 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1079,7 +1079,7 @@ void unix_format(char *fname)
if (*fname == '/')
{
- strcpy(namecopy,fname);
+ pstrcpy(namecopy,fname);
strcpy(fname,".");
strcat(fname,namecopy);
}
@@ -1290,7 +1290,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;
@@ -1328,7 +1328,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;
@@ -1355,7 +1355,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);
}
@@ -1515,7 +1515,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)
@@ -1585,12 +1585,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);
@@ -1614,10 +1614,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);
}
}
@@ -1641,20 +1641,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;
}
}
@@ -1672,7 +1672,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,".");
@@ -1773,7 +1773,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;
@@ -2421,7 +2421,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);
@@ -2593,25 +2598,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,"");
}
}
@@ -2927,7 +2932,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)
@@ -3295,7 +3300,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;
@@ -3552,7 +3557,7 @@ char *readdirname(void *p)
{
static pstring buf;
- strcpy(buf, dname);
+ pstrcpy(buf, dname);
unix_to_dos(buf, True);
dname = buf;
}
@@ -3907,3 +3912,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/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index bc967bdacb4..29b54a708bc 100644
--- a/source/libsmb/nmblib.c
+++ b/source/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/source/locking/locking.c b/source/locking/locking.c
index 760d21a05d8..c2a06cac75c 100644
--- a/source/locking/locking.c
+++ b/source/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/source/nameannounce.c b/source/nameannounce.c
index 684ef412581..84e3ad3fa77 100644
--- a/source/nameannounce.c
+++ b/source/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/source/namedbname.c b/source/namedbname.c
index a45a749f140..51571d786a8 100644
--- a/source/namedbname.c
+++ b/source/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/source/namedbsubnet.c b/source/namedbsubnet.c
index 6364ebba543..4f0b647996d 100644
--- a/source/namedbsubnet.c
+++ b/source/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/source/nameelect.c b/source/nameelect.c
index 4666b22588c..5c156a312ed 100644
--- a/source/nameelect.c
+++ b/source/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/source/namelogon.c b/source/namelogon.c
index 1c118c85418..1f57139d56a 100644
--- a/source/namelogon.c
+++ b/source/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/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 925f975ffef..3f0279908da 100644
--- a/source/nmbd/nmbd.c
+++ b/source/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/source/nmbsync.c b/source/nmbsync.c
index f2161f631af..de2f7aa00f1 100644
--- a/source/nmbsync.c
+++ b/source/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/source/param/loadparm.c b/source/param/loadparm.c
index ad9bf83886d..510a661dc39 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -1382,7 +1382,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);
}
@@ -1402,7 +1402,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",
@@ -1532,7 +1532,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);
@@ -2025,7 +2025,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/source/printing/pcap.c b/source/printing/pcap.c
index 549ebcd70df..65195ab1af6 100644
--- a/source/printing/pcap.c
+++ b/source/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/source/printing/printing.c b/source/printing/printing.c
index c83d2169891..51fd3a992eb 100644
--- a/source/printing/printing.c
+++ b/source/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/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 6063f2aac8a..bed81138b24 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/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/source/smbd/dir.c b/source/smbd/dir.c
index 06ee6ae8ed7..567bc14424e 100644
--- a/source/smbd/dir.c
+++ b/source/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/source/smbd/ipc.c b/source/smbd/ipc.c
index 55e293d7ffd..9aaf03e6c4f 100644
--- a/source/smbd/ipc.c
+++ b/source/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
@@ -2461,7 +2461,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 */
@@ -3018,7 +3019,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)
{
@@ -3080,6 +3085,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/source/smbd/mangle.c b/source/smbd/mangle.c
index a08402a85ea..a964f4a5c73 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -269,7 +269,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))
@@ -303,7 +303,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 == '*')) {
@@ -442,7 +442,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. */
@@ -456,7 +456,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/source/smbd/message.c b/source/smbd/message.c
index 93a2d9d850a..64253932abb 100644
--- a/source/smbd/message.c
+++ b/source/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/source/smbd/pipes.c b/source/smbd/pipes.c
index afab7e1d911..feb8d91a5b0 100644
--- a/source/smbd/pipes.c
+++ b/source/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/source/smbd/reply.c b/source/smbd/reply.c
index a15185146da..4235e7725e9 100644
--- a/source/smbd/reply.c
+++ b/source/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)
@@ -69,22 +81,22 @@ int reply_special(char *inbuf,char *outbuf)
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);
- }
+ 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);
+ fstrcpy(remote_machine,name2);
trim_string(remote_machine," "," ");
p = strchr(remote_machine,' ');
strlower(remote_machine);
if (p) *p = 0;
- strcpy(local_machine,name1);
+ fstrcpy(local_machine,name1);
trim_string(local_machine," "," ");
p = strchr(local_machine,' ');
strlower(local_machine);
@@ -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);
@@ -2620,7 +2647,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))
@@ -2668,7 +2695,7 @@ int reply_rmdir(char *inbuf,char *outbuf)
errno = ENOMEM;
break;
}
- strcpy(fullname, directory);
+ pstrcpy(fullname, directory);
strcat(fullname, "/");
strcat(fullname, dname);
@@ -2730,21 +2757,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;
@@ -2818,8 +2845,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));
@@ -2933,14 +2960,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;
@@ -2986,7 +3013,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)
@@ -3063,8 +3090,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));
@@ -3133,7 +3160,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;
@@ -3187,7 +3214,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/source/smbd/server.c b/source/smbd/server.c
index d4407269f0b..2bc0e023158 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -393,7 +393,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))
@@ -539,7 +539,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,'*') ||
@@ -1051,7 +1051,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)
@@ -1180,7 +1180,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) <
@@ -1315,10 +1315,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);
@@ -2280,10 +2280,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;
}
}
@@ -2576,13 +2576,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));
}
@@ -2592,7 +2592,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));
@@ -2628,7 +2628,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);
@@ -2668,7 +2668,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);
@@ -2682,7 +2682,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);
}
@@ -3153,7 +3153,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));
@@ -3272,7 +3272,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,"","/");
@@ -3344,7 +3344,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,"","/");
@@ -3440,7 +3440,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/source/smbd/trans2.c b/source/smbd/trans2.c
index 19c1158658c..ecc8f5dbec7 100644
--- a/source/smbd/trans2.c
+++ b/source/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,&params[6]);
+ pstrcpy(fname,&params[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,&params[6]);
+ pstrcpy(fname,&params[6]);
unix_convert(fname,cnum,0,&bad_path);
if(!check_name(fname, cnum))
{
@@ -1435,7 +1435,7 @@ static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
if (!CAN_WRITE(cnum))
return(ERROR(ERRSRV,ERRaccess));
- strcpy(directory, &params[4]);
+ pstrcpy(directory, &params[4]);
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
@@ -1637,6 +1637,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);
@@ -1664,6 +1667,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( &params[ SVAL(inbuf, smb_spsdisp)],
smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
diff --git a/source/smbd/vt_mode.c b/source/smbd/vt_mode.c
index 0a4d50c217f..07558274a52 100644
--- a/source/smbd/vt_mode.c
+++ b/source/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/source/utils/nmblookup.c b/source/utils/nmblookup.c
index 25c94dcd6a0..aebbc4292ca 100644
--- a/source/utils/nmblookup.c
+++ b/source/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 == '-') {