*/
#include "includes.h"
+#include "version.h"
+#include "smbd/globals.h"
+#include "../libcli/auth/libcli_auth.h"
-extern int max_send;
extern enum protocol_types Protocol;
-extern uint32 global_client_caps;
-#define get_file_size(sbuf) ((sbuf).st_size)
#define DIR_ENTRY_SAFETY_MARGIN 4096
static char *store_file_unix_basic(connection_struct *conn,
return val;
}
-/********************************************************************
- Given a stat buffer return the allocated size on disk, taking into
- account sparse files.
-********************************************************************/
-
-uint64_t get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
-{
- uint64_t ret;
-
- if(S_ISDIR(sbuf->st_mode)) {
- return 0;
- }
-
-#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- ret = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
-#else
- ret = (uint64_t)get_file_size(*sbuf);
-#endif
-
- if (fsp && fsp->initial_allocation_size)
- ret = MAX(ret,fsp->initial_allocation_size);
-
- return smb_roundup(conn, ret);
-}
-
/****************************************************************************
Utility functions for dealing with extended attributes.
****************************************************************************/
static bool samba_private_attr_name(const char *unix_ea_name)
{
- static const char *prohibited_ea_names[] = {
+ static const char * const prohibited_ea_names[] = {
SAMBA_POSIX_INHERITANCE_EA_NAME,
SAMBA_XATTR_DOS_ATTRIB,
NULL
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)))
+ true, req->seqnum+1,
+ IS_CONN_ENCRYPTED(conn),
+ &req->pcd))
exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
uint32 create_options = 0;
TALLOC_CTX *ctx = talloc_tos();
+ SET_STAT_INVALID(sbuf);
+
/*
* Ensure we have enough parameters to perform the operation.
*/
return;
}
- size = get_file_size(sbuf);
+ size = get_file_size_stat(&sbuf);
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
- inode = sbuf.st_ino;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ inode = sbuf.st_ex_ino;
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
if (!VALID_STAT(*psbuf)) {
return NT_STATUS_INVALID_PARAMETER;
} else {
- *ret_perms = psbuf->st_mode;
+ *ret_perms = psbuf->st_ex_mode;
return NT_STATUS_OK;
}
}
DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
"as a directory\n",
pathname));
- psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR;
+ psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
errno = saved_errno;
return true;
}
int *last_entry_off,
struct ea_list *name_list)
{
- const char *dname;
+ char *dname;
bool found = False;
SMB_STRUCT_STAT sbuf;
const char *mask = NULL;
char *pathreal = NULL;
- const char *fname = NULL;
+ char *fname = NULL;
char *p, *q, *pdata = *ppdata;
uint32 reskey=0;
long prev_dirpos=0;
/* Mangle fname if it's an illegal name. */
if (mangle_must_mangle(dname,conn->params)) {
if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
+ TALLOC_FREE(fname);
continue; /* Error - couldn't mangle. */
}
- fname = mangled_name;
+ fname = talloc_strdup(ctx, mangled_name);
+ if (!fname) {
+ return False;
+ }
}
if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
*/
/* Force the mangling into 8.3. */
if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
+ TALLOC_FREE(fname);
continue; /* Error - couldn't mangle. */
}
bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
if (dont_descend && !isdots) {
+ TALLOC_FREE(fname);
continue;
}
}
if (!pathreal) {
+ TALLOC_FREE(fname);
return False;
}
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
TALLOC_FREE(pathreal);
+ TALLOC_FREE(fname);
continue;
}
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
pathreal,strerror(errno)));
TALLOC_FREE(pathreal);
+ TALLOC_FREE(fname);
continue;
}
}
if (!dir_check_ftype(conn,mode,dirtype)) {
DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
TALLOC_FREE(pathreal);
+ TALLOC_FREE(fname);
continue;
}
if (!(mode & aDIR)) {
- file_size = get_file_size(sbuf);
+ file_size = get_file_size_stat(&sbuf);
}
- allocation_size = get_allocation_size(conn,NULL,&sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
- mdate_ts = get_mtimespec(&sbuf);
- adate_ts = get_atimespec(&sbuf);
- create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ mdate_ts = sbuf.st_ex_mtime;
+ adate_ts = sbuf.st_ex_atime;
+ create_date_ts = sbuf.st_ex_btime;
if (ask_sharemode) {
struct timespec write_time_ts;
mdate = convert_timespec_to_time_t(mdate_ts);
adate = convert_timespec_to_time_t(adate_ts);
- DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",pathreal,fname));
+ DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
+ pathreal,fname));
found = True;
dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
}
+
+ if (!found)
+ TALLOC_FREE(fname);
}
p = pdata;
p +=4;
}
SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
}
p += 26;
SSVAL(p,0,0); p += 2; /* Reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
break;
default:
+ TALLOC_FREE(fname);
return(False);
}
-
+ TALLOC_FREE(fname);
if (PTR_DIFF(p,pdata) > space_remaining) {
/* Move the dirptr back to prev_dirpos */
dptr_SeekDir(conn->dirptr, prev_dirpos);
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
+ struct smb_filename *smb_dname = NULL;
char *params = *pparams;
char *pdata = *ppdata;
char *data_end;
bool out_of_space = False;
int space_remaining;
bool mask_contains_wcard = False;
- SMB_STRUCT_STAT sbuf;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
/* W2K3 seems to treat zero as 1. */
maxentries = 1;
}
-
+
switch (info_level) {
case SMB_FIND_INFO_STANDARD:
case SMB_FIND_EA_SIZE:
return;
}
- ntstatus = unix_convert(ctx, conn, directory, True, &directory, &mask, &sbuf);
+ ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
+ (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
+ if (!NT_STATUS_IS_OK(ntstatus)) {
+ reply_nterror(req, ntstatus);
+ return;
+ }
+
+ mask = smb_dname->original_lcomp;
+
+ ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
+ TALLOC_FREE(smb_dname);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
return;
}
params = *pparams;
- /* Save the wildcard match and attribs we are using on this directory -
+ /* Save the wildcard match and attribs we are using on this directory -
needed as lanman2 assumes these are being saved between calls */
ntstatus = dptr_create(conn,
dptr_num = dptr_dnum(conn->dirptr);
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
+ /* Initialize per TRANS2_FIND_FIRST operation data */
+ dptr_init_search_op(conn->dirptr);
+
/* We don't need to check for VOL here as this is returned by
a different TRANS2 call. */
for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
bool got_exact_match = False;
- /* this is a heuristic to avoid seeking the dirptr except when
+ /* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
if (space_remaining < DIRLEN_GUESS && numentries > 0) {
out_of_space = True;
(long)conn->dirptr,
dptr_TellDir(conn->dirptr)));
+ /* Initialize per TRANS2_FIND_NEXT operation data */
+ dptr_init_search_op(conn->dirptr);
+
/* We don't need to check for VOL here as this is returned by
a different TRANS2 call. */
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
uint32 additional_flags = 0;
-
+
if (total_params < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
sectors_per_unit = bsize/bytes_per_sector;
DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
-cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
+cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
- SIVAL(pdata,l1_idFileSystem,st.st_dev);
+ SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
SIVAL(pdata,l1_cUnit,dsize);
SIVAL(pdata,l1_cUnitAvail,dfree);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
- (unsigned)st.st_ctime, len, vname));
+ (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
+ len, vname));
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
*/
files_struct fsp;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(fsp);
ZERO_STRUCT(quotas);
-
+
fsp.conn = conn;
fsp.fnum = -1;
-
+
/* access check */
if (conn->server_info->utok.uid != 0) {
DEBUG(0,("set_user_quota: access_denied "
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
+
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, 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,(uint64_t)0);
SBIG_UINT(pdata,8,(uint64_t)0);
SBIG_UINT(pdata,16,(uint64_t)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_QUERY_CIFS_UNIX_INFO:
{
bool large_write = lp_min_receive_file_size() &&
- !srv_is_signing_active();
- bool large_read = !srv_is_signing_active();
+ !srv_is_signing_active(smbd_server_conn);
+ bool large_read = !srv_is_signing_active(smbd_server_conn);
int encrypt_caps = 0;
if (!lp_unix_extensions()) {
i < conn->server_info->ptok->num_sids; ++i) {
sid_bytes += ndr_size_dom_sid(
&conn->server_info->ptok->user_sids[i],
+ NULL,
0);
}
i < conn->server_info->ptok->num_sids; ++i) {
int sid_len = ndr_size_dom_sid(
&conn->server_info->ptok->user_sids[i],
+ NULL,
0);
sid_linearize(pdata + data_len, sid_len,
{
files_struct *fsp = NULL;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(quotas);
/* access check */
NT_STATUS_INVALID_PARAMETER);
return;
}
-
+
/* unknown_1 24 NULL bytes in pdata*/
-
+
/* the soft quotas 8 bytes (uint64_t)*/
quotas.softlim = (uint64_t)IVAL(pdata,24);
#ifdef LARGE_SMB_OFF_T
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
/* the hard quotas 8 bytes (uint64_t)*/
quotas.hardlim = (uint64_t)IVAL(pdata,32);
#ifdef LARGE_SMB_OFF_T
return;
}
#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, "as)!=0) {
DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, ERRSRV, ERRerror);
return;
}
-
+
break;
}
default:
switch (tagtype) {
case SMB_ACL_USER_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
- own_grp = (unsigned int)pst->st_uid;
+ own_grp = (unsigned int)pst->st_ex_uid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
}
case SMB_ACL_GROUP_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
- own_grp = (unsigned int)pst->st_gid;
+ own_grp = (unsigned int)pst->st_ex_gid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
const SMB_STRUCT_STAT *psbuf)
{
DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
- DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
+ DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
- SOFF_T(pdata,0,get_file_size(*psbuf)); /* File size 64 Bit */
+ SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */
pdata += 8;
- SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
- put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */
- put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */
- put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */
+ put_long_date_timespec(pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
+ put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
+ put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
pdata += 24;
- SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */
+ SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */
+ SIVAL(pdata,0,psbuf->st_ex_gid); /* group id of owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_filetype(psbuf->st_mode));
+ SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
pdata += 4;
- SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */
+ SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */
+ SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */
pdata += 8;
-
- SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */
+
+ SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */
+ SIVAL(pdata,0,psbuf->st_ex_nlink); /* number of hard links */
SIVAL(pdata,4,0);
pdata += 8;
static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
uint32 *smb_fflags, uint32 *smb_fmask)
{
-#ifdef HAVE_STAT_ST_FLAGS
int i;
for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
*smb_fmask |= info2_flags_map[i].smb_fflag;
- if (psbuf->st_flags & info2_flags_map[i].stat_fflag) {
+ if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
*smb_fflags |= info2_flags_map[i].smb_fflag;
}
}
-#endif /* HAVE_STAT_ST_FLAGS */
}
static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
const uint32 smb_fmask,
int *stat_fflags)
{
-#ifdef HAVE_STAT_ST_FLAGS
uint32 max_fmask = 0;
int i;
- *stat_fflags = psbuf->st_flags;
+ *stat_fflags = psbuf->st_ex_flags;
/* For each flags requested in smb_fmask, check the state of the
* corresponding flag in smb_fflags and set or clear the matching
}
return True;
-#else
- return False;
-#endif /* HAVE_STAT_ST_FLAGS */
}
pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
/* Create (birth) time 64 bit */
- put_long_date_timespec(pdata, get_create_timespec(psbuf, False));
+ put_long_date_timespec(pdata, psbuf->st_ex_btime);
pdata += 8;
map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
SMB_STRUCT_STAT sbuf;
char *dos_fname = NULL;
char *fname = NULL;
+ struct smb_filename *smb_fname = NULL;
char *fullpathname;
char *base_name;
char *p;
return;
}
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+ sbuf = smb_fname->st;
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ TALLOC_FREE(smb_fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
+
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
if (!mode)
mode = FILE_ATTRIBUTE_NORMAL;
- nlink = sbuf.st_nlink;
+ nlink = sbuf.st_ex_nlink;
if (nlink && (mode&aDIR)) {
nlink = 1;
fullpathname = fname;
if (!(mode & aDIR))
- file_size = get_file_size(sbuf);
+ file_size = get_file_size_stat(&sbuf);
/* Pull out any data sent here before we realloc. */
switch (info_level) {
dstart = pdata;
dend = dstart + data_size - 1;
- create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
- mtime_ts = get_mtimespec(&sbuf);
- atime_ts = get_atimespec(&sbuf);
+ create_time_ts = sbuf.st_ex_btime;
+ mtime_ts = sbuf.st_ex_mtime;
+ atime_ts = sbuf.st_ex_atime;
- allocation_size = get_allocation_size(conn,fsp,&sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
if (!fsp) {
/* Do we have this path open ? */
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
fsp1 = file_find_di_first(fileid);
if (fsp1 && fsp1->initial_allocation_size) {
- allocation_size = get_allocation_size(conn, fsp1, &sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
}
}
BasicFileInformationTest. -tpot */
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
+ SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
+ SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
data_size = 8;
break;
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_mode)) {
+ if(!S_ISLNK(sbuf.st_ex_mode)) {
reply_unixerror(req, ERRSRV,
ERRbadlink);
return;
return;
}
- if (S_ISDIR(sbuf.st_mode)) {
+ if (S_ISDIR(sbuf.st_ex_mode)) {
if (fsp && fsp->is_directory) {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
} else {
const char *oldname_in,
const char *newname_in)
{
- SMB_STRUCT_STAT sbuf1, sbuf2;
- char *last_component_oldname = NULL;
- char *last_component_newname = NULL;
+ struct smb_filename *smb_fname = NULL;
+ struct smb_filename *smb_fname_new = NULL;
char *oldname = NULL;
char *newname = NULL;
NTSTATUS status = NT_STATUS_OK;
- ZERO_STRUCT(sbuf1);
- ZERO_STRUCT(sbuf2);
+ status = unix_convert(ctx, conn, oldname_in, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- status = unix_convert(ctx, conn, oldname_in, False, &oldname,
- &last_component_oldname, &sbuf1);
+ status = get_full_smb_filename(ctx, smb_fname, &oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
status = check_name(conn, oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
/* source must already exist. */
- if (!VALID_STAT(sbuf1)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!VALID_STAT(smb_fname->st)) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto out;
}
- status = unix_convert(ctx, conn, newname_in, False, &newname,
- &last_component_newname, &sbuf2);
+ status = unix_convert(ctx, conn, newname_in, &smb_fname_new, 0);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname_new, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
status = check_name(conn, newname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
/* Disallow if newname already exists. */
- if (VALID_STAT(sbuf2)) {
- return NT_STATUS_OBJECT_NAME_COLLISION;
+ if (VALID_STAT(smb_fname_new->st)) {
+ status = NT_STATUS_OBJECT_NAME_COLLISION;
+ goto out;
}
/* No links from a directory. */
- if (S_ISDIR(sbuf1.st_mode)) {
- return NT_STATUS_FILE_IS_A_DIRECTORY;
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
+ status = NT_STATUS_FILE_IS_A_DIRECTORY;
+ goto out;
}
/* Ensure this is within the share. */
status = check_reduced_name(conn, oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
- nt_errstr(status), newname, oldname));
+ nt_errstr(status), newname, oldname));
}
-
+ out:
+ TALLOC_FREE(smb_fname);
+ TALLOC_FREE(smb_fname_new);
return status;
}
files_struct *fsp,
const char *fname,
const SMB_STRUCT_STAT *psbuf,
- struct timespec ts[2],
+ struct smb_file_time *ft,
bool setting_write_time)
{
uint32 action =
}
/* get some defaults (no modifications) if any info is zero or -1. */
- if (null_timespec(ts[0])) {
- ts[0] = get_atimespec(psbuf);
+ if (null_timespec(ft->atime)) {
+ ft->atime= psbuf->st_ex_atime;
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
- if (null_timespec(ts[1])) {
- ts[1] = get_mtimespec(psbuf);
+ if (null_timespec(ft->mtime)) {
+ ft->mtime = psbuf->st_ex_mtime;
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
if (!setting_write_time) {
- /* ts[1] comes from change time, not write time. */
+ /* ft->mtime comes from change time, not write time. */
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
- DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) ));
- DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) ));
+ DEBUG(5,("smb_set_filetime: actime: %s\n ",
+ time_to_asc(convert_timespec_to_time_t(ft->atime))));
+ DEBUG(5,("smb_set_filetime: modtime: %s\n ",
+ time_to_asc(convert_timespec_to_time_t(ft->mtime))));
+ if (!null_timespec(ft->create_time)) {
+ DEBUG(5,("smb_set_file_time: createtime: %s\n ",
+ time_to_asc(convert_timespec_to_time_t(ft->create_time))));
+ }
/*
* Try and set the times of this file if
*/
{
- struct timespec mts = get_mtimespec(psbuf);
- struct timespec ats = get_atimespec(psbuf);
- if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) {
+ struct timespec mts = psbuf->st_ex_mtime;
+ struct timespec ats = psbuf->st_ex_atime;
+ if ((timespec_compare(&ft->atime, &ats) == 0) &&
+ (timespec_compare(&ft->mtime, &mts) == 0)) {
return NT_STATUS_OK;
}
}
*/
DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
- time_to_asc(convert_timespec_to_time_t(ts[1])) ));
+ time_to_asc(convert_timespec_to_time_t(ft->mtime))));
if (fsp != NULL) {
if (fsp->base_fsp) {
- set_sticky_write_time_fsp(fsp->base_fsp, ts[1]);
+ set_sticky_write_time_fsp(fsp->base_fsp,
+ ft->mtime);
} else {
- set_sticky_write_time_fsp(fsp, ts[1]);
+ set_sticky_write_time_fsp(fsp, ft->mtime);
}
} else {
set_sticky_write_time_path(conn, fname,
vfs_file_id_from_sbuf(conn, psbuf),
- ts[1]);
+ ft->mtime);
}
}
fname = fsp->base_fsp->fsp_name;
}
- if(file_ntimes(conn, fname, ts)!=0) {
+ if(file_ntimes(conn, fname, ft)!=0) {
return map_nt_error_from_unix(errno);
}
notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
****************************************************************************/
static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
+ files_struct *fsp,
const char *fname,
SMB_STRUCT_STAT *psbuf,
uint32 dosmode)
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ if (fsp) {
+ if (fsp->base_fsp) {
+ fname = fsp->base_fsp->fsp_name;
+ } else {
+ fname = fsp->fsp_name;
+ }
+ }
+
if (dosmode) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
dosmode |= aDIR;
} else {
dosmode &= ~aDIR;
DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
- if (size == get_file_size(*psbuf)) {
+ if (size == get_file_size_stat(psbuf)) {
return NT_STATUS_OK;
}
uint32 len;
char *newname = NULL;
char *base_name = NULL;
+ struct smb_filename *smb_fname = NULL;
bool dest_has_wcard = False;
- SMB_STRUCT_STAT sbuf;
- char *newname_last_component = NULL;
NTSTATUS status = NT_STATUS_OK;
char *p;
TALLOC_CTX *ctx = talloc_tos();
return NT_STATUS_INVALID_PARAMETER;
}
- ZERO_STRUCT(sbuf);
-
overwrite = (CVAL(pdata,0) ? True : False);
root_fid = IVAL(pdata,4);
len = IVAL(pdata,8);
return NT_STATUS_NO_MEMORY;
}
- status = unix_convert(ctx, conn, newname, False,
- &newname,
- &newname_last_component,
- &sbuf);
+ status = unix_convert(ctx, conn, newname, &smb_fname,
+ UCF_SAVE_LCOMP);
/* If an error we expect this to be
* NT_STATUS_OBJECT_PATH_NOT_FOUND */
if (!NT_STATUS_IS_OK(status)
&& !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
status)) {
- return status;
+ goto out;
}
}
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
fsp->fnum, fsp->fsp_name, base_name ));
status = rename_internals_fsp(conn, fsp, base_name,
- newname_last_component, 0,
- overwrite);
+ smb_fname ?
+ smb_fname->original_lcomp : NULL,
+ 0, overwrite);
} else {
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
fname, base_name ));
overwrite, False, dest_has_wcard,
FILE_WRITE_ATTRIBUTES);
}
-
+ out:
+ TALLOC_FREE(smb_fname);
return status;
}
POSIX_LOCK,
blocking_lock,
&status,
- &block_smbpid);
+ &block_smbpid,
+ NULL);
if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/*
const char *fname,
const SMB_STRUCT_STAT *psbuf)
{
- struct timespec ts[2];
+ struct smb_file_time ft;
+ ZERO_STRUCT(ft);
if (total_data < 12) {
return NT_STATUS_INVALID_PARAMETER;
}
+ /* create time */
+ ft.create_time = interpret_long_date(pdata);
+
/* access time */
- ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastAccess));
+ ft.atime = interpret_long_date(pdata + 8);
+
/* write time */
- ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastWrite));
+ ft.mtime = interpret_long_date(pdata + 16);
DEBUG(10,("smb_set_info_standard: file %s\n",
fname ? fname : fsp->fsp_name ));
fsp,
fname,
psbuf,
- ts,
+ &ft,
true);
}
/* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
struct timespec write_time;
struct timespec changed_time;
+ struct smb_file_time ft;
uint32 dosmode = 0;
- struct timespec ts[2];
NTSTATUS status = NT_STATUS_OK;
bool setting_write_time = true;
+ ZERO_STRUCT(ft);
+
if (total_data < 36) {
return NT_STATUS_INVALID_PARAMETER;
}
/* Set the attributes */
dosmode = IVAL(pdata,32);
- status = smb_set_file_dosmode(conn,
- fname,
- psbuf,
- dosmode);
+ status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- /* Ignore create time at offset pdata. */
-
/* access time */
- ts[0] = interpret_long_date(pdata+8);
+ ft.atime = interpret_long_date(pdata+8);
write_time = interpret_long_date(pdata+16);
changed_time = interpret_long_date(pdata+24);
/* mtime */
- ts[1] = timespec_min(&write_time, &changed_time);
+ ft.mtime = timespec_min(&write_time, &changed_time);
+
+ /* create time */
+ ft.create_time = interpret_long_date(pdata);
- if ((timespec_compare(&write_time, &ts[1]) == 1) && !null_timespec(write_time)) {
- ts[1] = write_time;
+ if ((timespec_compare(&write_time, &ft.mtime) == 1) &&
+ !null_timespec(write_time)) {
+ ft.mtime = write_time;
}
/* Prefer a defined time to an undefined one. */
- if (null_timespec(ts[1])) {
+ if (null_timespec(ft.mtime)) {
if (null_timespec(write_time)) {
- ts[1] = changed_time;
+ ft.mtime = changed_time;
setting_write_time = false;
} else {
- ts[1] = write_time;
+ ft.mtime = write_time;
}
}
fsp,
fname,
psbuf,
- ts,
+ &ft,
setting_write_time);
}
if (fsp && fsp->fh->fd != -1) {
/* Open file handle. */
/* Only change if needed. */
- if (allocation_size != get_file_size(*psbuf)) {
+ if (allocation_size != get_file_size_stat(psbuf)) {
if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
return map_nt_error_from_unix(errno);
}
}
/* Only change if needed. */
- if (allocation_size != get_file_size(*psbuf)) {
+ if (allocation_size != get_file_size_stat(psbuf)) {
if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
status = map_nt_error_from_unix(errno);
close_file(req, new_fsp, NORMAL_CLOSE);
const char *fname,
SMB_STRUCT_STAT *psbuf)
{
- struct timespec ts[2];
+ struct smb_file_time ft;
uint32 raw_unixmode;
mode_t unixmode;
SMB_OFF_T size = 0;
bool delete_on_fail = False;
enum perm_type ptype;
+ ZERO_STRUCT(ft);
+
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
}
#endif /* LARGE_SMB_OFF_T */
}
- ts[0] = interpret_long_date(pdata+24); /* access_time */
- ts[1] = interpret_long_date(pdata+32); /* modification_time */
+ ft.atime = interpret_long_date(pdata+24); /* access_time */
+ ft.mtime = interpret_long_date(pdata+32); /* modification_time */
set_owner = (uid_t)IVAL(pdata,40);
set_grp = (gid_t)IVAL(pdata,48);
raw_unixmode = IVAL(pdata,84);
if (VALID_STAT(*psbuf)) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
ptype = PERM_EXISTING_DIR;
} else {
ptype = PERM_EXISTING_FILE;
/* Ensure we don't try and change anything else. */
raw_unixmode = SMB_MODE_NO_CHANGE;
- size = get_file_size(*psbuf);
- ts[0] = get_atimespec(psbuf);
- ts[1] = get_mtimespec(psbuf);
+ size = get_file_size_stat(psbuf);
+ ft.atime = psbuf->st_ex_atime;
+ ft.mtime = psbuf->st_ex_mtime;
/*
* We continue here as we might want to change the
* owner uid/gid.
* */
if (!size) {
- size = get_file_size(*psbuf);
+ size = get_file_size_stat(psbuf);
}
#endif
* Deal with the UNIX specific uid set.
*/
- if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
+ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_ex_uid != set_owner)) {
int ret;
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for path %s\n",
(unsigned int)set_owner, fname ));
- if (S_ISLNK(psbuf->st_mode)) {
+ if (S_ISLNK(psbuf->st_ex_mode)) {
ret = SMB_VFS_LCHOWN(conn, fname, set_owner, (gid_t)-1);
} else {
ret = SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1);
* Deal with the UNIX specific gid set.
*/
- if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
+ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_ex_gid != set_grp)) {
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) {
fsp,
fname,
psbuf,
- ts,
+ &ft,
true);
}
create_disp = FILE_OVERWRITE_IF;
} else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
create_disp = FILE_OPEN_IF;
+ } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
+ create_disp = FILE_OPEN;
} else {
DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
(unsigned int)wire_open_mode ));
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
FILE_SHARE_DELETE),
create_disp, /* create_disposition*/
- 0, /* create_options */
+ FILE_NON_DIRECTORY_FILE, /* create_options */
mod_unixmode, /* file_attributes */
oplock_request, /* oplock_request */
0, /* allocation_size */
uint16 info_level;
SMB_STRUCT_STAT sbuf;
char *fname = NULL;
+ struct smb_filename *smb_fname = NULL;
files_struct *fsp = NULL;
NTSTATUS status = NT_STATUS_OK;
int data_return_size = 0;
return;
}
- status = unix_convert(ctx, conn, fname, False,
- &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+ sbuf = smb_fname->st;
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ TALLOC_FREE(smb_fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
return;
}
-
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
-
+
return;
}
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
+ struct smb_filename *smb_dname = NULL;
char *params = *pparams;
char *pdata = *ppdata;
char *directory = NULL;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status = NT_STATUS_OK;
struct ea_list *ea_list = NULL;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
+ status = unix_convert(ctx, conn, directory, &smb_dname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = get_full_smb_filename(ctx, smb_dname, &directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
reply_nterror(req, status);
return;
}
-
+
/* Try and set any given EA. */
if (ea_list) {
status = set_ea(conn, NULL, directory, ea_list);
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
-
+
return;
}
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
- static uint16 fnf_handle = 257;
char *params = *pparams;
uint16 info_level;
fnf_handle = 257;
send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
-
+
return;
}
SSVAL(params,2,0); /* No EA errors */
send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
-
+
return;
}
END_PROFILE(SMBfindnclose);
return;
}
-
+
dptr_num = SVAL(req->vwv+0, 0);
DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
}
}
+ SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
+
/* Now we must call the relevant TRANS2 function */
switch(state->call) {
case TRANSACT2_OPEN:
state->received_param += pcnt;
state->received_data += dcnt;
-
+
if ((state->received_data > state->total_data) ||
(state->received_param > state->total_param))
goto bad_param;