summaryrefslogtreecommitdiff
path: root/source3/smbd/trans2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/trans2.c')
-rw-r--r--source3/smbd/trans2.c353
1 files changed, 260 insertions, 93 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index de598d6713..bdcd04443e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-2001
+ Copyright (C) Jeremy Allison 1994-2001
+ Copyright (C) Stefan (metze) Metzmacher 2003
Extensively modified by Andrew Tridgell, 1995
@@ -28,6 +29,7 @@ extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
extern uint32 global_client_caps;
+extern struct current_user current_user;
#define get_file_size(sbuf) ((sbuf).st_size)
@@ -324,7 +326,7 @@ static BOOL exact_match(char *str,char *mask, BOOL case_sig)
return False;
if (case_sig)
return strcmp(str,mask)==0;
- return strcasecmp(str,mask) == 0;
+ return StrCaseCmp(str,mask) == 0;
}
/****************************************************************************
@@ -549,12 +551,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcat(pathreal,dname);
if (INFO_LEVEL_IS_UNIX(info_level)) {
- if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
+ if (SMB_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 (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as
* directories */
@@ -647,8 +649,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,l2_cbList,0); /* No extended attributes */
p += l2_achName;
nameptr = p;
- p += align_string(outbuf, p, 0);
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
SCVAL(nameptr, -1, len-2);
else
@@ -680,14 +681,14 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(mangled_name, fname);
mangle_map(mangled_name,True,True,SNUM(conn));
mangled_name[12] = 0;
- len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
+ len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
SSVAL(p, 0, len);
} else {
SSVAL(p,0,0);
*(p+2) = 0;
}
p += 2 + 24;
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(q,0,len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -708,7 +709,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
p += 4;
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(p, -4, len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -727,13 +728,13 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SOFF_T(p,0,file_size);
SOFF_T(p,8,allocation_size);
p += 16;
- SIVAL(p,0,nt_extmode); p += 4;
+ SIVAL(p,0,nt_extmode);
p += 4;
- SIVAL(p,0,0); p += 4;
- len = srvstr_push(outbuf, p, fname, -1, 0);
- SIVAL(p, -4, len);
- p += len;
+ SIVAL(p,4,0); /* ea size */
+ len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII);
+ SIVAL(p, 0, len);
+ p += 8 + len;
len = PTR_DIFF(p, pdata);
len = (len + 3) & ~3;
@@ -747,7 +748,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p += 4;
/* this must *not* be null terminated or w2k gets in a loop trying to set an
acl on a dir (tridge) */
- len = srvstr_push(outbuf, p, fname, -1, 0);
+ len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(p, -4, len);
p += len;
len = PTR_DIFF(p, pdata);
@@ -1318,10 +1319,11 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
+ int quota_flag = 0;
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
- if(vfs_stat(conn,".",&st)!=0) {
+ if(SMB_VFS_STAT(conn,".",&st)!=0) {
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
@@ -1338,7 +1340,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SMB_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);
@@ -1357,7 +1359,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
* the called hostname and the service name.
*/
SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
- len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 0);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
@@ -1367,19 +1369,26 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
+
+#if defined(HAVE_SYS_QUOTAS)
+ quota_flag = FILE_VOLUME_QUOTAS;
+#endif
+
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
+ (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
+ quota_flag); /* FS ATTRIBUTES */
+
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
and will think we can't do long filenames */
- len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
+ len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
SIVAL(pdata,8,len);
data_len = 12 + len;
break;
case SMB_QUERY_FS_LABEL_INFO:
case SMB_FS_LABEL_INFORMATION:
- len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
data_len = 4 + len;
SIVAL(pdata,0,len);
break;
@@ -1394,7 +1403,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
(str_checksum(local_machine)<<16));
- len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
SIVAL(pdata,12,len);
data_len = 18+len;
DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
@@ -1406,7 +1415,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
{
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);
+ SMB_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;
@@ -1436,7 +1445,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
{
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);
+ SMB_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;
@@ -1470,6 +1479,78 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
SIVAL(pdata,4,0); /* characteristics */
break;
+#ifdef HAVE_SYS_QUOTAS
+ case SMB_FS_QUOTA_INFORMATION:
+ /*
+ * what we have to send --metze:
+ *
+ * Unknown1: 24 NULL bytes
+ * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
+ * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
+ * Quota Flags: 2 byte :
+ * Unknown3: 6 NULL bytes
+ *
+ * 48 bytes total
+ *
+ * details for Quota Flags:
+ *
+ * 0x0020 Log Limit: log if the user exceeds his Hard Quota
+ * 0x0010 Log Warn: log if the user exceeds his Soft Quota
+ * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
+ * 0x0001 Enable Quotas: enable quota for this fs
+ *
+ */
+ {
+ /* we need to fake up a fsp here,
+ * because its not send in this call
+ */
+ files_struct fsp;
+ SMB_NTQUOTA_STRUCT quotas;
+
+ ZERO_STRUCT(fsp);
+ ZERO_STRUCT(quotas);
+
+ fsp.conn = conn;
+ fsp.fnum = -1;
+ fsp.fd = -1;
+
+ /* access check */
+ if (conn->admin_user != True) {
+ DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
+ DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ data_len = 48;
+
+ DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
+
+ /* Unknown1 24 NULL bytes*/
+ SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
+ SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
+ SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
+
+ /* Default Soft Quota 8 bytes */
+ SBIG_UINT(pdata,24,quotas.softlim);
+
+ /* Default Hard Quota 8 bytes */
+ SBIG_UINT(pdata,32,quotas.hardlim);
+
+ /* Quota flag 2 bytes */
+ SSVAL(pdata,40,quotas.qflags);
+
+ /* Unknown3 6 NULL bytes */
+ SSVAL(pdata,42,0);
+ SIVAL(pdata,44,0);
+
+ break;
+ }
+#endif /* HAVE_SYS_QUOTAS */
case SMB_FS_OBJECTID_INFORMATION:
data_len = 64;
break;
@@ -1511,6 +1592,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return -1;
}
+#ifdef HAVE_SYS_QUOTAS
/****************************************************************************
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
@@ -1519,18 +1601,110 @@ static int call_trans2setfsinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length, int bufsize,
char **pparams, int total_params, char **ppdata, int total_data)
{
- /* Just say yes we did it - there is nothing that
- can be set here so it doesn't matter. */
+ char *pdata = *ppdata;
+ char *params = *pparams;
+ files_struct *fsp = NULL;
+ uint16 info_level;
int outsize;
- DEBUG(3,("call_trans2setfsinfo\n"));
+ SMB_NTQUOTA_STRUCT quotas;
+
+ ZERO_STRUCT(quotas);
- if (!CAN_WRITE(conn))
+ DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
+
+ /* access check */
+ if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
+ DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
+ lp_servicename(SNUM(conn)),conn->user));
return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+
+ /* */
+ if (total_params < 4) {
+ DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
+ total_params));
+ return ERROR_DOS(ERRDOS,ERRinvalidparam);
+ }
+
+ fsp = file_fsp(params,0);
+
+ if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
+ DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+ info_level = SVAL(params,2);
+
+ switch(info_level) {
+ case SMB_FS_QUOTA_INFORMATION:
+ /* note: normaly there're 48 bytes,
+ * but we didn't use the last 6 bytes for now
+ * --metze
+ */
+ if (total_data < 42) {
+ DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
+ total_data));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ /* unknown_1 24 NULL bytes in pdata*/
+
+ /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
+ quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
+#ifdef LARGE_SMB_OFF_T
+ quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,28) != 0)&&
+ ((quotas.softlim != 0xFFFFFFFF)||
+ (IVAL(pdata,28)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
+ quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
+#ifdef LARGE_SMB_OFF_T
+ quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if ((IVAL(pdata,36) != 0)&&
+ ((quotas.hardlim != 0xFFFFFFFF)||
+ (IVAL(pdata,36)!=0xFFFFFFFF))) {
+ /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+#endif /* LARGE_SMB_OFF_T */
+
+ /* quota_flags 2 bytes **/
+ quotas.qflags = SVAL(pdata,40);
+
+ /* unknown_2 6 NULL bytes follow*/
+
+ /* now set the quotas */
+ if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
+ DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ break;
+ default:
+ DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
+ info_level));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ break;
+ }
+
+ /*
+ * sending this reply works fine,
+ * but I'm not sure it's the same
+ * like windows do...
+ * --metze
+ */
outsize = set_message(outbuf,10,0,True);
return outsize;
}
+#endif /* HAVE_SYS_QUOTAS */
/****************************************************************************
* Utility function to set bad path error.
@@ -1589,7 +1763,20 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
- if(fsp && (fsp->is_directory || fsp->fd == -1)) {
+ if(fsp && (fsp->fake_file_handle)) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ pstrcpy(fname, fsp->fsp_name);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn)) {
+ DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
@@ -1605,13 +1792,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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 (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_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) && SMB_VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1624,11 +1811,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
CHECK_FSP(fsp,conn);
pstrcpy(fname, fsp->fsp_name);
- if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ if (SMB_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 = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
delete_pending = fsp->delete_on_close;
@@ -1655,13 +1842,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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 (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_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) && SMB_VFS_STAT(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1733,9 +1920,17 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,l1_cbFile,(uint32)file_size);
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
- SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
+ SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */
break;
+ case SMB_INFO_IS_NAME_VALID:
+ if (tran_call == TRANSACT2_QFILEINFO) {
+ /* os/2 needs this ? really ?*/
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+ }
+ data_size = 0;
+ break;
+
case SMB_INFO_QUERY_EAS_FROM_LIST:
data_size = 24;
put_dos_date2(pdata,0,c_time);
@@ -1748,12 +1943,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_INFO_QUERY_ALL_EAS:
data_size = 4;
- SIVAL(pdata,0,data_size);
+ SIVAL(pdata,0,0); /* ea size */
break;
- case 6:
- return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
-
case SMB_FILE_BASIC_INFORMATION:
case SMB_QUERY_FILE_BASIC_INFO:
@@ -1836,6 +2028,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_QUERY_FILE_ALL_INFO:
+ case SMB_FILE_ALL_INFORMATION:
put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
@@ -1848,20 +2041,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
pdata += 24;
- SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
- pdata += 8; /* index number */
pdata += 4; /* EA info */
- if (mode & aRONLY)
- SIVAL(pdata,0,0xA9);
- else
- SIVAL(pdata,0,0xd01BF);
- pdata += 4;
- SOFF_T(pdata,0,pos); /* current offset */
- pdata += 8;
- SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
- pdata += 4;
- pdata += 4; /* alignment */
- len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
+ len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
SIVAL(pdata,0,len);
pdata += 4 + len;
data_size = PTR_DIFF(pdata,(*ppdata));
@@ -1915,28 +2096,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
#if 0
- /* Not yet finished... JRA */
- case 1018:
- {
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
- SIVAL(pdata,36,0); /* ??? */
- SIVAL(pdata,40,0x20); /* ??? */
- SIVAL(pdata,44,0); /* ??? */
- SOFF_T(pdata,48,size);
- SIVAL(pdata,56,0x1); /* ??? */
- SIVAL(pdata,60,0); /* ??? */
- SIVAL(pdata,64,0); /* ??? */
- SIVAL(pdata,68,length); /* Following string length in bytes. */
- dos_PutUniCode(pdata+72,,False);
- break;
- }
-#endif
-
-#if 0
/*
* NT4 server just returns "invalid query" to this - if we try to answer
* it then NTws gets a BSOD! (tridge).
@@ -1958,8 +2117,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
break;
+ case SMB_QUERY_COMPRESSION_INFO:
case SMB_FILE_COMPRESSION_INFORMATION:
- SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,0,file_size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
@@ -2054,7 +2214,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
#else
return(UNIXERROR(ERRDOS,ERRbadlink));
#endif
- len = conn->vfs_ops.readlink(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
+ len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
if (len == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
buffer[len] = 0;
@@ -2178,7 +2338,7 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
pstrcpy(link_dest, "./");
}
- if (conn->vfs_ops.realpath(conn,link_dest,resolved_name) == NULL)
+ if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
return -1;
pstrcpy(link_dest, resolved_name);
@@ -2229,7 +2389,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
mode_t unixmode = 0;
+ if (!params)
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+
if (tran_call == TRANSACT2_SETFILEINFO) {
+ if (total_params < 4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
@@ -2269,7 +2435,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
pstrcpy(fname, fsp->fsp_name);
fd = fsp->fd;
- if (vfs_fstat(fsp,fd,&sbuf) != 0) {
+ if (SMB_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));
}
@@ -2461,7 +2627,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
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 (SMB_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;
@@ -2469,7 +2635,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
close_file(new_fsp,True);
} else {
ret = vfs_allocate_file_space(fsp, allocation_size);
- if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
+ if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
fsp->fnum, strerror(errno)));
ret = -1;
@@ -2609,7 +2775,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
inherit_access_acl(conn, fname, unixmode);
@@ -2628,7 +2794,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2639,7 +2805,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2650,7 +2816,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
break;
@@ -2677,7 +2843,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -2702,7 +2868,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
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 (SMB_VFS_LINK(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -2854,7 +3020,7 @@ static int call_trans2mkdir(connection_struct *conn,
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)));
@@ -3298,13 +3464,14 @@ int reply_trans2(connection_struct *conn,
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
+#ifdef HAVE_SYS_QUOTAS
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
&params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
-
+#endif
case TRANSACT2_QPATHINFO:
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);