1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-14 20:23:54 +03:00

Fixed allocation bug in database prog. Some format fixes.

Jeremy.
This commit is contained in:
Jeremy Allison
-
parent 8bb5cb27c2
commit 9ff6b0c20c
4 changed files with 1037 additions and 1049 deletions

View File

@@ -189,4 +189,7 @@
/* the maximum age in seconds of a password. Should be a lp_ parameter */ /* the maximum age in seconds of a password. Should be a lp_ parameter */
#define MAX_PASSWORD_AGE (21*24*60*60) #define MAX_PASSWORD_AGE (21*24*60*60)
/* Allocation roundup. */
#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000
#endif #endif

View File

@@ -159,6 +159,7 @@
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__) #define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1)) #define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
#define SMB_ROUNDUP_ALLOCATION(s) (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE)))
/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */ /* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2) #define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)

View File

@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation. Unix SMB/Netbios implementation.
Version 1.9. Version 1.9.
SMB transaction2 handling SMB transaction2 handling
Copyright (C) Jeremy Allison 1994-1998 Copyright (C) Jeremy Allison 1994-2001
Extensively modified by Andrew Tridgell, 1995 Extensively modified by Andrew Tridgell, 1995
@@ -37,6 +37,7 @@ extern pstring global_myname;
set correctly for the type of call. set correctly for the type of call.
HACK ! Always assumes smb_setup field is zero. HACK ! Always assumes smb_setup field is zero.
****************************************************************************/ ****************************************************************************/
static int send_trans2_replies(char *outbuf, int bufsize, char *params, static int send_trans2_replies(char *outbuf, int bufsize, char *params,
int paramsize, char *pdata, int datasize) int paramsize, char *pdata, int datasize)
{ {
@@ -181,10 +182,10 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
return 0; return 0;
} }
/**************************************************************************** /****************************************************************************
reply to a TRANSACT2_OPEN Reply to a TRANSACT2_OPEN.
****************************************************************************/ ****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
int bufsize, int bufsize,
char **pparams, char **ppdata) char **pparams, char **ppdata)
@@ -289,21 +290,25 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
} }
/********************************************************* /*********************************************************
* Routine to check if a given string matches exactly. Routine to check if a given string matches exactly.
* as a special case a mask of "." does NOT match. That as a special case a mask of "." does NOT match. That
* is required for correct wildcard semantics is required for correct wildcard semantics
* Case can be significant or not. Case can be significant or not.
**********************************************************/ **********************************************************/
static BOOL exact_match(char *str,char *mask, BOOL case_sig) static BOOL exact_match(char *str,char *mask, BOOL case_sig)
{ {
if (mask[0] == '.' && mask[1] == 0) return False; if (mask[0] == '.' && mask[1] == 0)
if (case_sig) return strcmp(str,mask)==0; return False;
if (case_sig)
return strcmp(str,mask)==0;
return strcasecmp(str,mask) == 0; return strcasecmp(str,mask) == 0;
} }
/**************************************************************************** /****************************************************************************
get a level dependent lanman2 dir entry. Get a level dependent lanman2 dir entry.
****************************************************************************/ ****************************************************************************/
static BOOL get_lanman2_dir_entry(connection_struct *conn, static BOOL get_lanman2_dir_entry(connection_struct *conn,
void *inbuf, void *outbuf, void *inbuf, void *outbuf,
char *path_mask,int dirtype,int info_level, char *path_mask,int dirtype,int info_level,
@@ -324,6 +329,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
int prev_dirpos=0; int prev_dirpos=0;
int mode=0; int mode=0;
SMB_OFF_T size = 0; SMB_OFF_T size = 0;
SMB_OFF_T allocation_size = 0;
uint32 len; uint32 len;
time_t mdate=0, adate=0, cdate=0; time_t mdate=0, adate=0, cdate=0;
char *nameptr; char *nameptr;
@@ -339,18 +345,15 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
return(False); return(False);
p = strrchr_m(path_mask,'/'); p = strrchr_m(path_mask,'/');
if(p != NULL) if(p != NULL) {
{
if(p[1] == '\0') if(p[1] == '\0')
pstrcpy(mask,"*.*"); pstrcpy(mask,"*.*");
else else
pstrcpy(mask, p+1); pstrcpy(mask, p+1);
} } else
else
pstrcpy(mask, path_mask); pstrcpy(mask, path_mask);
while (!found) while (!found) {
{
BOOL got_match; BOOL got_match;
/* Needed if we run out of space */ /* Needed if we run out of space */
@@ -374,9 +377,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(fname,dname); pstrcpy(fname,dname);
if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) { if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
got_match = mask_match(fname, mask, case_sensitive); got_match = mask_match(fname, mask, case_sensitive);
}
if(!got_match && !is_8_3(fname, False)) { if(!got_match && !is_8_3(fname, False)) {
@@ -394,8 +396,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
got_match = mask_match(newname, mask, case_sensitive); got_match = mask_match(newname, mask, case_sensitive);
} }
if(got_match) if(got_match) {
{
BOOL isdots = (strequal(fname,"..") || strequal(fname,".")); BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
if (dont_descend && !isdots) if (dont_descend && !isdots)
continue; continue;
@@ -404,19 +405,17 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
if(needslash) if(needslash)
pstrcat(pathreal,"/"); pstrcat(pathreal,"/");
pstrcat(pathreal,dname); pstrcat(pathreal,dname);
if (vfs_stat(conn,pathreal,&sbuf) != 0)
{ if (vfs_stat(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as directories */ /* Needed to show the msdfs symlinks as directories */
if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn)) if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
|| !is_msdfs_link(conn, pathreal)) || !is_msdfs_link(conn, pathreal)) {
{
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n", DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
pathreal,strerror(errno))); pathreal,strerror(errno)));
continue; continue;
} } else {
else DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n",
{ pathreal));
DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR; sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
} }
} }
@@ -429,6 +428,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
} }
size = sbuf.st_size; size = sbuf.st_size;
allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
mdate = sbuf.st_mtime; mdate = sbuf.st_mtime;
adate = sbuf.st_atime; adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@@ -455,8 +455,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL; nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
switch (info_level) switch (info_level) {
{
case 1: case 1:
if(requires_resume_key) { if(requires_resume_key) {
SIVAL(p,0,reskey); SIVAL(p,0,reskey);
@@ -466,7 +465,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l1_fdateLastAccess,adate); put_dos_date2(p,l1_fdateLastAccess,adate);
put_dos_date2(p,l1_fdateLastWrite,mdate); put_dos_date2(p,l1_fdateLastWrite,mdate);
SIVAL(p,l1_cbFile,(uint32)size); SIVAL(p,l1_cbFile,(uint32)size);
SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024)); SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l1_attrFile,mode); SSVAL(p,l1_attrFile,mode);
p += l1_achName; p += l1_achName;
nameptr = p; nameptr = p;
@@ -477,7 +476,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
break; break;
case 2: case 2:
/* info_level 2 */
if(requires_resume_key) { if(requires_resume_key) {
SIVAL(p,0,reskey); SIVAL(p,0,reskey);
p += 4; p += 4;
@@ -486,13 +484,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l2_fdateLastAccess,adate); put_dos_date2(p,l2_fdateLastAccess,adate);
put_dos_date2(p,l2_fdateLastWrite,mdate); put_dos_date2(p,l2_fdateLastWrite,mdate);
SIVAL(p,l2_cbFile,(uint32)size); SIVAL(p,l2_cbFile,(uint32)size);
SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024)); SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l2_attrFile,mode); SSVAL(p,l2_attrFile,mode);
SIVAL(p,l2_cbList,0); /* No extended attributes */ SIVAL(p,l2_cbList,0); /* No extended attributes */
p += l2_achName; p += l2_achName;
nameptr = p; nameptr = p;
len = srvstr_push(outbuf, p, fname, -1, len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
STR_NOALIGN);
SCVAL(p, -1, len); SCVAL(p, -1, len);
p += len; p += len;
*p++ = 0; /* craig from unisys pointed out we need this */ *p++ = 0; /* craig from unisys pointed out we need this */
@@ -507,7 +504,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size); SOFF_T(p,0,size);
SOFF_T(p,8,size); SOFF_T(p,8,allocation_size);
p += 16; p += 16;
SIVAL(p,0,nt_extmode); p += 4; SIVAL(p,0,nt_extmode); p += 4;
q = p; p += 4; q = p; p += 4;
@@ -541,7 +538,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size); SOFF_T(p,0,size);
SOFF_T(p,8,size); SOFF_T(p,8,allocation_size);
p += 16; p += 16;
SIVAL(p,0,nt_extmode); p += 4; SIVAL(p,0,nt_extmode); p += 4;
p += 4; p += 4;
@@ -554,7 +551,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p = pdata + len; p = pdata + len;
break; break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO: case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
p += 4; p += 4;
SIVAL(p,0,reskey); p += 4; SIVAL(p,0,reskey); p += 4;
@@ -563,7 +559,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8; put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size); SOFF_T(p,0,size);
SOFF_T(p,8,size); SOFF_T(p,8,allocation_size);
p += 16; p += 16;
SIVAL(p,0,nt_extmode); p += 4; SIVAL(p,0,nt_extmode); p += 4;
p += 4; p += 4;
@@ -613,7 +609,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
return(found); return(found);
} }
/**************************************************************************** /****************************************************************************
Reply to a TRANS2_FINDFIRST. Reply to a TRANS2_FINDFIRST.
****************************************************************************/ ****************************************************************************/
@@ -839,10 +834,10 @@ static int call_trans2findfirst(connection_struct *conn,
return(-1); return(-1);
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_FINDNEXT Reply to a TRANS2_FINDNEXT.
****************************************************************************/ ****************************************************************************/
static int call_trans2findnext(connection_struct *conn, static int call_trans2findnext(connection_struct *conn,
char *inbuf, char *outbuf, char *inbuf, char *outbuf,
int length, int bufsize, int length, int bufsize,
@@ -1092,7 +1087,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_QFSINFO (query filesystem info) Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/ ****************************************************************************/
static int call_trans2qfsinfo(connection_struct *conn, static int call_trans2qfsinfo(connection_struct *conn,
@@ -1225,8 +1220,9 @@ static int call_trans2qfsinfo(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_SETFSINFO (set filesystem info) Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/ ****************************************************************************/
static int call_trans2setfsinfo(connection_struct *conn, static int call_trans2setfsinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length, char *inbuf, char *outbuf, int length,
int bufsize, int bufsize,
@@ -1263,6 +1259,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 info_level; uint16 info_level;
int mode=0; int mode=0;
SMB_OFF_T size=0; SMB_OFF_T size=0;
SMB_OFF_T allocation_size=0;
unsigned int data_size; unsigned int data_size;
SMB_STRUCT_STAT sbuf; SMB_STRUCT_STAT sbuf;
pstring fname; pstring fname;
@@ -1307,8 +1304,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pstrcpy(fname, fsp->fsp_name); 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", DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid)); return(UNIXERROR(ERRDOS,ERRbadfid));
} }
if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
@@ -1320,8 +1316,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/* qpathinfo */ /* qpathinfo */
info_level = SVAL(params,0); info_level = SVAL(params,0);
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
info_level));
srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE); srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE);
@@ -1344,27 +1339,27 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
fname,info_level,tran_call,total_data)); fname,info_level,tran_call,total_data));
p = strrchr_m(fname,'/'); p = strrchr_m(fname,'/');
if (!p) { if (!p)
base_name = fname; base_name = fname;
} else { else
base_name = p+1; base_name = p+1;
}
mode = dos_mode(conn,fname,&sbuf); mode = dos_mode(conn,fname,&sbuf);
size = sbuf.st_size; size = sbuf.st_size;
if (mode & aDIR) size = 0; allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
if (mode & aDIR)
size = 0;
params = Realloc(*pparams,2); params = Realloc(*pparams,2);
if (params == NULL) { if (params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem); return ERROR_DOS(ERRDOS,ERRnomem);
}
*pparams = params; *pparams = params;
memset((char *)params,'\0',2); memset((char *)params,'\0',2);
data_size = max_data_bytes + 1024; data_size = max_data_bytes + 1024;
pdata = Realloc(*ppdata, data_size); pdata = Realloc(*ppdata, data_size);
if ( pdata == NULL ) { if ( pdata == NULL )
return ERROR_DOS(ERRDOS,ERRnomem); return ERROR_DOS(ERRDOS,ERRnomem);
}
*ppdata = pdata; *ppdata = pdata;
if (total_data > 0 && IVAL(pdata,0) == total_data) { if (total_data > 0 && IVAL(pdata,0) == total_data) {
@@ -1384,8 +1379,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
sbuf.st_mtime &= ~1; sbuf.st_mtime &= ~1;
} }
switch (info_level) switch (info_level) {
{
case SMB_INFO_STANDARD: case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE: case SMB_INFO_QUERY_EA_SIZE:
data_size = (info_level==1?22:26); data_size = (info_level==1?22:26);
@@ -1393,7 +1387,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
SIVAL(pdata,l1_cbFile,(uint32)size); SIVAL(pdata,l1_cbFile,(uint32)size);
SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024)); SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode); SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */ SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
break; break;
@@ -1404,7 +1398,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,4,sbuf.st_atime); put_dos_date2(pdata,4,sbuf.st_atime);
put_dos_date2(pdata,8,sbuf.st_mtime); put_dos_date2(pdata,8,sbuf.st_mtime);
SIVAL(pdata,12,(uint32)size); SIVAL(pdata,12,(uint32)size);
SIVAL(pdata,16,SMB_ROUNDUP(size,1024)); SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode); SIVAL(pdata,20,mode);
break; break;
@@ -1447,7 +1441,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_STANDARD_INFO: case SMB_QUERY_FILE_STANDARD_INFO:
data_size = 24; data_size = 24;
/* Fake up allocation size. */ /* Fake up allocation size. */
SOFF_T(pdata,0,SMB_ROUNDUP(size + 1, ((SMB_OFF_T)0x100000))); SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size); SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink); SIVAL(pdata,16,sbuf.st_nlink);
CVAL(pdata,20) = 0; CVAL(pdata,20) = 0;
@@ -1466,17 +1460,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pstrcpy(short_name,base_name); pstrcpy(short_name,base_name);
/* Mangle if not already 8.3 */ /* Mangle if not already 8.3 */
if(!is_8_3(short_name, True)) if(!is_8_3(short_name, True)) {
{
if(!name_map_mangle(short_name,True,True,SNUM(conn))) if(!name_map_mangle(short_name,True,True,SNUM(conn)))
*short_name = '\0'; *short_name = '\0';
} }
len = srvstr_push(outbuf, pdata+4, short_name, -1, len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
STR_TERMINATE|STR_UPPER);
data_size = 4 + len; data_size = 4 + len;
SIVAL(pdata,0,len); SIVAL(pdata,0,len);
}
break; break;
}
case SMB_QUERY_FILE_NAME_INFO: case SMB_QUERY_FILE_NAME_INFO:
/* /*
@@ -1494,14 +1486,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,0,len); SIVAL(pdata,0,len);
break; break;
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_FILE_END_OF_FILE_INFORMATION: case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
case SMB_QUERY_FILE_END_OF_FILEINFO: case SMB_QUERY_FILE_END_OF_FILEINFO:
data_size = 8; data_size = 8;
SOFF_T(pdata,0,size); SOFF_T(pdata,0,size);
break; break;
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
data_size = 8;
SOFF_T(pdata,0,allocation_size);
break;
case SMB_QUERY_FILE_ALL_INFO: case SMB_QUERY_FILE_ALL_INFO:
put_long_date(pdata,c_time); put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+8,sbuf.st_atime);
@@ -1509,7 +1505,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+24,sbuf.st_mtime); /* change time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,mode); SIVAL(pdata,32,mode);
pdata += 40; pdata += 40;
SOFF_T(pdata,0,size); SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size); SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink); SIVAL(pdata,16,sbuf.st_nlink);
CVAL(pdata,20) = delete_pending; CVAL(pdata,20) = delete_pending;
@@ -1622,7 +1618,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,0,0); /* ??? */ SIVAL(pdata,0,0); /* ??? */
SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
SOFF_T(pdata,8,size); SOFF_T(pdata,8,size);
SIVAL(pdata,16,0x20); /* ??? */ SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */ SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len; data_size = 24 + byte_len;
} }
@@ -1640,8 +1636,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,0x20); /* ??? */ SIVAL(pdata,32,allocation_size);
SIVAL(pdata,36,0); /* ??? */
SOFF_T(pdata,40,size); SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode); SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */ SIVAL(pdata,52,0); /* ??? */
@@ -1654,17 +1649,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
data_size = 8; data_size = 8;
break; break;
/*
* End new completely undocumented info levels... JRA.
*/
#if 0 #if 0
/* NT4 server just returns "invalid query" to this - if we try to answer /* NT4 server just returns "invalid query" to this - if we try to answer
it then NTws gets a BSOD! (tridge) */ it then NTws gets a BSOD! (tridge) */
case SMB_QUERY_FILE_STREAM_INFO: case SMB_QUERY_FILE_STREAM_INFO:
SIVAL(pdata,0,pos); SIVAL(pdata,0,pos);
SIVAL(pdata,4,size); SIVAL(pdata,4,(uint32)size);
SIVAL(pdata,12,size); SIVAL(pdata,12,(uint32)allocation_size);
len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE); len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
SIVAL(pdata,20,len); SIVAL(pdata,20,len);
data_size = 24 + len; data_size = 24 + len;
@@ -1681,8 +1672,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_SETFILEINFO (set file info by fileid) Reply to a TRANS2_SETFILEINFO (set file info by fileid).
****************************************************************************/ ****************************************************************************/
static int call_trans2setfilepathinfo(connection_struct *conn, static int call_trans2setfilepathinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length, char *inbuf, char *outbuf, int length,
int bufsize, char **pparams, int bufsize, char **pparams,
@@ -1715,8 +1707,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
unix_convert(fname,conn,0,&bad_path,&sbuf); unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) { if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path) if((errno == ENOENT) && bad_path) {
{
unix_ERR_class = ERRDOS; unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath; unix_ERR_code = ERRbadpath;
} }
@@ -1729,8 +1720,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
fsp->share_mode = FILE_DELETE_ON_CLOSE; fsp->share_mode = FILE_DELETE_ON_CLOSE;
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
fsp->fsp_name ));
SSVAL(params,0,0); SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -1755,10 +1745,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
info_level = SVAL(params,0); info_level = SVAL(params,0);
srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE); srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE);
unix_convert(fname,conn,0,&bad_path,&sbuf); unix_convert(fname,conn,0,&bad_path,&sbuf);
if(!check_name(fname, conn)) if(!check_name(fname, conn)) {
{ if((errno == ENOENT) && bad_path) {
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS; unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath; unix_ERR_code = ERRbadpath;
} }
@@ -1767,8 +1755,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if(!VALID_STAT(sbuf)) { if(!VALID_STAT(sbuf)) {
DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno))); DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
if((errno == ENOENT) && bad_path) if((errno == ENOENT) && bad_path) {
{
unix_ERR_class = ERRDOS; unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath; unix_ERR_code = ERRbadpath;
} }
@@ -1784,9 +1771,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* Realloc the parameter and data sizes */ /* Realloc the parameter and data sizes */
params = Realloc(*pparams,2); params = Realloc(*pparams,2);
if(params == NULL) { if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem); return ERROR_DOS(ERRDOS,ERRnomem);
}
*pparams = params; *pparams = params;
SSVAL(params,0,0); SSVAL(params,0,0);
@@ -1802,8 +1788,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
return ERROR_DOS(ERRDOS,ERReasnotsupported); return ERROR_DOS(ERRDOS,ERReasnotsupported);
} }
switch (info_level) switch (info_level) {
{
case SMB_INFO_STANDARD: case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE: case SMB_INFO_QUERY_EA_SIZE:
{ {
@@ -1856,33 +1841,32 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* Prefer a defined time to an undefined one. */ /* Prefer a defined time to an undefined one. */
if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1) if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
? changed_time ? changed_time : write_time);
: write_time);
/* attributes */ /* attributes */
mode = IVAL(pdata,32); mode = IVAL(pdata,32);
break; break;
} }
case 1019: case SMB_FILE_ALLOCATION_INFORMATION:
case 1020:
case SMB_SET_FILE_ALLOCATION_INFO: case SMB_SET_FILE_ALLOCATION_INFO:
{ {
int ret = -1; int ret = -1;
size = IVAL(pdata,0); SMB_OFF_T allocation_size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T #ifdef LARGE_SMB_OFF_T
size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */ #else /* LARGE_SMB_OFF_T */
if (IVAL(pdata,4) != 0) /* more than 32 bits? */ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return ERROR_DOS(ERRDOS,ERRunknownlevel); return ERROR_DOS(ERRDOS,ERRunknownlevel);
#endif /* LARGE_SMB_OFF_T */ #endif /* LARGE_SMB_OFF_T */
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
fname, (double)size )); fname, (double)allocation_size ));
if(size != sbuf.st_size) { if(allocation_size != sbuf.st_size) {
SMB_STRUCT_STAT new_sbuf;
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n", DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
fname, (double)size )); fname, (double)allocation_size ));
if (fd == -1) { if (fd == -1) {
files_struct *new_fsp = NULL; files_struct *new_fsp = NULL;
@@ -1906,14 +1890,24 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (new_fsp == NULL) if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath)); return(UNIXERROR(ERRDOS,ERRbadpath));
ret = vfs_allocate_file_space(new_fsp, size); ret = vfs_allocate_file_space(new_fsp, allocation_size);
if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
ret = -1;
}
close_file(new_fsp,True); close_file(new_fsp,True);
} else { } else {
ret = vfs_allocate_file_space(fsp, size); ret = vfs_allocate_file_space(fsp, size);
if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
ret = -1;
} }
if (ret == -1) return ERROR_NT(NT_STATUS_DISK_FULL); }
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
sbuf.st_size = size; /* Allocate can trucate size... */
size = new_sbuf.st_size;
} }
break; break;
@@ -2020,10 +2014,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
} }
default: default:
{
return ERROR_DOS(ERRDOS,ERRunknownlevel); return ERROR_DOS(ERRDOS,ERRunknownlevel);
} }
}
/* get some defaults (no modifications) if any info is zero or -1. */ /* get some defaults (no modifications) if any info is zero or -1. */
if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1) if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
@@ -2041,6 +2033,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
(info_level == SMB_SET_FILE_ALLOCATION_INFO) || (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
(info_level == SMB_FILE_ALLOCATION_INFORMATION) || (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
(info_level == SMB_FILE_END_OF_FILE_INFORMATION))) { (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
/* /*
* Only do this test if we are not explicitly * Only do this test if we are not explicitly
* changing the size of a file. * changing the size of a file.
@@ -2049,8 +2042,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
size = sbuf.st_size; size = sbuf.st_size;
} }
/* Try and set the times, size and mode of this file - /*
if they are different from the current values * Try and set the times, size and mode of this file -
* if they are different from the current values
*/ */
if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) { if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
if(fsp != NULL) { if(fsp != NULL) {
@@ -2063,8 +2057,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
*/ */
if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) { if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
ctime(&tvs.modtime) ));
fsp->pending_modtime = tvs.modtime; fsp->pending_modtime = tvs.modtime;
} }
@@ -2080,8 +2073,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* check the mode isn't different, before changing it */ /* check the mode isn't different, before changing it */
if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) { if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
fname, mode ));
if(file_chmod(conn, fname, mode, NULL)) { if(file_chmod(conn, fname, mode, NULL)) {
DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno))); DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
@@ -2131,8 +2123,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_MKDIR (make directory with extended attributes). Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/ ****************************************************************************/
static int call_trans2mkdir(connection_struct *conn, static int call_trans2mkdir(connection_struct *conn,
char *inbuf, char *outbuf, int length, int bufsize, char *inbuf, char *outbuf, int length, int bufsize,
char **pparams, char **ppdata) char **pparams, char **ppdata)
@@ -2180,9 +2173,10 @@ static int call_trans2mkdir(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes) Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
We don't actually do this - we just send a null response. We don't actually do this - we just send a null response.
****************************************************************************/ ****************************************************************************/
static int call_trans2findnotifyfirst(connection_struct *conn, static int call_trans2findnotifyfirst(connection_struct *conn,
char *inbuf, char *outbuf, char *inbuf, char *outbuf,
int length, int bufsize, int length, int bufsize,
@@ -2225,9 +2219,10 @@ static int call_trans2findnotifyfirst(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
changes). Currently this does nothing. changes). Currently this does nothing.
****************************************************************************/ ****************************************************************************/
static int call_trans2findnotifynext(connection_struct *conn, static int call_trans2findnotifynext(connection_struct *conn,
char *inbuf, char *outbuf, char *inbuf, char *outbuf,
int length, int bufsize, int length, int bufsize,
@@ -2253,8 +2248,9 @@ static int call_trans2findnotifynext(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com> Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/ ****************************************************************************/
static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
char* outbuf, int length, int bufsize, char* outbuf, int length, int bufsize,
char** pparams, char** ppdata) char** pparams, char** ppdata)
@@ -2285,7 +2281,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
#define LMFUNC_GETJOBID 0x60 #define LMFUNC_GETJOBID 0x60
/**************************************************************************** /****************************************************************************
reply to a TRANS2_IOCTL - used for OS/2 printing. Reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/ ****************************************************************************/
static int call_trans2ioctl(connection_struct *conn, char* inbuf, static int call_trans2ioctl(connection_struct *conn, char* inbuf,
@@ -2318,8 +2314,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
} }
/**************************************************************************** /****************************************************************************
reply to a SMBfindclose (stop trans2 directory search) Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/ ****************************************************************************/
int reply_findclose(connection_struct *conn, int reply_findclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize) char *inbuf,char *outbuf,int length,int bufsize)
{ {
@@ -2340,8 +2337,9 @@ int reply_findclose(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search) Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/ ****************************************************************************/
int reply_findnclose(connection_struct *conn, int reply_findnclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize) char *inbuf,char *outbuf,int length,int bufsize)
{ {
@@ -2365,10 +2363,10 @@ int reply_findnclose(connection_struct *conn,
return(outsize); return(outsize);
} }
/**************************************************************************** /****************************************************************************
reply to a SMBtranss2 - just ignore it! Reply to a SMBtranss2 - just ignore it!
****************************************************************************/ ****************************************************************************/
int reply_transs2(connection_struct *conn, int reply_transs2(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize) char *inbuf,char *outbuf,int length,int bufsize)
{ {
@@ -2379,8 +2377,9 @@ int reply_transs2(connection_struct *conn,
} }
/**************************************************************************** /****************************************************************************
reply to a SMBtrans2 Reply to a SMBtrans2.
****************************************************************************/ ****************************************************************************/
int reply_trans2(connection_struct *conn, int reply_trans2(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize) char *inbuf,char *outbuf,int length,int bufsize)
{ {

View File

@@ -283,12 +283,13 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
size_t total=0; size_t total=0;
ssize_t ret; ssize_t ret;
while (total < N) while (total < N) {
{
ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total); ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
if (ret == -1) return -1; if (ret == -1)
if (ret == 0) return total; return -1;
if (ret == 0)
return total;
total += ret; total += ret;
} }
@@ -305,10 +306,15 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
{ {
int ret; int ret;
SMB_STRUCT_STAT st; SMB_STRUCT_STAT st;
struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops; connection_struct *conn = fsp->conn;
struct vfs_ops *vfs_ops = &conn->vfs_ops;
SMB_OFF_T space_avail;
SMB_BIG_UINT bsize,dfree,dsize;
#if 0
if (!lp_strict_allocate(SNUM(fsp->conn))) if (!lp_strict_allocate(SNUM(fsp->conn)))
return vfs_set_filelen(fsp, len); return vfs_set_filelen(fsp, len);
#endif
release_level_2_oplocks_on_change(fsp); release_level_2_oplocks_on_change(fsp);
@@ -337,41 +343,20 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
return ret; return ret;
} }
/* Grow - we need to write out the space.... */ /* Grow - we need to test if we have enough space. */
{
static unsigned char zero_space[65536];
SMB_OFF_T start_pos = st.st_size; len -= st.st_size;
SMB_OFF_T len_to_write = len - st.st_size; len /= 1024; /* Len is now number of 1k blocks needed. */
SMB_OFF_T retlen; space_avail = (SMB_OFF_T)conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f\n", DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %lu, space avail = %lu\n",
fsp->fsp_name, (double)st.st_size )); fsp->fsp_name, (double)st.st_size, (unsigned long)len, (unsigned long)space_avail ));
if ((retlen = vfs_ops->lseek(fsp, fsp->fd, start_pos, SEEK_SET)) != start_pos) if (len > space_avail) {
return -1; errno = ENOSPC;
while ( len_to_write > 0) {
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),len_to_write);
retlen = vfs_ops->write(fsp,fsp->fd,(const char *)zero_space,current_len_to_write);
if (retlen <= 0) {
/* Write fail - return to original size. */
int save_errno = errno;
fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, st.st_size);
errno = save_errno;
DEBUG(10,("vfs_allocate_file_space: file %s, grow. write fail %s\n",
fsp->fsp_name, strerror(errno) ));
return -1; return -1;
} }
DEBUG(10,("vfs_allocate_file_space: file %s, grow. wrote %.0f\n",
fsp->fsp_name, (double)retlen ));
len_to_write -= retlen;
}
set_filelen_write_cache(fsp, len);
}
return 0; return 0;
} }