extern fstring local_machine;
extern int global_oplock_break;
extern uint32 global_client_caps;
-extern pstring global_myname;
+
+#define get_file_size(sbuf) ((sbuf).st_size)
/* given a stat buffer return the allocated size on disk, taking into
account sparse files */
-SMB_OFF_T get_allocation_size(SMB_STRUCT_STAT *sbuf)
+SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
- SMB_OFF_T ret;
- ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks;
- ret = SMB_ROUNDUP_ALLOCATION(ret);
+ SMB_BIG_UINT ret;
+#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
+ ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
+#else
+ ret = (SMB_BIG_UINT)get_file_size(*sbuf);
+#endif
+ if (!ret && fsp && fsp->initial_allocation_size)
+ ret = fsp->initial_allocation_size;
+ ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE);
return ret;
}
-#define get_file_size(sbuf) (sbuf.st_size)
-
-
/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
BOOL *out_of_space, BOOL *got_exact_match,
int *last_name_off)
{
- char *dname;
+ const char *dname;
BOOL found = False;
SMB_STRUCT_STAT sbuf;
pstring mask;
int prev_dirpos=0;
int mode=0;
SMB_OFF_T file_size = 0;
- SMB_OFF_T allocation_size = 0;
+ SMB_BIG_UINT allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
char *nameptr;
pstrcat(pathreal,dname);
if (INFO_LEVEL_IS_UNIX(info_level)) {
- if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
+ if (VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
continue;
}
- } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
+ } else if (VFS_STAT(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as
* directories */
}
file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ allocation_size = get_allocation_size(NULL,&sbuf);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
nameptr = p;
p += align_string(outbuf, p, 0);
len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
- SCVAL(nameptr, -1, len);
+ if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
+ SCVAL(nameptr, -1, len-2);
+ else
+ SCVAL(nameptr, -1, len-1);
p += len;
break;
SIVAL(p,l2_cbList,0); /* No extended attributes */
p += l2_achName;
nameptr = p;
- len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
- SCVAL(p, -1, len);
+ p += align_string(outbuf, p, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
+ if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
+ SCVAL(nameptr, -1, len-2);
+ else
+ SCVAL(nameptr, -1, len-1);
p += len;
- *p++ = 0; /* craig from unisys pointed out we need this */
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
SIVAL(p,0,nt_extmode); p += 4;
q = p; p += 4;
SIVAL(p,0,0); p += 4;
+ /* Clear the short name buffer. This is
+ * IMPORTANT as not doing so will trigger
+ * a Win2k client bug. JRA.
+ */
+ memset(p,'\0',26);
if (!was_8_3) {
pstring mangled_name;
pstrcpy(mangled_name, fname);
SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
p+= 8;
-#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
-#else
- /* Can't get the value - fake it using size. */
- SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
-#endif
+ SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
p+= 8;
put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
p = strrchr_m(directory,'/');
if(p == NULL) {
- pstrcpy(mask,directory);
+ /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
+ if((directory[0] == '.') && (directory[1] == '\0'))
+ pstrcpy(mask,"*");
+ else
+ pstrcpy(mask,directory);
pstrcpy(directory,"./");
} else {
pstrcpy(mask,p+1);
*/
int current_pos, start_pos;
- char *dname = NULL;
+ const char *dname = NULL;
+ pstring dname_pstring;
void *dirptr = conn->dirptr;
start_pos = TellDir(dirptr);
for(current_pos = start_pos; current_pos >= 0; current_pos--) {
SeekDir(dirptr, current_pos);
dname = ReadDirName(dirptr);
+ if (dname) {
+ /*
+ * Remember, mangle_map is called by
+ * get_lanman2_dir_entry(), so the resume name
+ * could be mangled. Ensure we do the same
+ * here.
+ */
+
+ /* make sure we get a copy that mangle_map can modify */
- /*
- * Remember, mangle_map is called by
- * get_lanman2_dir_entry(), so the resume name
- * could be mangled. Ensure we do the same
- * here.
- */
-
- if(dname != NULL)
- mangle_map( dname, False, True, SNUM(conn));
-
- if(dname && strcsequal( resume_name, dname)) {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
+ pstrcpy(dname_pstring, dname);
+ mangle_map( dname_pstring, False, True, SNUM(conn));
+
+ if(strcsequal( resume_name, dname_pstring)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
+ }
}
}
* here.
*/
- if(dname != NULL)
- mangle_map( dname, False, True, SNUM(conn));
+ if(dname) {
+ /* make sure we get a copy that mangle_map can modify */
+
+ pstrcpy(dname_pstring, dname);
+ mangle_map(dname_pstring, False, True, SNUM(conn));
- if(dname && strcsequal( resume_name, dname)) {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
+ if(strcsequal( resume_name, dname_pstring)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
+ }
}
} /* end for */
} /* end if current_pos */
dptr_close(&dptr_num); /* This frees up the saved mask */
}
-
/* Set up the return parameter block */
SSVAL(params,0,numentries);
SSVAL(params,2,finished);
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
- if(vfs_stat(conn,".",&st)!=0) {
+ if(VFS_STAT(conn,".",&st)!=0) {
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
SIVAL(pdata,l1_idFileSystem,st.st_dev);
SIVAL(pdata,l1_cSectorUnit,bsize/512);
SIVAL(pdata,l1_cUnit,dsize);
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
uint16 info_level;
int mode=0;
SMB_OFF_T file_size=0;
- SMB_OFF_T allocation_size=0;
+ SMB_BIG_UINT allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
pstring fname, dos_fname;
BOOL delete_pending = False;
int len;
time_t c_time;
+ files_struct *fsp = NULL;
if (!params)
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
if (tran_call == TRANSACT2_QFILEINFO) {
- files_struct *fsp = file_fsp(params,0);
+ if (total_params < 4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ fsp = file_fsp(params,0);
info_level = SVAL(params,2);
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (vfs_lstat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ if (VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ } else if (!VALID_STAT(sbuf) && VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
CHECK_FSP(fsp,conn);
pstrcpy(fname, fsp->fsp_name);
- if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ if (VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
+ if((pos = VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
delete_pending = fsp->delete_on_close;
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (vfs_lstat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ if (VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ } else if (!VALID_STAT(sbuf) && VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
mode = dos_mode(conn,fname,&sbuf);
fullpathname = fname;
file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ allocation_size = get_allocation_size(fsp,&sbuf);
if (mode & aDIR)
file_size = 0;
/* Get the 8.3 name - used if NT SMB was negotiated. */
case SMB_QUERY_FILE_ALT_NAME_INFO:
+ case SMB_FILE_ALTERNATE_NAME_INFORMATION:
{
pstring short_name;
if(!mangle_is_8_3(short_name, True)) {
mangle_map(short_name,True,True,SNUM(conn));
}
- len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
+ len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
data_size = 4 + len;
SIVAL(pdata,0,len);
break;
break;
case SMB_FILE_INTERNAL_INFORMATION:
- /* This should be an index number - looks like dev/ino to me :-) */
+ /* This should be an index number - looks like
+ dev/ino to me :-)
+
+ I think this causes us to fail the IFSKIT
+ BasicFileInformationTest. -tpot */
+
SIVAL(pdata,0,sbuf.st_dev);
SIVAL(pdata,4,sbuf.st_ino);
data_size = 8;
}
#endif
- case SMB_FILE_ALTERNATE_NAME_INFORMATION:
- /* Last component of pathname. */
- {
- size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
- SIVAL(pdata,0,byte_len);
- data_size = 4 + byte_len;
- break;
- }
-
#if 0
/*
* NT4 server just returns "invalid query" to this - if we try to answer
SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
pdata += 8;
-#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- SOFF_T(pdata,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
-#else
- /* Can't get the value - fake it using size. */
- SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
-#endif
+ SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
#else
return(UNIXERROR(ERRDOS,ERRbadlink));
#endif
- len = conn->vfs_ops.readlink(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
+ len = VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
if (len == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
buffer[len] = 0;
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
} else {
+ fsp->delete_on_close = delete_on_close;
+ DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ }
- files_struct *iterate_fsp;
-
- /*
- * Modify the share mode entry for all files open
- * on this device and inode to tell other smbds we have
- * changed the delete on close flag. This will be noticed
- * in the close code, the last closer will delete the file
- * if flag is set.
- */
+ return NT_STATUS_OK;
+}
- DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+/****************************************************************************
+ Sets the delete on close flag over all share modes on this file.
+ Modify the share mode entry for all files open
+ on this device and inode to tell other smbds we have
+ changed the delete on close flag. This will be noticed
+ in the close code, the last closer will delete the file
+ if flag is set.
+****************************************************************************/
- if (lock_share_entry_fsp(fsp) == False)
- return NT_STATUS_ACCESS_DENIED;
+NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
+{
+ DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
- if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
- DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
- fsp->fsp_name ));
- unlock_share_entry_fsp(fsp);
- return NT_STATUS_ACCESS_DENIED;
- }
+ if (fsp->is_directory || fsp->is_stat)
+ return NT_STATUS_OK;
- /*
- * Release the lock.
- */
+ if (lock_share_entry_fsp(fsp) == False)
+ return NT_STATUS_ACCESS_DENIED;
+ if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
+ DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
+ fsp->fsp_name ));
unlock_share_entry_fsp(fsp);
-
- /*
- * Go through all files we have open on the same device and
- * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
- * Other smbd's that have this file open will look in the share_mode on close.
- * take care of this (rare) case in close_file(). See the comment there.
- * NB. JRA. We don't really need to do this anymore - all should be taken
- * care of in the share_mode changes in the tdb.
- */
-
- for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
- iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
- fsp->delete_on_close = delete_on_close;
-
- /*
- * Set the delete on close flag in the fsp.
- */
- fsp->delete_on_close = delete_on_close;
-
- DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
-
+ return NT_STATUS_ACCESS_DENIED;
}
+ unlock_share_entry_fsp(fsp);
return NT_STATUS_OK;
}
pstrcpy(link_dest, "./");
}
- if (conn->vfs_ops.realpath(conn,link_dest,resolved_name) == NULL)
+ if (VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
return -1;
pstrcpy(link_dest, resolved_name);
pstrcpy(fname, fsp->fsp_name);
fd = fsp->fd;
- if (vfs_fstat(fsp,fd,&sbuf) != 0) {
+ if (VFS_FSTAT(fsp,fd,&sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
switch (info_level) {
case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
{
if (total_data < l1_cbFile+4)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
break;
}
+ case SMB_INFO_SET_EA:
+ return(ERROR_DOS(ERRDOS,ERReasnotsupported));
+
/* XXXX um, i don't think this is right.
it's also not in the cifs6.txt spec.
*/
case SMB_SET_FILE_ALLOCATION_INFO:
{
int ret = -1;
- SMB_OFF_T allocation_size = IVAL(pdata,0);
+ SMB_BIG_UINT allocation_size;
if (total_data < 8)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
- allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+ allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return ERROR_DOS(ERRDOS,ERRunknownlevel);
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
fname, (double)allocation_size ));
+ if (allocation_size)
+ allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
+
if(allocation_size != get_file_size(sbuf)) {
SMB_STRUCT_STAT new_sbuf;
if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath));
ret = vfs_allocate_file_space(new_fsp, allocation_size);
- if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
+ if (VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
new_fsp->fnum, strerror(errno)));
ret = -1;
close_file(new_fsp,True);
} else {
ret = vfs_allocate_file_space(fsp, allocation_size);
- if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
+ if (VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
fsp->fnum, strerror(errno)));
ret = -1;
status = set_delete_on_close_internal(fsp, delete_on_close);
+ if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ return ERROR_NT(status);
+
+ /* The set is across all open files on this dev/inode pair. */
+ status =set_delete_on_close_over_all(fsp, delete_on_close);
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
return ERROR_NT(status);
0%o for file %s\n", (double)dev, unixmode, fname ));
/* Ok - do the mknod. */
- if (conn->vfs_ops.mknod(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
+ if (VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ inherit_access_acl(conn, fname, unixmode);
+
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
if (raw_unixmode != SMB_MODE_NO_CHANGE) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
(unsigned int)unixmode, fname ));
- if (vfs_chmod(conn,fname,unixmode) != 0)
+ if (VFS_CHMOD(conn,fname,unixmode) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0)
+ if (VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0)
+ if (VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
break;
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
fname, link_dest ));
- if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0)
+ if (VFS_SYMLINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
fname, link_dest ));
- if (conn->vfs_ops.link(conn,link_dest,fname) != 0)
+ if (VFS_LINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
unix_convert(directory,conn,0,&bad_path,&sbuf);
if (check_name(directory,conn))
- ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
if(ret < 0) {
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
- uint16 rap_jobid;
-
pdata = Realloc(*ppdata, 32);
if(pdata == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
CAN ACCEPT THIS IN UNICODE. JRA. */
- rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */
- SSVAL(pdata,0,rap_jobid); /* Job number */
- srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
+ SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
+ srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
return(-1);
unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
unsigned int tran_call = SVAL(inbuf, smb_setup0);
char *params = NULL, *data = NULL;
- int num_params, num_params_sofar, num_data, num_data_sofar;
+ unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
START_PROFILE(SMBtrans2);
if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
} else {
- DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
+ DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
DEBUG(2,("Transaction is %d\n",tran_call));
END_PROFILE(SMBtrans2);
- return ERROR_DOS(ERRSRV,ERRerror);
+ ERROR_DOS(ERRDOS,ERRinvalidparam);
}
}
if (num_params > total_params || num_data > total_data)
exit_server("invalid params in reply_trans2");
- if(params)
- memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
- if(data)
- memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
+ if(params) {
+ unsigned int psoff = SVAL(inbuf, smb_psoff);
+ if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
+ goto bad_param;
+ if (smb_base(inbuf) + psoff + num_params > inbuf + length)
+ goto bad_param;
+ memcpy( params, smb_base(inbuf) + psoff, num_params);
+ }
+ if(data) {
+ unsigned int dsoff = SVAL(inbuf, smb_dsoff);
+ if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
+ goto bad_param;
+ if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
+ goto bad_param;
+ memcpy( data, smb_base(inbuf) + dsoff, num_data);
+ }
if(num_data_sofar < total_data || num_params_sofar < total_params) {
/* We need to send an interim response then receive the rest
while (num_data_sofar < total_data ||
num_params_sofar < total_params) {
BOOL ret;
+ unsigned int param_disp;
+ unsigned int param_off;
+ unsigned int data_disp;
+ unsigned int data_off;
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
else
DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
(smb_read_error == READ_ERROR) ? "error" : "timeout" ));
- SAFE_FREE(params);
- SAFE_FREE(data);
- END_PROFILE(SMBtrans2);
- return ERROR_DOS(ERRSRV,ERRerror);
+ goto bad_param;
}
/* Revise total_params and total_data in case
they have changed downwards */
- total_params = SVAL(inbuf, smb_tpscnt);
- 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 (SVAL(inbuf, smb_tpscnt) < total_params)
+ total_params = SVAL(inbuf, smb_tpscnt);
+ if (SVAL(inbuf, smb_tdscnt) < total_data)
+ total_data = SVAL(inbuf, smb_tdscnt);
+
+ num_params = SVAL(inbuf,smb_spscnt);
+ param_off = SVAL(inbuf, smb_spsoff);
+ param_disp = SVAL(inbuf, smb_spsdisp);
+ num_params_sofar += num_params;
+
+ num_data = SVAL(inbuf, smb_sdscnt);
+ data_off = SVAL(inbuf, smb_sdsoff);
+ data_disp = SVAL(inbuf, smb_sdsdisp);
+ num_data_sofar += num_data;
+
if (num_params_sofar > total_params || num_data_sofar > total_data)
- exit_server("data overflow in trans2");
+ goto bad_param;
- memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
- smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
- memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
- smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
+ if (num_params) {
+ if (param_disp + num_params >= total_params)
+ goto bad_param;
+ if ((param_disp + num_params < param_disp) ||
+ (param_disp + num_params < num_params))
+ goto bad_param;
+ if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
+ goto bad_param;
+ if (params + param_disp < params)
+ goto bad_param;
+
+ memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
+ }
+ if (num_data) {
+ if (data_disp + num_data >= total_data)
+ goto bad_param;
+ if ((data_disp + num_data < data_disp) ||
+ (data_disp + num_data < num_data))
+ goto bad_param;
+ if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
+ goto bad_param;
+ if (data + data_disp < data)
+ goto bad_param;
+
+ memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
+ }
}
}
return outsize; /* If a correct response was needed the
call_trans2xxx calls have already sent
it. If outsize != -1 then it is returning */
+
+ bad_param:
+
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ END_PROFILE(SMBtrans2);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}