Unix SMB/Netbios implementation.
Version 1.9.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994
+ Copyright (C) Jeremy Allison 1994-1997
Extensively modified by Andrew Tridgell, 1995
static int send_trans2_replies(char *outbuf, int bufsize, char *params,
int paramsize, char *pdata, int datasize)
{
- /* As we are using a protocol > LANMAN1 then the maxxmit
+ /* As we are using a protocol > LANMAN1 then the max_send
variable must have been set in the sessetupX call.
This takes precedence over the max_xmit field in the
global struct. These different max_xmit variables should
be merged as this is now too confusing */
- extern int maxxmit;
+ extern int max_send;
int data_to_send = datasize;
int params_to_send = paramsize;
int useable_space;
}
/* Space is bufsize minus Netbios over TCP header minus SMB header */
- /* The + 1 is to align the param and data bytes on an even byte
+ /* The alignment_offset is to align the param and data bytes on an even byte
boundary. NT 4.0 Beta needs this to work correctly. */
useable_space = bufsize - ((smb_buf(outbuf)+alignment_offset) - outbuf);
- useable_space = MIN(useable_space, maxxmit); /* XXX is this needed? correct? */
+ /* useable_space can never be more than max_send minus the
+ alignment offset. */
+ useable_space = MIN(useable_space, max_send - alignment_offset);
while( params_to_send || data_to_send)
{
/* Calculate whether we will totally or partially fill this packet */
total_sent_thistime = params_to_send + data_to_send + alignment_offset;
+ /* We can never send more than useable_space */
total_sent_thistime = MIN(total_sent_thistime, useable_space);
set_message(outbuf, 10, total_sent_thistime, True);
char *params = *pparams;
int16 open_mode = SVAL(params, 2);
int16 open_attr = SVAL(params,6);
+ BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
#if 0
BOOL return_additional_info = BITSETW(params,0);
int16 open_sattr = SVAL(params, 4);
int32 inode = 0;
struct stat sbuf;
int smb_action = 0;
+ BOOL bad_path = False;
StrnCpy(fname,pname,namelen);
/* XXXX we need to handle passed times, sattr and flags */
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0,&bad_path);
fnum = find_free_file();
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
if (!check_name(fname,cnum))
+ {
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
unixmode = unix_mode(cnum,open_attr | aARCH);
open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
- &rmode,&smb_action);
+ oplock_request, &rmode,&smb_action);
if (!Files[fnum].open)
+ {
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- if (fstat(Files[fnum].fd,&sbuf) != 0) {
+ if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
return(ERROR(ERRDOS,ERRnoaccess));
}
SIVAL(params,8, size);
SSVAL(params,12,rmode);
+ if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
SSVAL(params,18,smb_action);
SIVAL(params,20,inode);
strequal(Connections[cnum].dirpath,".") ||
strequal(Connections[cnum].dirpath,"/"));
BOOL was_8_3;
+ int nt_extmode; /* Used for NT connections instead of mode */
+ BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
*fname = 0;
*out_of_space = False;
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)
{
reskey = TellDir(Connections[cnum].dirptr);
- DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
+ DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
if (!dname)
matched = False;
- strcpy(fname,dname);
+ pstrcpy(fname,dname);
if(mask_match(fname, mask, case_sensitive, True))
{
if (isrootdir && isdots)
continue;
- strcpy(pathreal,Connections[cnum].dirpath);
- strcat(pathreal,"/");
- strcat(pathreal,fname);
+ pstrcpy(pathreal,Connections[cnum].dirpath);
+ if(needslash)
+ strcat(pathreal,"/");
+ strcat(pathreal,dname);
if (sys_stat(pathreal,&sbuf) != 0)
{
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
}
}
-
-#ifndef KANJI
- unix2dos_format(fname, True);
-#endif
+ name_map_mangle(fname,False,SNUM(cnum));
p = pdata;
nameptr = p;
- name_map_mangle(fname,False,SNUM(cnum));
+ nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL;
switch (info_level)
{
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- was_8_3 = is_8_3(fname);
+ was_8_3 = is_8_3(fname, True);
len = 94+strlen(fname);
len = (len + 3) & ~3;
SIVAL(p,0,len); p += 4;
put_long_date(p,mdate); p += 8;
SIVAL(p,0,size); p += 8;
SIVAL(p,0,size); p += 8;
- SIVAL(p,0,mode); p += 4;
+ SIVAL(p,0,nt_extmode); p += 4;
SIVAL(p,0,strlen(fname)); p += 4;
SIVAL(p,0,0); p += 4;
if (!was_8_3) {
-#ifndef KANJI
- strcpy(p+2,unix2dos_format(fname,False));
-#else
strcpy(p+2,fname);
-#endif
if (!name_map_mangle(p+2,True,SNUM(cnum)))
(p+2)[12] = 0;
} else
put_long_date(p,mdate); p += 8;
SIVAL(p,0,size); p += 8;
SIVAL(p,0,size); p += 8;
- SIVAL(p,0,mode); p += 4;
+ SIVAL(p,0,nt_extmode); p += 4;
SIVAL(p,0,strlen(fname)); p += 4;
strcpy(p,fname);
p = pdata + len;
put_long_date(p,mdate); p += 8;
SIVAL(p,0,size); p += 8;
SIVAL(p,0,size); p += 8;
- SIVAL(p,0,mode); p += 4;
+ SIVAL(p,0,nt_extmode); p += 4;
SIVAL(p,0,strlen(fname)); p += 4;
SIVAL(p,0,0); p += 4;
strcpy(p,fname);
BOOL dont_descend = False;
BOOL out_of_space = False;
int space_remaining;
+ BOOL bad_path = False;
*directory = *mask = 0;
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));
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0,&bad_path);
if(!check_name(directory,cnum)) {
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+
+#if 0
+ /* Ugly - NT specific hack - maybe not needed ? (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+#endif
+
return(ERROR(ERRDOS,ERRbadpath));
}
dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
if (dptr_num < 0)
- return(ERROR(ERRDOS,ERRbadpath));
+ {
+ if(dptr_num == -2)
+ {
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+
+#if 0
+ /* Ugly - NT specific hack - maybe not needed ? (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+#endif
+
+ return (UNIXERROR(ERRDOS,ERRbadpath));
+ }
+ return(ERROR(ERRDOS,ERRbadpath));
+ }
/* convert the formatted masks */
{
put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
SCVAL(pdata,l2_vol_cch,volname_len);
StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
- DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime,volname_len,
+ DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
pdata+l2_vol_szVolLabel));
break;
}
strcpy(pdata+4,vname);
break;
case SMB_QUERY_FS_VOLUME_INFO:
- data_len = 17 + strlen(vname);
- SIVAL(pdata,12,strlen(vname));
- strcpy(pdata+17,vname);
+ data_len = 18 + 2*strlen(vname);
+ SIVAL(pdata,12,2*strlen(vname));
+ PutUniCode(pdata+18,vname);
+ DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
+ vname));
break;
case SMB_QUERY_FS_SIZE_INFO:
{
char *fname;
char *p;
int l,pos;
-
+ BOOL bad_path = False;
if (tran_call == TRANSACT2_QFILEINFO) {
int16 fnum = SVALS(params,0);
CHECK_ERROR(fnum);
fname = Files[fnum].name;
- if (fstat(Files[fnum].fd,&sbuf) != 0) {
+ if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- pos = lseek(Files[fnum].fd,0,SEEK_CUR);
+ pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
} else {
/* qpathinfo */
info_level = SVAL(params,0);
fname = &fname1[0];
- strcpy(fname,¶ms[6]);
- unix_convert(fname,cnum);
+ 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)));
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
return(UNIXERROR(ERRDOS,ERRbadpath));
}
pos = 0;
if (total_data > 0 && IVAL(pdata,0) == total_data) {
/* uggh, EAs for OS2 */
DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
-#if 0
- SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
- return(-1);
-#else
return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
-#endif
}
bzero(pdata,data_size);
switch (info_level)
{
- case 1:
- case 2:
+ case SMB_INFO_STANDARD:
+ case SMB_INFO_QUERY_EA_SIZE:
data_size = (info_level==1?22:26);
- put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime);
- put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
- put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime);
+ put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime); /* create = inode mod */
+ put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); /* access time */
+ put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
SIVAL(pdata,l1_cbFile,size);
SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
break;
- case 3:
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
data_size = 24;
- put_dos_date2(pdata,0,sbuf.st_ctime);
+ put_dos_date2(pdata,0,sbuf.st_ctime); /* create time = inode mod time */
put_dos_date2(pdata,4,sbuf.st_atime);
put_dos_date2(pdata,8,sbuf.st_mtime);
SIVAL(pdata,12,size);
SIVAL(pdata,20,mode);
break;
- case 4:
+ case SMB_INFO_QUERY_ALL_EAS:
data_size = 4;
SIVAL(pdata,0,data_size);
break;
return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
case SMB_QUERY_FILE_BASIC_INFO:
- data_size = 36;
- put_long_date(pdata,sbuf.st_ctime);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime);
- put_long_date(pdata+24,sbuf.st_mtime);
+ data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
+ put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
+ put_long_date(pdata+8,sbuf.st_atime); /* access time */
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,mode);
+
+ DEBUG(5,("SMB_QFBI - "));
+ DEBUG(5,("create: %s ", ctime(&sbuf.st_ctime)));
+ DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
+ DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("mode: %x\n", mode));
+
break;
case SMB_QUERY_FILE_STANDARD_INFO:
data_size = 4;
break;
- case SMB_QUERY_FILE_NAME_INFO:
+ /* Get the 8.3 name - used if NT SMB was negotiated. */
case SMB_QUERY_FILE_ALT_NAME_INFO:
+ {
+ pstring short_name;
+ pstrcpy(short_name,fname);
+ /* Mangle if not already 8.3 */
+ if(!is_8_3(short_name, True))
+ {
+ if(!name_map_mangle(short_name,True,SNUM(cnum)))
+ *short_name = '\0';
+ }
+ strncpy(pdata + 4,short_name,12);
+ (pdata + 4)[12] = 0;
+ strupper(pdata + 4);
+ l = strlen(pdata + 4);
+ data_size = 4 + l;
+ SIVAL(pdata,0,l);
+ }
+ break;
+
+ case SMB_QUERY_FILE_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:
data_size = 8;
break;
case SMB_QUERY_FILE_ALL_INFO:
- put_long_date(pdata,sbuf.st_ctime);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime);
- put_long_date(pdata+24,sbuf.st_mtime);
+ put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
+ put_long_date(pdata+8,sbuf.st_atime); /* access time */
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,mode);
pdata += 40;
SIVAL(pdata,0,size);
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;
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));
pstring fname1;
char *fname;
int fd = -1;
+ BOOL bad_path = False;
if (!CAN_WRITE(cnum))
return(ERROR(ERRSRV,ERRaccess));
CHECK_ERROR(fnum);
fname = Files[fnum].name;
- fd = Files[fnum].fd;
+ fd = Files[fnum].fd_ptr->fd;
if(fstat(fd,&st)!=0) {
DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
/* set path info */
info_level = SVAL(params,0);
fname = fname1;
- strcpy(fname,¶ms[6]);
- unix_convert(fname,cnum);
+ pstrcpy(fname,¶ms[6]);
+ unix_convert(fname,cnum,0,&bad_path);
if(!check_name(fname, cnum))
- return(ERROR(ERRDOS,ERRbadpath));
-
+ {
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
if(sys_stat(fname,&st)!=0) {
DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
- return(ERROR(ERRDOS,ERRbadpath));
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
}
if (total_data > 0 && IVAL(pdata,0) == total_data) {
/* uggh, EAs for OS2 */
DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
-
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
-
- return(-1);
+ return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
}
switch (info_level)
+ {
+ case SMB_INFO_STANDARD:
+ case SMB_INFO_QUERY_EA_SIZE:
{
- case 1:
+ /* access time */
tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
- tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
- mode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
- break;
- case 2:
- tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
+ /* write time */
tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
+
mode = SVAL(pdata,l1_attrFile);
size = IVAL(pdata,l1_cbFile);
break;
+ }
- case 3:
+ /* XXXX um, i don't think this is right.
+ it's also not in the cifs6.txt spec.
+ */
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
tvs.actime = make_unix_date2(pdata+8);
tvs.modtime = make_unix_date2(pdata+12);
size = IVAL(pdata,16);
mode = IVAL(pdata,24);
break;
- case 4:
+ /* XXXX nor this. not in cifs6.txt, either. */
+ case SMB_INFO_QUERY_ALL_EAS:
tvs.actime = make_unix_date2(pdata+8);
tvs.modtime = make_unix_date2(pdata+12);
size = IVAL(pdata,16);
break;
case SMB_SET_FILE_BASIC_INFO:
- pdata += 8; /* create time */
- tvs.actime = interpret_long_date(pdata); pdata += 8;
- tvs.modtime=MAX(interpret_long_date(pdata),interpret_long_date(pdata+8));
- pdata += 16;
- mode = IVAL(pdata,0);
+ {
+ /* Ignore create time at offset pdata. */
+
+ /* access time */
+ tvs.actime = interpret_long_date(pdata+8);
+
+ /* write time + changed time, combined. */
+ tvs.modtime=MAX(interpret_long_date(pdata+16),
+ interpret_long_date(pdata+24));
+
+#if 0 /* Needs more testing... */
+ /* Test from Luke to prevent Win95 from
+ setting incorrect values here.
+ */
+ if (tvs.actime < tvs.modtime)
+ return(ERROR(ERRDOS,ERRnoaccess));
+#endif /* Needs more testing... */
+
+ /* attributes */
+ mode = IVAL(pdata,32);
break;
+ }
case SMB_SET_FILE_END_OF_FILE_INFO:
+ {
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return(ERROR(ERRDOS,ERRunknownlevel));
+ return(ERROR(ERRDOS,ERRunknownlevel));
size = IVAL(pdata,0);
break;
+ }
case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
default:
+ {
return(ERROR(ERRDOS,ERRunknownlevel));
}
+ }
+ DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
+ DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
+ DEBUG(6,("size: %x " , size));
+ DEBUG(6,("mode: %x\n" , mode));
+ /* get some defaults (no modifications) if any info is zero. */
if (!tvs.actime) tvs.actime = st.st_atime;
if (!tvs.modtime) tvs.modtime = st.st_mtime;
if (!size) size = st.st_size;
- /* Try and set the times, size and mode of this file - if they are different
- from the current values */
- if(st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
+ /* Try and set the times, size and mode of this file -
+ if they are different from the current values
+ */
+ if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
+ {
if(sys_utime(fname, &tvs)!=0)
+ {
return(ERROR(ERRDOS,ERRnoaccess));
+ }
}
- if(mode != dos_mode(cnum,fname,&st) && dos_chmod(cnum,fname,mode,NULL)) {
+
+ /* check the mode isn't different, before changing it */
+ if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL))
+ {
DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
return(ERROR(ERRDOS,ERRnoaccess));
}
- if(size != st.st_size) {
- if (fd == -1) {
+
+ if(size != st.st_size)
+ {
+ if (fd == -1)
+ {
fd = sys_open(fname,O_RDWR,0);
if (fd == -1)
- return(ERROR(ERRDOS,ERRbadpath));
+ {
+ return(ERROR(ERRDOS,ERRbadpath));
+ }
set_filelen(fd, size);
close(fd);
- } else {
+ }
+ else
+ {
set_filelen(fd, size);
}
}
char *params = *pparams;
pstring directory;
int ret = -1;
+ BOOL bad_path = False;
if (!CAN_WRITE(cnum))
return(ERROR(ERRSRV,ERRaccess));
- strcpy(directory, ¶ms[4]);
+ pstrcpy(directory, ¶ms[4]);
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0,&bad_path);
if (check_name(directory,cnum))
ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
if(ret < 0)
{
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
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);
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)],