mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture
tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy.
This commit is contained in:
parent
053e892e07
commit
c7fe18761e
@ -63,6 +63,9 @@
|
||||
#define ERRinvalidname 123 /* Invalid name */
|
||||
#define ERRunknownlevel 124
|
||||
#define ERRnotlocked 158 /* This region is not locked by this locking context. */
|
||||
#define ERRinvalidpath 161
|
||||
#define ERRcancelviolation 173
|
||||
#define ERRnoatomiclocks 174
|
||||
#define ERRrename 183
|
||||
#define ERRbadpipe 230 /* Named pipe invalid */
|
||||
#define ERRpipebusy 231 /* All instances of pipe are busy */
|
||||
|
@ -124,7 +124,6 @@ typedef struct ntlmssp_state
|
||||
*
|
||||
* @param ntlmssp_state This structure
|
||||
* @param challenge 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
|
||||
* @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
|
||||
*
|
||||
*/
|
||||
NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge);
|
||||
|
@ -107,44 +107,32 @@ typedef int BOOL;
|
||||
#define DOS_OPEN_FCB 0xF
|
||||
|
||||
/* define shifts and masks for share and open modes. */
|
||||
#define OPEN_MODE_MASK 0xF
|
||||
#define SHARE_MODE_SHIFT 4
|
||||
#define SHARE_MODE_MASK 0x7
|
||||
#define GET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
|
||||
#define SET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
|
||||
#define GET_DENY_MODE(x) (((x)>>SHARE_MODE_SHIFT) & SHARE_MODE_MASK)
|
||||
#define SET_DENY_MODE(x) (((x) & SHARE_MODE_MASK) <<SHARE_MODE_SHIFT)
|
||||
#define OPENX_MODE_MASK 0xF
|
||||
#define DENY_MODE_SHIFT 4
|
||||
#define DENY_MODE_MASK 0x7
|
||||
#define GET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK)
|
||||
#define SET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK)
|
||||
#define GET_DENY_MODE(x) (((x)>>DENY_MODE_SHIFT) & DENY_MODE_MASK)
|
||||
#define SET_DENY_MODE(x) (((x) & DENY_MODE_MASK) <<DENY_MODE_SHIFT)
|
||||
|
||||
/* Sync on open file (not sure if used anymore... ?) */
|
||||
#define FILE_SYNC_OPENMODE (1<<14)
|
||||
#define GET_FILE_SYNC_OPENMODE(x) (((x) & FILE_SYNC_OPENMODE) ? True : False)
|
||||
|
||||
/* allow delete on open file mode (used by NT SMB's). */
|
||||
#define ALLOW_SHARE_DELETE (1<<15)
|
||||
#define GET_ALLOW_SHARE_DELETE(x) (((x) & ALLOW_SHARE_DELETE) ? True : False)
|
||||
#define SET_ALLOW_SHARE_DELETE(x) ((x) ? ALLOW_SHARE_DELETE : 0)
|
||||
|
||||
/* delete on close flag (used by NT SMB's). */
|
||||
#define DELETE_ON_CLOSE_FLAG (1<<16)
|
||||
#define GET_DELETE_ON_CLOSE_FLAG(x) (((x) & DELETE_ON_CLOSE_FLAG) ? True : False)
|
||||
#define SET_DELETE_ON_CLOSE_FLAG(x) ((x) ? DELETE_ON_CLOSE_FLAG : 0)
|
||||
|
||||
/* open disposition values */
|
||||
#define FILE_EXISTS_FAIL 0
|
||||
#define FILE_EXISTS_OPEN 1
|
||||
#define FILE_EXISTS_TRUNCATE 2
|
||||
#define OPENX_FILE_EXISTS_FAIL 0
|
||||
#define OPENX_FILE_EXISTS_OPEN 1
|
||||
#define OPENX_FILE_EXISTS_TRUNCATE 2
|
||||
|
||||
/* mask for open disposition. */
|
||||
#define FILE_OPEN_MASK 0x3
|
||||
#define OPENX_FILE_OPEN_MASK 0x3
|
||||
|
||||
#define GET_FILE_OPEN_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||
#define SET_FILE_OPEN_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||
#define GET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||
#define SET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||
|
||||
/* The above can be OR'ed with... */
|
||||
#define FILE_CREATE_IF_NOT_EXIST 0x10
|
||||
#define FILE_FAIL_IF_NOT_EXIST 0
|
||||
|
||||
#define GET_FILE_CREATE_DISPOSITION(x) ((x) & (FILE_CREATE_IF_NOT_EXIST|FILE_FAIL_IF_NOT_EXIST))
|
||||
#define OPENX_FILE_CREATE_IF_NOT_EXIST 0x10
|
||||
#define OPENX_FILE_FAIL_IF_NOT_EXIST 0
|
||||
|
||||
/* share types */
|
||||
#define STYPE_DISKTREE 0 /* Disk drive */
|
||||
@ -407,27 +395,38 @@ typedef struct
|
||||
|
||||
#include "fake_file.h"
|
||||
|
||||
struct fd_handle {
|
||||
size_t ref_count;
|
||||
int fd;
|
||||
SMB_BIG_UINT position_information;
|
||||
SMB_OFF_T pos;
|
||||
uint32 private_options; /* NT Create options, but we only look at
|
||||
* NTCREATEX_OPTIONS_PRIVATE_DENY_DOS and
|
||||
* NTCREATEX_OPTIONS_PRIVATE_DENY_FCB (Except
|
||||
* for print files *only*, where
|
||||
* DELETE_ON_CLOSE is not stored in the share
|
||||
* mode database.
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct files_struct {
|
||||
struct files_struct *next, *prev;
|
||||
int fnum;
|
||||
struct connection_struct *conn;
|
||||
int fd;
|
||||
struct fd_handle *fh;
|
||||
unsigned int num_smb_operations;
|
||||
uint16 rap_print_jobid;
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
BOOL delete_on_close;
|
||||
SMB_OFF_T pos;
|
||||
SMB_BIG_UINT initial_allocation_size; /* Faked up initial allocation on disk. */
|
||||
SMB_BIG_UINT position_information;
|
||||
mode_t mode;
|
||||
uint16 file_pid;
|
||||
uint16 vuid;
|
||||
write_bmpx_struct *wbmpx_ptr;
|
||||
write_cache *wcp;
|
||||
struct timeval open_time;
|
||||
int share_mode;
|
||||
uint32 desired_access;
|
||||
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
|
||||
uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
|
||||
BOOL pending_modtime_owner;
|
||||
time_t pending_modtime;
|
||||
time_t last_write_time;
|
||||
@ -441,7 +440,6 @@ typedef struct files_struct {
|
||||
BOOL modified;
|
||||
BOOL is_directory;
|
||||
BOOL is_stat;
|
||||
BOOL directory_delete_on_close;
|
||||
BOOL aio_write_behind;
|
||||
char *fsp_name;
|
||||
FAKE_FILE_HANDLE *fake_file_handle;
|
||||
@ -639,8 +637,12 @@ typedef struct {
|
||||
pid_t pid;
|
||||
uint16 op_port;
|
||||
uint16 op_type;
|
||||
int share_mode;
|
||||
uint32 desired_access;
|
||||
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
|
||||
uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
|
||||
uint32 private_options; /* NT Create options, but we only look at
|
||||
* NTCREATEX_OPTIONS_PRIVATE_DENY_DOS and
|
||||
* NTCREATEX_OPTIONS_PRIVATE_DENY_FCB for
|
||||
* smbstatus and swat */
|
||||
struct timeval time;
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
@ -1079,18 +1081,18 @@ struct bitmap {
|
||||
#define DESIRED_ACCESS_PIPE 0x2019f
|
||||
|
||||
/* Generic access masks & rights. */
|
||||
#define DELETE_ACCESS (1L<<16) /* 0x00010000 */
|
||||
#define READ_CONTROL_ACCESS (1L<<17) /* 0x00020000 */
|
||||
#define WRITE_DAC_ACCESS (1L<<18) /* 0x00040000 */
|
||||
#define WRITE_OWNER_ACCESS (1L<<19) /* 0x00080000 */
|
||||
#define SYNCHRONIZE_ACCESS (1L<<20) /* 0x00100000 */
|
||||
#define DELETE_ACCESS 0x00010000 /* (1L<<16) */
|
||||
#define READ_CONTROL_ACCESS 0x00020000 /* (1L<<17) */
|
||||
#define WRITE_DAC_ACCESS 0x00040000 /* (1L<<18) */
|
||||
#define WRITE_OWNER_ACCESS 0x00080000 /* (1L<<19) */
|
||||
#define SYNCHRONIZE_ACCESS 0x00100000 /* (1L<<20) */
|
||||
|
||||
#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */
|
||||
#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */
|
||||
#define GENERIC_ALL_ACCESS (1<<28) /* 0x10000000 */
|
||||
#define GENERIC_EXECUTE_ACCESS (1<<29) /* 0x20000000 */
|
||||
#define GENERIC_WRITE_ACCESS (1<<30) /* 0x40000000 */
|
||||
#define GENERIC_READ_ACCESS (((unsigned)1)<<31) /* 0x80000000 */
|
||||
#define SYSTEM_SECURITY_ACCESS 0x01000000 /* (1L<<24) */
|
||||
#define MAXIMUM_ALLOWED_ACCESS 0x02000000 /* (1L<<25) */
|
||||
#define GENERIC_ALL_ACCESS 0x10000000 /* (1<<28) */
|
||||
#define GENERIC_EXECUTE_ACCESS 0x20000000 /* (1<<29) */
|
||||
#define GENERIC_WRITE_ACCESS 0x40000000 /* (1<<30) */
|
||||
#define GENERIC_READ_ACCESS ((unsigned)0x80000000) /* (((unsigned)1)<<31) */
|
||||
|
||||
/* Mapping of generic access rights for files to specific rights. */
|
||||
|
||||
@ -1172,12 +1174,12 @@ struct bitmap {
|
||||
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L
|
||||
|
||||
/* CreateDisposition field. */
|
||||
#define FILE_SUPERSEDE 0
|
||||
#define FILE_OPEN 1
|
||||
#define FILE_CREATE 2
|
||||
#define FILE_OPEN_IF 3
|
||||
#define FILE_OVERWRITE 4
|
||||
#define FILE_OVERWRITE_IF 5
|
||||
#define FILE_SUPERSEDE 0 /* File exists overwrite/supersede. File not exist create. */
|
||||
#define FILE_OPEN 1 /* File exists open. File not exist fail. */
|
||||
#define FILE_CREATE 2 /* File exists fail. File not exist create. */
|
||||
#define FILE_OPEN_IF 3 /* File exists open. File not exist create. */
|
||||
#define FILE_OVERWRITE 4 /* File exists overwrite. File not exist fail. */
|
||||
#define FILE_OVERWRITE_IF 5 /* File exists overwrite. File not exist create. */
|
||||
|
||||
/* CreateOptions field. */
|
||||
#define FILE_DIRECTORY_FILE 0x0001
|
||||
@ -1190,6 +1192,10 @@ struct bitmap {
|
||||
#define FILE_DELETE_ON_CLOSE 0x1000
|
||||
#define FILE_OPEN_BY_FILE_ID 0x2000
|
||||
|
||||
/* Private create options used by the ntcreatex processing code. From Samba4. */
|
||||
#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000
|
||||
#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000
|
||||
|
||||
/* Responses when opening a file. */
|
||||
#define FILE_WAS_SUPERSEDED 0
|
||||
#define FILE_WAS_OPENED 1
|
||||
@ -1335,7 +1341,7 @@ char *strdup(char *s);
|
||||
#define FLAGS2_IS_LONG_NAME 0x0040
|
||||
#define FLAGS2_EXTENDED_SECURITY 0x0800
|
||||
#define FLAGS2_DFS_PATHNAMES 0x1000
|
||||
#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
|
||||
#define FLAGS2_READ_PERMIT_EXECUTE 0x2000
|
||||
#define FLAGS2_32_BIT_ERROR_CODES 0x4000
|
||||
#define FLAGS2_UNICODE_STRINGS 0x8000
|
||||
|
||||
@ -1442,36 +1448,36 @@ extern int chain_size;
|
||||
#define LOCKING_ANDX_CANCEL_LOCK 0x8
|
||||
#define LOCKING_ANDX_LARGE_FILES 0x10
|
||||
|
||||
/* Oplock levels */
|
||||
#define OPLOCKLEVEL_NONE 0
|
||||
#define OPLOCKLEVEL_II 1
|
||||
|
||||
/*
|
||||
* Bits we test with.
|
||||
*/
|
||||
|
||||
|
||||
#define NO_OPLOCK 0
|
||||
#define EXCLUSIVE_OPLOCK 1
|
||||
#define BATCH_OPLOCK 2
|
||||
#define LEVEL_II_OPLOCK 4
|
||||
#define INTERNAL_OPEN_ONLY 8
|
||||
|
||||
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
|
||||
#define BATCH_OPLOCK_TYPE(lck) ((lck) & BATCH_OPLOCK)
|
||||
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & LEVEL_II_OPLOCK)
|
||||
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
|
||||
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
|
||||
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & (unsigned int)LEVEL_II_OPLOCK)
|
||||
|
||||
/*
|
||||
* On the wire return values for oplock types.
|
||||
*/
|
||||
|
||||
#define CORE_OPLOCK_GRANTED (1<<5)
|
||||
#define EXTENDED_OPLOCK_GRANTED (1<<15)
|
||||
|
||||
/*
|
||||
* Return values for oplock types.
|
||||
*/
|
||||
|
||||
#define NO_OPLOCK_RETURN 0
|
||||
#define EXCLUSIVE_OPLOCK_RETURN 1
|
||||
#define BATCH_OPLOCK_RETURN 2
|
||||
#define LEVEL_II_OPLOCK_RETURN 3
|
||||
|
||||
/* Oplock levels */
|
||||
#define OPLOCKLEVEL_NONE 0
|
||||
#define OPLOCKLEVEL_II 1
|
||||
|
||||
/*
|
||||
* Loopback command offsets.
|
||||
*/
|
||||
|
@ -101,15 +101,16 @@
|
||||
extern struct current_user current_user;\
|
||||
if (!FNUM_OK(fsp,conn)) \
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid)); \
|
||||
else if((fsp)->fd == -1) \
|
||||
else if((fsp)->fh->fd == -1) \
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));\
|
||||
(fsp)->num_smb_operations++;\
|
||||
} while(0)
|
||||
|
||||
#define CHECK_READ(fsp) if (!(fsp)->can_read) \
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess))
|
||||
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess))
|
||||
#define CHECK_READ(fsp,inbuf) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \
|
||||
((SVAL((inbuf),smb_flg2) & FLAGS2_READ_PERMIT_EXECUTE) && \
|
||||
(fsp->access_mask & FILE_EXECUTE))))
|
||||
|
||||
#define CHECK_WRITE(fsp) ((fsp)->can_write && ((fsp)->fh->fd != -1))
|
||||
|
||||
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
|
||||
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
|
||||
|
@ -58,7 +58,8 @@
|
||||
/* Changed to version 11 to include seekdir/telldir/rewinddir calls. JRA */
|
||||
/* Changed to version 12 to add mask and attributes to opendir(). JRA
|
||||
Also include aio calls. JRA. */
|
||||
#define SMB_VFS_INTERFACE_VERSION 12
|
||||
/* Changed to version 13 as the internal structure of files_struct has changed. JRA */
|
||||
#define SMB_VFS_INTERFACE_VERSION 13
|
||||
|
||||
|
||||
/* to bug old modules which are trying to compile with the old functions */
|
||||
|
@ -2735,3 +2735,25 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
|
||||
{
|
||||
switch (share_access) {
|
||||
case FILE_SHARE_NONE:
|
||||
return DENY_ALL;
|
||||
case FILE_SHARE_READ:
|
||||
return DENY_WRITE;
|
||||
case FILE_SHARE_WRITE:
|
||||
return DENY_READ;
|
||||
case FILE_SHARE_READ|FILE_SHARE_WRITE:
|
||||
case FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE:
|
||||
return DENY_NONE;
|
||||
}
|
||||
if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
|
||||
return DENY_DOS;
|
||||
} else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
|
||||
return DENY_FCB;
|
||||
}
|
||||
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
@ -705,7 +705,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
|
||||
int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)
|
||||
{
|
||||
return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0);
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -124,9 +124,9 @@ static const struct {
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE},
|
||||
{ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED},
|
||||
{ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID},
|
||||
{ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_INVALID},
|
||||
{ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND},
|
||||
{ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD},
|
||||
{ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_SYNTAX_BAD},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR},
|
||||
{ERRDOS, 23, NT_STATUS_DATA_ERROR},
|
||||
|
@ -3,6 +3,7 @@
|
||||
Locking functions
|
||||
Copyright (C) Andrew Tridgell 1992-2000
|
||||
Copyright (C) Jeremy Allison 1992-2000
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -46,7 +47,10 @@ static TDB_CONTEXT *deferred_open_tdb;
|
||||
|
||||
struct locking_data {
|
||||
union {
|
||||
int num_share_mode_entries;
|
||||
struct {
|
||||
int num_share_mode_entries;
|
||||
BOOL delete_on_close;
|
||||
} s;
|
||||
share_mode_entry dummy; /* Needed for alignment. */
|
||||
} u;
|
||||
/* the following two entries are implicit
|
||||
@ -432,10 +436,14 @@ char *share_mode_str(int num, share_mode_entry *e)
|
||||
{
|
||||
static pstring share_str;
|
||||
|
||||
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
|
||||
pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
|
||||
num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
|
||||
(unsigned int)e->dev, (double)e->inode );
|
||||
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: "
|
||||
"pid = %lu, share_access = 0x%x, private_options = 0x%x, "
|
||||
"access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, "
|
||||
"dev = 0x%x, inode = %.0f",
|
||||
num, (unsigned long)e->pid,
|
||||
e->share_access, e->private_options,
|
||||
e->access_mask, e->op_port, e->op_type, e->share_file_id,
|
||||
(unsigned int)e->dev, (double)e->inode );
|
||||
|
||||
return share_str;
|
||||
}
|
||||
@ -446,7 +454,7 @@ pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, fi
|
||||
|
||||
static void print_share_mode_table(struct locking_data *data)
|
||||
{
|
||||
int num_share_modes = data->u.num_share_mode_entries;
|
||||
int num_share_modes = data->u.s.num_share_mode_entries;
|
||||
share_mode_entry *shares = (share_mode_entry *)(data + 1);
|
||||
int i;
|
||||
|
||||
@ -460,9 +468,9 @@ static void print_share_mode_table(struct locking_data *data)
|
||||
Get all share mode entries for a dev/inode pair.
|
||||
********************************************************************/
|
||||
|
||||
int get_share_modes(connection_struct *conn,
|
||||
SMB_DEV_T dev, SMB_INO_T inode,
|
||||
share_mode_entry **pp_shares)
|
||||
int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode,
|
||||
share_mode_entry **pp_shares,
|
||||
BOOL *delete_on_close)
|
||||
{
|
||||
TDB_DATA dbuf;
|
||||
struct locking_data *data;
|
||||
@ -470,13 +478,18 @@ int get_share_modes(connection_struct *conn,
|
||||
share_mode_entry *shares = NULL;
|
||||
TDB_DATA key = locking_key(dev, inode);
|
||||
*pp_shares = NULL;
|
||||
*delete_on_close = False;
|
||||
|
||||
dbuf = tdb_fetch(tdb, key);
|
||||
if (!dbuf.dptr)
|
||||
return 0;
|
||||
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
num_share_modes = data->u.num_share_mode_entries;
|
||||
|
||||
*delete_on_close = data->u.s.delete_on_close;
|
||||
DEBUG(10, ("get_share_modes: delete_on_close: %d\n",
|
||||
*delete_on_close));
|
||||
num_share_modes = data->u.s.num_share_mode_entries;
|
||||
if(num_share_modes) {
|
||||
pstring fname;
|
||||
int i;
|
||||
@ -515,7 +528,7 @@ int get_share_modes(connection_struct *conn,
|
||||
|
||||
/* Did we delete any ? If so, re-store in tdb. */
|
||||
if (del_count) {
|
||||
data->u.num_share_mode_entries = num_share_modes;
|
||||
data->u.s.num_share_mode_entries = num_share_modes;
|
||||
|
||||
if (num_share_modes) {
|
||||
memcpy(dbuf.dptr + sizeof(*data), shares,
|
||||
@ -527,7 +540,7 @@ int get_share_modes(connection_struct *conn,
|
||||
/* The record has shrunk a bit */
|
||||
dbuf.dsize -= del_count * sizeof(share_mode_entry);
|
||||
|
||||
if (data->u.num_share_mode_entries == 0) {
|
||||
if (data->u.s.num_share_mode_entries == 0) {
|
||||
if (tdb_delete(tdb, key) == -1) {
|
||||
SAFE_FREE(shares);
|
||||
SAFE_FREE(dbuf.dptr);
|
||||
@ -548,6 +561,15 @@ int get_share_modes(connection_struct *conn,
|
||||
return num_share_modes;
|
||||
}
|
||||
|
||||
BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
|
||||
{
|
||||
share_mode_entry *shares;
|
||||
BOOL result;
|
||||
get_share_modes(dev, inode, &shares, &result);
|
||||
SAFE_FREE(shares);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Fill a share mode entry.
|
||||
********************************************************************/
|
||||
@ -559,8 +581,9 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t
|
||||
|
||||
memset(e, '\0', sizeof(share_mode_entry));
|
||||
e->pid = sys_getpid();
|
||||
e->share_mode = fsp->share_mode;
|
||||
e->desired_access = fsp->desired_access;
|
||||
e->share_access = fsp->share_access;
|
||||
e->private_options = fsp->fh->private_options;
|
||||
e->access_mask = fsp->access_mask;
|
||||
e->op_port = port;
|
||||
e->op_type = op_type;
|
||||
memcpy(x, &fsp->open_time, sizeof(struct timeval));
|
||||
@ -581,16 +604,17 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
|
||||
e1->share_file_id == e2->share_file_id &&
|
||||
e1->dev == e2->dev &&
|
||||
e1->inode == e2->inode &&
|
||||
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
|
||||
DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
|
||||
(unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
|
||||
(unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
|
||||
(e1->share_access) != (e2->share_access)) {
|
||||
DEBUG(0,("PANIC: share_modes_identical: share_mode "
|
||||
"mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
|
||||
(unsigned int)e1->share_access,
|
||||
(unsigned int)e2->share_access ));
|
||||
smb_panic("PANIC: share_modes_identical logic error.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return (e1->pid == e2->pid &&
|
||||
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
|
||||
(e1->share_access) == (e2->share_access) &&
|
||||
e1->dev == e2->dev &&
|
||||
e1->inode == e2->inode &&
|
||||
e1->share_file_id == e2->share_file_id );
|
||||
@ -602,8 +626,9 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
|
||||
Ignore if no entry deleted.
|
||||
********************************************************************/
|
||||
|
||||
ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
||||
share_mode_entry *entry, share_mode_entry **ppse)
|
||||
ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode,
|
||||
share_mode_entry *entry, share_mode_entry **ppse,
|
||||
BOOL *delete_on_close)
|
||||
{
|
||||
TDB_DATA dbuf;
|
||||
struct locking_data *data;
|
||||
@ -621,6 +646,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
||||
return -1;
|
||||
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
*delete_on_close = data->u.s.delete_on_close;
|
||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
||||
|
||||
/*
|
||||
@ -629,15 +655,15 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
||||
* from the record.
|
||||
*/
|
||||
|
||||
DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries ));
|
||||
DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries ));
|
||||
|
||||
for (i=0;i<data->u.num_share_mode_entries;) {
|
||||
for (i=0;i<data->u.s.num_share_mode_entries;) {
|
||||
if (share_modes_identical(&shares[i], entry)) {
|
||||
DEBUG(10,("del_share_entry: deleted %s\n",
|
||||
share_mode_str(i, &shares[i]) ));
|
||||
if (ppse)
|
||||
*ppse = memdup(&shares[i], sizeof(*shares));
|
||||
data->u.num_share_mode_entries--;
|
||||
data->u.s.num_share_mode_entries--;
|
||||
if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) {
|
||||
memmove(&shares[i], &shares[i+1],
|
||||
dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
|
||||
@ -655,10 +681,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
||||
/* the record may have shrunk a bit */
|
||||
dbuf.dsize -= del_count * sizeof(*shares);
|
||||
|
||||
count = (ssize_t)data->u.num_share_mode_entries;
|
||||
count = (ssize_t)data->u.s.num_share_mode_entries;
|
||||
|
||||
/* store it back in the database */
|
||||
if (data->u.num_share_mode_entries == 0) {
|
||||
if (data->u.s.num_share_mode_entries == 0) {
|
||||
if (tdb_delete(tdb, key) == -1)
|
||||
count = -1;
|
||||
} else {
|
||||
@ -677,7 +703,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
||||
of entries left, and a memdup'ed copy of the entry deleted.
|
||||
********************************************************************/
|
||||
|
||||
ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
|
||||
ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse,
|
||||
BOOL *delete_on_close)
|
||||
{
|
||||
share_mode_entry entry;
|
||||
|
||||
@ -686,7 +713,8 @@ ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
|
||||
*/
|
||||
|
||||
fill_share_mode((char *)&entry, fsp, 0, 0);
|
||||
return del_share_entry(fsp->dev, fsp->inode, &entry, ppse);
|
||||
return del_share_entry(fsp->dev, fsp->inode, &entry, ppse,
|
||||
delete_on_close);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -718,7 +746,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
|
||||
if (!p)
|
||||
return False;
|
||||
data = (struct locking_data *)p;
|
||||
data->u.num_share_mode_entries = 1;
|
||||
ZERO_STRUCT(data->u); /* Keep valgrind happy */
|
||||
data->u.s.num_share_mode_entries = 1;
|
||||
|
||||
DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
|
||||
fsp->fsp_name ));
|
||||
@ -740,10 +769,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
|
||||
/* we're adding to an existing entry - this is a bit fiddly */
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
|
||||
data->u.num_share_mode_entries++;
|
||||
data->u.s.num_share_mode_entries++;
|
||||
|
||||
DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
|
||||
fsp->fsp_name, data->u.num_share_mode_entries ));
|
||||
fsp->fsp_name, data->u.s.num_share_mode_entries ));
|
||||
|
||||
size = dbuf.dsize + sizeof(share_mode_entry);
|
||||
p = SMB_MALLOC(size);
|
||||
@ -790,7 +819,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
|
||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
||||
|
||||
/* find any with our pid and call the supplied function */
|
||||
for (i=0;i<data->u.num_share_mode_entries;i++) {
|
||||
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
|
||||
if (share_modes_identical(entry, &shares[i])) {
|
||||
mod_fn(&shares[i], dev, inode, param);
|
||||
need_store=True;
|
||||
@ -799,7 +828,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
|
||||
|
||||
/* if the mod fn was called then store it back */
|
||||
if (need_store) {
|
||||
if (data->u.num_share_mode_entries == 0) {
|
||||
if (data->u.s.num_share_mode_entries == 0) {
|
||||
if (tdb_delete(tdb, key) == -1)
|
||||
ret = False;
|
||||
} else {
|
||||
@ -877,8 +906,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
|
||||
{
|
||||
TDB_DATA dbuf;
|
||||
struct locking_data *data;
|
||||
int i;
|
||||
share_mode_entry *shares;
|
||||
BOOL res;
|
||||
TDB_DATA key = locking_key(dev, inode);
|
||||
|
||||
/* read in the existing share modes */
|
||||
@ -887,25 +915,14 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
|
||||
return False;
|
||||
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
||||
|
||||
/* Set/Unset the delete on close element. */
|
||||
for (i=0;i<data->u.num_share_mode_entries;i++,shares++) {
|
||||
shares->share_mode = (delete_on_close ?
|
||||
(shares->share_mode | DELETE_ON_CLOSE_FLAG) :
|
||||
(shares->share_mode & ~DELETE_ON_CLOSE_FLAG) );
|
||||
}
|
||||
data->u.s.delete_on_close = delete_on_close;
|
||||
|
||||
/* store it back */
|
||||
if (data->u.num_share_mode_entries) {
|
||||
if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
|
||||
SAFE_FREE(dbuf.dptr);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1);
|
||||
|
||||
SAFE_FREE(dbuf.dptr);
|
||||
return True;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -1200,6 +1217,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T
|
||||
if (!p)
|
||||
return False;
|
||||
data = (struct deferred_open_data *)p;
|
||||
ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */
|
||||
data->u.num_deferred_open_entries = 1;
|
||||
|
||||
DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n",
|
||||
@ -1268,9 +1286,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
|
||||
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
||||
name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares);
|
||||
name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares);
|
||||
|
||||
for (i=0;i<data->u.num_share_mode_entries;i++) {
|
||||
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
|
||||
traverse_callback(&shares[i], name);
|
||||
}
|
||||
return 0;
|
||||
|
@ -114,7 +114,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
|
||||
} else
|
||||
dbuf.dptr = tp;
|
||||
|
||||
memcpy(dbuf.dptr + dbuf.dsize, &fsp->fd, sizeof(int));
|
||||
memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
|
||||
dbuf.dsize += sizeof(int);
|
||||
|
||||
if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
|
||||
@ -209,8 +209,8 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
||||
/*
|
||||
* No POSIX to worry about, just close.
|
||||
*/
|
||||
ret = SMB_VFS_CLOSE(fsp,fsp->fd);
|
||||
fsp->fd = -1;
|
||||
ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
|
||||
fsp->fh->fd = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -227,7 +227,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
||||
*/
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (entries[i].fd != fsp->fd) {
|
||||
if (entries[i].fd != fsp->fh->fd) {
|
||||
locks_on_other_fds = True;
|
||||
break;
|
||||
}
|
||||
@ -237,7 +237,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
||||
|
||||
/*
|
||||
* There are outstanding locks on this dev/inode pair on other fds.
|
||||
* Add our fd to the pending close tdb and set fsp->fd to -1.
|
||||
* Add our fd to the pending close tdb and set fsp->fh->fd to -1.
|
||||
*/
|
||||
|
||||
if (!add_fd_to_close_entry(fsp)) {
|
||||
@ -246,7 +246,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
||||
}
|
||||
|
||||
SAFE_FREE(entries);
|
||||
fsp->fd = -1;
|
||||
fsp->fh->fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -282,14 +282,14 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
||||
* Finally close the fd associated with this fsp.
|
||||
*/
|
||||
|
||||
ret = SMB_VFS_CLOSE(fsp,fsp->fd);
|
||||
ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
|
||||
|
||||
if (saved_errno != 0) {
|
||||
errno = saved_errno;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
fsp->fd = -1;
|
||||
fsp->fh->fd = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -371,7 +371,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
|
||||
* Add new record.
|
||||
*/
|
||||
|
||||
pl.fd = fsp->fd;
|
||||
pl.fd = fsp->fh->fd;
|
||||
pl.start = start;
|
||||
pl.size = size;
|
||||
pl.lock_type = lock_type;
|
||||
@ -455,7 +455,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T
|
||||
for (i=0; i<count; i++) {
|
||||
struct posix_lock *entry = &locks[i];
|
||||
|
||||
if (entry->fd == fsp->fd &&
|
||||
if (entry->fd == fsp->fh->fd &&
|
||||
entry->start == start &&
|
||||
entry->size == size) {
|
||||
|
||||
@ -490,7 +490,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T
|
||||
for (i = 0; i < count; i++) {
|
||||
struct posix_lock *entry = &locks[i];
|
||||
|
||||
if (fsp->fd == entry->fd &&
|
||||
if (fsp->fh->fd == entry->fd &&
|
||||
does_lock_overlap( start, size, entry->start, entry->size))
|
||||
num_overlapping_records++;
|
||||
}
|
||||
@ -524,13 +524,17 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
|
||||
*/
|
||||
DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n"));
|
||||
return F_RDLCK;
|
||||
} else if((lock_type == READ_LOCK) && !fsp->can_read) {
|
||||
}
|
||||
#if 0
|
||||
/* We no longer open files write-only. */
|
||||
else if((lock_type == READ_LOCK) && !fsp->can_read) {
|
||||
/*
|
||||
* Ditto for read locks on write only files.
|
||||
*/
|
||||
DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n"));
|
||||
return F_WRLCK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This return should be the most normal, as we attempt
|
||||
@ -652,9 +656,9 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
|
||||
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type));
|
||||
|
||||
ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
|
||||
ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
|
||||
|
||||
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
|
||||
|
||||
@ -678,7 +682,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
|
||||
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
|
||||
errno = 0;
|
||||
count &= 0x7fffffff;
|
||||
ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
|
||||
ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1247,7 +1251,7 @@ void posix_locking_close_file(files_struct *fsp)
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (entries[i].fd != fsp->fd )
|
||||
if (entries[i].fd != fsp->fh->fd )
|
||||
break;
|
||||
|
||||
dump_entry(&entries[i]);
|
||||
@ -1269,7 +1273,7 @@ void posix_locking_close_file(files_struct *fsp)
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct posix_lock *pl = &entries[i];
|
||||
if (pl->fd == fsp->fd)
|
||||
if (pl->fd == fsp->fh->fd)
|
||||
release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size );
|
||||
}
|
||||
SAFE_FREE(entries);
|
||||
|
@ -605,13 +605,13 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
|
||||
|
||||
struct afs_ace *afs_ace;
|
||||
|
||||
if (fsp->is_directory || fsp->fd == -1) {
|
||||
if (fsp->is_directory || fsp->fh->fd == -1) {
|
||||
/* Get the stat struct for the owner info. */
|
||||
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -922,7 +922,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
|
||||
}
|
||||
|
||||
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
|
||||
if (SMB_VFS_LSEEK(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
|
||||
if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
|
||||
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
|
||||
fname, errno));
|
||||
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
|
||||
@ -988,7 +988,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
|
||||
}
|
||||
|
||||
/* Seek to the start of the .rsrc section info */
|
||||
if (SMB_VFS_LSEEK(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
|
||||
if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
|
||||
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
|
||||
fname, errno));
|
||||
goto error_exit;
|
||||
@ -1084,7 +1084,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
|
||||
* twice, as it is simpler to read the code. */
|
||||
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
|
||||
/* Compute skip alignment to next long address */
|
||||
int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
|
||||
int skip = -(SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR) - (byte_count - i) +
|
||||
sizeof(VS_SIGNATURE)) & 3;
|
||||
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
|
||||
|
||||
@ -1142,8 +1142,6 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
uint32 old_minor;
|
||||
time_t old_create_time;
|
||||
|
||||
int access_mode;
|
||||
int action;
|
||||
files_struct *fsp = NULL;
|
||||
SMB_STRUCT_STAT st;
|
||||
SMB_STRUCT_STAT stat_buf;
|
||||
@ -1159,10 +1157,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
|
||||
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
|
||||
|
||||
fsp = open_file_shared(conn, filepath, &stat_buf,
|
||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
||||
fsp = open_file_ntcreate(conn, filepath, &stat_buf,
|
||||
FILE_GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
/* Old file not found, so by definition new file is in fact newer */
|
||||
DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
|
||||
@ -1171,13 +1174,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
|
||||
} else {
|
||||
int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
|
||||
if (ret == -1) goto error_exit;
|
||||
if (ret == -1) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
||||
old_file));
|
||||
use_version = False;
|
||||
if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
|
||||
if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
|
||||
old_create_time = st.st_mtime;
|
||||
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
|
||||
}
|
||||
@ -1188,10 +1193,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
pstrcpy(filepath, new_file);
|
||||
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
|
||||
|
||||
fsp = open_file_shared(conn, filepath, &stat_buf,
|
||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
||||
fsp = open_file_ntcreate(conn, filepath, &stat_buf,
|
||||
FILE_GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
/* New file not found, this shouldn't occur if the caller did its job */
|
||||
DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
|
||||
@ -1200,13 +1210,15 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
|
||||
} else {
|
||||
int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
|
||||
if (ret == -1) goto error_exit;
|
||||
if (ret == -1) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
||||
new_file));
|
||||
use_version = False;
|
||||
if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
|
||||
if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
|
||||
new_create_time = st.st_mtime;
|
||||
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
|
||||
}
|
||||
@ -1251,8 +1263,6 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
|
||||
struct current_user *user, WERROR *perr)
|
||||
{
|
||||
int cversion;
|
||||
int access_mode;
|
||||
int action;
|
||||
NTSTATUS nt_status;
|
||||
pstring driverpath;
|
||||
DATA_BLOB null_pw;
|
||||
@ -1309,18 +1319,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
fsp = open_file_shared(conn, driverpath, &st,
|
||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
||||
fsp = open_file_ntcreate(conn, driverpath, &st,
|
||||
FILE_GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
|
||||
driverpath, errno));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint32 major;
|
||||
uint32 minor;
|
||||
int ret = get_file_version(fsp, driverpath, &major, &minor);
|
||||
@ -1660,7 +1673,8 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
||||
if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
new_name, old_name));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
@ -1675,7 +1689,8 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
||||
if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
new_name, old_name));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
@ -1692,7 +1707,8 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
||||
if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
new_name, old_name));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
@ -1710,7 +1726,8 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
||||
if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
new_name, old_name));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
@ -1737,7 +1754,9 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
||||
if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
if ( !copy_file(new_name, old_name, conn,
|
||||
OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
new_name, old_name));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
|
@ -28,7 +28,7 @@ open a print file and setup a fsp for it. This is a wrapper around
|
||||
print_job_start().
|
||||
***************************************************************************/
|
||||
|
||||
files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
files_struct *print_fsp_open(connection_struct *conn, const char *fname)
|
||||
{
|
||||
int jobid;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
@ -40,10 +40,11 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
|
||||
fstrcpy( name, "Remote Downlevel Document");
|
||||
if (fname) {
|
||||
char *p = strrchr(fname, '/');
|
||||
const char *p = strrchr(fname, '/');
|
||||
fstrcat(name, " ");
|
||||
if (!p)
|
||||
if (!p) {
|
||||
p = fname;
|
||||
}
|
||||
fstrcat(name, p);
|
||||
}
|
||||
|
||||
@ -63,24 +64,23 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
}
|
||||
|
||||
/* setup a full fsp */
|
||||
fsp->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
|
||||
fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
|
||||
GetTimeOfDay(&fsp->open_time);
|
||||
fsp->vuid = current_user.vuid;
|
||||
fsp->pos = -1;
|
||||
fsp->fh->pos = -1;
|
||||
fsp->can_lock = True;
|
||||
fsp->can_read = False;
|
||||
fsp->access_mask = FILE_GENERIC_WRITE;
|
||||
fsp->can_write = True;
|
||||
fsp->share_mode = 0;
|
||||
fsp->print_file = True;
|
||||
fsp->modified = False;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||
fsp->is_directory = False;
|
||||
fsp->directory_delete_on_close = False;
|
||||
string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
|
||||
fsp->wbmpx_ptr = NULL;
|
||||
fsp->wcp = NULL;
|
||||
SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf);
|
||||
SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf);
|
||||
fsp->mode = sbuf.st_mode;
|
||||
fsp->inode = sbuf.st_ino;
|
||||
fsp->dev = sbuf.st_dev;
|
||||
@ -91,19 +91,20 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
print a file - called on closing the file
|
||||
Print a file - called on closing the file.
|
||||
****************************************************************************/
|
||||
|
||||
void print_fsp_end(files_struct *fsp, BOOL normal_close)
|
||||
{
|
||||
uint32 jobid;
|
||||
fstring sharename;
|
||||
|
||||
if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
|
||||
if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) {
|
||||
/*
|
||||
* Truncate the job. print_job_end will take
|
||||
* care of deleting it for us. JRA.
|
||||
*/
|
||||
sys_ftruncate(fsp->fd, 0);
|
||||
sys_ftruncate(fsp->fh->fd, 0);
|
||||
}
|
||||
|
||||
if (fsp->fsp_name) {
|
||||
|
@ -1976,8 +1976,6 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
|
||||
files_struct *fsp = NULL;
|
||||
SMB_STRUCT_STAT st;
|
||||
BOOL bad_path;
|
||||
int access_mode;
|
||||
int action;
|
||||
NTSTATUS nt_status;
|
||||
struct current_user user;
|
||||
connection_struct *conn = NULL;
|
||||
@ -2025,15 +2023,16 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
||||
&access_mode, &action);
|
||||
|
||||
fsp = open_file_stat(conn, filename, &st);
|
||||
if (!fsp) {
|
||||
/* Perhaps it is a directory */
|
||||
if (errno == EISDIR)
|
||||
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
|
||||
fsp = open_directory(conn, filename, &st,
|
||||
READ_CONTROL_ACCESS,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
|
||||
@ -2092,8 +2091,6 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
|
||||
files_struct *fsp = NULL;
|
||||
SMB_STRUCT_STAT st;
|
||||
BOOL bad_path;
|
||||
int access_mode;
|
||||
int action;
|
||||
NTSTATUS nt_status;
|
||||
struct current_user user;
|
||||
connection_struct *conn = NULL;
|
||||
@ -2142,15 +2139,17 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
|
||||
}
|
||||
|
||||
|
||||
fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
||||
&access_mode, &action);
|
||||
fsp = open_file_stat(conn, filename, &st);
|
||||
|
||||
if (!fsp) {
|
||||
/* Perhaps it is a directory */
|
||||
if (errno == EISDIR)
|
||||
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
|
||||
fsp = open_directory(conn, filename, &st,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
|
||||
@ -2178,11 +2177,13 @@ error_exit:
|
||||
close_file(fsp, True);
|
||||
}
|
||||
|
||||
if (became_user)
|
||||
if (became_user) {
|
||||
unbecome_user();
|
||||
}
|
||||
|
||||
if (conn)
|
||||
if (conn) {
|
||||
close_cnum(conn, user.vuid);
|
||||
}
|
||||
|
||||
return r_u->status;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
file closing
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Jeremy Allison 1992-2004.
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -92,7 +93,7 @@ static int close_filestruct(files_struct *fsp)
|
||||
connection_struct *conn = fsp->conn;
|
||||
int ret = 0;
|
||||
|
||||
if (fsp->fd != -1) {
|
||||
if (fsp->fh->fd != -1) {
|
||||
if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
|
||||
ret = -1;
|
||||
|
||||
@ -148,7 +149,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
||||
{
|
||||
share_mode_entry *share_entry = NULL;
|
||||
size_t share_entry_count = 0;
|
||||
BOOL delete_on_close = False;
|
||||
BOOL delete_file = False;
|
||||
connection_struct *conn = fsp->conn;
|
||||
int saved_errno = 0;
|
||||
int err = 0;
|
||||
@ -194,34 +195,16 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
||||
|
||||
lock_share_entry_fsp(fsp);
|
||||
|
||||
if (fsp->delete_on_close) {
|
||||
|
||||
/*
|
||||
* Modify the share mode entry for all files open
|
||||
* on this device and inode to tell other smbds we have
|
||||
* changed the delete on close flag. The last closer will delete the file
|
||||
* if flag is set.
|
||||
*/
|
||||
|
||||
NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close);
|
||||
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
|
||||
DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n",
|
||||
fsp->fsp_name ));
|
||||
}
|
||||
|
||||
share_entry_count = del_share_mode(fsp, &share_entry);
|
||||
share_entry_count = del_share_mode(fsp, &share_entry,
|
||||
&delete_file);
|
||||
|
||||
DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
|
||||
(unsigned long)share_entry_count, fsp->fsp_name ));
|
||||
|
||||
/*
|
||||
* We delete on close if it's the last open, and the
|
||||
* delete on close flag was set in the entry we just deleted.
|
||||
*/
|
||||
|
||||
if ((share_entry_count == 0) && share_entry &&
|
||||
GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
|
||||
delete_on_close = True;
|
||||
if (share_entry_count != 0) {
|
||||
/* We're not the last ones -- don't delete */
|
||||
delete_file = False;
|
||||
}
|
||||
|
||||
SAFE_FREE(share_entry);
|
||||
|
||||
@ -233,7 +216,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
||||
* reference to a file.
|
||||
*/
|
||||
|
||||
if (normal_close && delete_on_close) {
|
||||
if (normal_close && delete_file) {
|
||||
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
|
||||
fsp->fsp_name));
|
||||
if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
|
||||
@ -311,7 +294,8 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
|
||||
* reference to a directory also.
|
||||
*/
|
||||
|
||||
if (normal_close && fsp->directory_delete_on_close) {
|
||||
if (normal_close &&
|
||||
get_delete_on_close_flag(fsp->dev, fsp->inode)) {
|
||||
BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
|
||||
DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
|
||||
fsp->fsp_name, ok ? "succeeded" : "failed" ));
|
||||
@ -321,8 +305,9 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
|
||||
* now fail as the directory has been deleted.
|
||||
*/
|
||||
|
||||
if(ok)
|
||||
if(ok) {
|
||||
remove_pending_change_notify_requests_by_filename(fsp);
|
||||
}
|
||||
process_pending_change_notify_queue((time_t)0);
|
||||
}
|
||||
|
||||
@ -331,8 +316,9 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
|
||||
*/
|
||||
close_filestruct(fsp);
|
||||
|
||||
if (fsp->fsp_name)
|
||||
if (fsp->fsp_name) {
|
||||
string_free(&fsp->fsp_name);
|
||||
}
|
||||
|
||||
file_free(fsp);
|
||||
return 0;
|
||||
|
@ -822,7 +822,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
|
||||
SEC_DESC *psd = NULL;
|
||||
size_t sd_size;
|
||||
files_struct *fsp;
|
||||
int smb_action;
|
||||
NTSTATUS status;
|
||||
uint32 access_granted;
|
||||
|
||||
@ -831,32 +830,41 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
|
||||
* we never hide files from them.
|
||||
*/
|
||||
|
||||
if (conn->admin_user)
|
||||
if (conn->admin_user) {
|
||||
return True;
|
||||
}
|
||||
|
||||
/* If we can't stat it does not show it */
|
||||
if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
|
||||
if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Pseudo-open the file (note - no fd's created). */
|
||||
|
||||
if(S_ISDIR(pst->st_mode))
|
||||
fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
&smb_action);
|
||||
else
|
||||
if(S_ISDIR(pst->st_mode)) {
|
||||
fsp = open_directory(conn, name, pst,
|
||||
READ_CONTROL_ACCESS,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0, /* no create options. */
|
||||
NULL);
|
||||
} else {
|
||||
fsp = open_file_stat(conn, name, pst);
|
||||
}
|
||||
|
||||
if (!fsp)
|
||||
if (!fsp) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
|
||||
sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
|
||||
sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd,
|
||||
(OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
|
||||
close_file(fsp, True);
|
||||
|
||||
/* No access if SD get failed. */
|
||||
if (!sd_size)
|
||||
if (!sd_size) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
|
||||
&access_granted, &status);
|
||||
@ -874,8 +882,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
|
||||
SEC_DESC *psd = NULL;
|
||||
size_t sd_size;
|
||||
files_struct *fsp;
|
||||
int smb_action;
|
||||
int access_mode;
|
||||
int info;
|
||||
NTSTATUS status;
|
||||
uint32 access_granted;
|
||||
|
||||
@ -884,27 +891,36 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
|
||||
* we never hide files from them.
|
||||
*/
|
||||
|
||||
if (conn->admin_user)
|
||||
if (conn->admin_user) {
|
||||
return True;
|
||||
}
|
||||
|
||||
/* If we can't stat it does not show it */
|
||||
if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
|
||||
if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Pseudo-open the file (note - no fd's created). */
|
||||
/* Pseudo-open the file */
|
||||
|
||||
if(S_ISDIR(pst->st_mode))
|
||||
if(S_ISDIR(pst->st_mode)) {
|
||||
return True;
|
||||
else
|
||||
fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
||||
&access_mode, &smb_action);
|
||||
} else {
|
||||
fsp = open_file_ntcreate(conn, name, pst,
|
||||
FILE_WRITE_ATTRIBUTES,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
&info);
|
||||
}
|
||||
|
||||
if (!fsp)
|
||||
if (!fsp) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
|
||||
sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
|
||||
sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd,
|
||||
(OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
|
||||
close_file(fsp, False);
|
||||
|
||||
|
@ -430,7 +430,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
|
||||
if (!fsp)
|
||||
return -1;
|
||||
become_root();
|
||||
ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode);
|
||||
ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode);
|
||||
unbecome_root();
|
||||
close_file_fchmod(fsp);
|
||||
}
|
||||
|
@ -22,77 +22,6 @@
|
||||
|
||||
extern struct current_user current_user;
|
||||
|
||||
/****************************************************************************
|
||||
Open a file with a share mode.
|
||||
****************************************************************************/
|
||||
files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname,
|
||||
SMB_STRUCT_STAT *psbuf,
|
||||
uint32 desired_access,
|
||||
int share_mode,int ofun, uint32 new_dos_attr, int oplock_request,
|
||||
int *Access,int *action)
|
||||
{
|
||||
int flags=0;
|
||||
files_struct *fsp = NULL;
|
||||
|
||||
if (fake_file_type == 0) {
|
||||
return open_file_shared1(conn,fname,psbuf,desired_access,
|
||||
share_mode,ofun,new_dos_attr,
|
||||
oplock_request,Access,action);
|
||||
}
|
||||
|
||||
/* access check */
|
||||
if (current_user.uid != 0) {
|
||||
DEBUG(1,("access_denied to service[%s] file[%s] user[%s]\n",
|
||||
lp_servicename(SNUM(conn)),fname,conn->user));
|
||||
errno = EACCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsp = file_new(conn);
|
||||
if(!fsp)
|
||||
return NULL;
|
||||
|
||||
DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n",
|
||||
fname, fsp->fnum, share_mode, ofun, oplock_request ));
|
||||
|
||||
if (!check_name(fname,conn)) {
|
||||
file_free(fsp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsp->fd = -1;
|
||||
fsp->mode = psbuf->st_mode;
|
||||
fsp->inode = psbuf->st_ino;
|
||||
fsp->dev = psbuf->st_dev;
|
||||
fsp->vuid = current_user.vuid;
|
||||
fsp->pos = -1;
|
||||
fsp->can_lock = True;
|
||||
fsp->can_read = ((flags & O_WRONLY)==0);
|
||||
fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
|
||||
fsp->share_mode = 0;
|
||||
fsp->desired_access = desired_access;
|
||||
fsp->print_file = False;
|
||||
fsp->modified = False;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||
fsp->is_directory = False;
|
||||
fsp->is_stat = False;
|
||||
fsp->directory_delete_on_close = False;
|
||||
fsp->conn = conn;
|
||||
string_set(&fsp->fsp_name,fname);
|
||||
fsp->wcp = NULL; /* Write cache pointer. */
|
||||
|
||||
fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
|
||||
|
||||
if (fsp->fake_file_handle==NULL) {
|
||||
file_free(fsp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->num_files_open++;
|
||||
return fsp;
|
||||
}
|
||||
|
||||
static FAKE_FILE fake_files[] = {
|
||||
#ifdef WITH_QUOTAS
|
||||
{FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle, destroy_quota_handle},
|
||||
@ -100,24 +29,11 @@ static FAKE_FILE fake_files[] = {
|
||||
{NULL, FAKE_FILE_TYPE_NONE, NULL, NULL }
|
||||
};
|
||||
|
||||
int is_fake_file(char *fname)
|
||||
{
|
||||
int i;
|
||||
/****************************************************************************
|
||||
Create a fake file handle
|
||||
****************************************************************************/
|
||||
|
||||
if (!fname)
|
||||
return 0;
|
||||
|
||||
for (i=0;fake_files[i].name!=NULL;i++) {
|
||||
if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
|
||||
DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
|
||||
return fake_files[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
return FAKE_FILE_TYPE_NONE;
|
||||
}
|
||||
|
||||
struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
|
||||
static struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
FAKE_FILE_HANDLE *fh = NULL;
|
||||
@ -141,8 +57,9 @@ struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
|
||||
fh->type = type;
|
||||
fh->mem_ctx = mem_ctx;
|
||||
|
||||
if (fake_files[i].init_pd)
|
||||
if (fake_files[i].init_pd) {
|
||||
fh->pd = fake_files[i].init_pd(fh->mem_ctx);
|
||||
}
|
||||
|
||||
fh->free_pd = fake_files[i].free_pd;
|
||||
|
||||
@ -153,13 +70,88 @@ struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Does this name match a fake filename ?
|
||||
****************************************************************************/
|
||||
|
||||
enum FAKE_FILE_TYPE is_fake_file(const char *fname)
|
||||
{
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (!fname) {
|
||||
return FAKE_FILE_TYPE_NONE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
for (i=0;fake_files[i].name!=NULL;i++) {
|
||||
if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
|
||||
DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
|
||||
return fake_files[i].type;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return FAKE_FILE_TYPE_NONE;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Open a fake quota file with a share mode.
|
||||
****************************************************************************/
|
||||
|
||||
files_struct *open_fake_file(connection_struct *conn,
|
||||
enum FAKE_FILE_TYPE fake_file_type,
|
||||
const char *fname,
|
||||
uint32 access_mask)
|
||||
{
|
||||
files_struct *fsp = NULL;
|
||||
|
||||
/* access check */
|
||||
if (current_user.uid != 0) {
|
||||
DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n",
|
||||
lp_servicename(SNUM(conn)),fname,conn->user));
|
||||
errno = EACCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsp = file_new(conn);
|
||||
if(!fsp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
|
||||
fname, fsp->fnum, (unsigned int)access_mask));
|
||||
|
||||
fsp->conn = conn;
|
||||
fsp->fh->fd = -1;
|
||||
fsp->vuid = current_user.vuid;
|
||||
fsp->fh->pos = -1;
|
||||
fsp->can_lock = True; /* Should this be true ? */
|
||||
fsp->access_mask = access_mask;
|
||||
string_set(&fsp->fsp_name,fname);
|
||||
|
||||
fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
|
||||
|
||||
if (fsp->fake_file_handle==NULL) {
|
||||
file_free(fsp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->num_files_open++;
|
||||
return fsp;
|
||||
}
|
||||
|
||||
void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
|
||||
{
|
||||
if (!fh||!(*fh))
|
||||
if (!fh||!(*fh)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*fh)->free_pd)
|
||||
if ((*fh)->free_pd) {
|
||||
(*fh)->free_pd(&(*fh)->pd);
|
||||
}
|
||||
|
||||
talloc_destroy((*fh)->mem_ctx);
|
||||
(*fh) = NULL;
|
||||
|
@ -65,20 +65,20 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
|
||||
*/
|
||||
|
||||
if(read_from_write_cache(fsp, data, pos, n)) {
|
||||
fsp->pos = pos + n;
|
||||
fsp->position_information = fsp->pos;
|
||||
fsp->fh->pos = pos + n;
|
||||
fsp->fh->position_information = fsp->fh->pos;
|
||||
return n;
|
||||
}
|
||||
|
||||
flush_write_cache(fsp, READ_FLUSH);
|
||||
|
||||
fsp->pos = pos;
|
||||
fsp->fh->pos = pos;
|
||||
|
||||
if (n > 0) {
|
||||
#ifdef DMF_FIX
|
||||
int numretries = 3;
|
||||
tryagain:
|
||||
readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
|
||||
readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos);
|
||||
|
||||
if (readret == -1) {
|
||||
if ((errno == EAGAIN) && numretries) {
|
||||
@ -90,7 +90,7 @@ tryagain:
|
||||
return -1;
|
||||
}
|
||||
#else /* NO DMF fix. */
|
||||
readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
|
||||
readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos);
|
||||
|
||||
if (readret == -1) {
|
||||
return -1;
|
||||
@ -104,8 +104,8 @@ tryagain:
|
||||
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
|
||||
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
|
||||
|
||||
fsp->pos += ret;
|
||||
fsp->position_information = fsp->pos;
|
||||
fsp->fh->pos += ret;
|
||||
fsp->fh->position_information = fsp->fh->pos;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -124,7 +124,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos
|
||||
if (pos == -1) {
|
||||
ret = vfs_write_data(fsp, data, n);
|
||||
} else {
|
||||
fsp->pos = pos;
|
||||
fsp->fh->pos = pos;
|
||||
if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
|
||||
if (vfs_fill_sparse(fsp, pos) == -1) {
|
||||
return -1;
|
||||
@ -137,7 +137,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos
|
||||
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
|
||||
|
||||
if (ret != -1) {
|
||||
fsp->pos += ret;
|
||||
fsp->fh->pos += ret;
|
||||
|
||||
/*
|
||||
* It turns out that setting the last write time from a Windows
|
||||
@ -180,7 +180,7 @@ static int wcp_file_size_change(files_struct *fsp)
|
||||
write_cache *wcp = fsp->wcp;
|
||||
|
||||
wcp->file_size = wcp->offset + wcp->data_size;
|
||||
ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, wcp->file_size);
|
||||
ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, wcp->file_size);
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
|
||||
fsp->fsp_name, (double)wcp->file_size, strerror(errno) ));
|
||||
@ -221,7 +221,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n)
|
||||
SMB_STRUCT_STAT st;
|
||||
fsp->modified = True;
|
||||
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) {
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
|
||||
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
|
||||
if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
|
||||
file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False);
|
||||
@ -288,9 +288,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
|
||||
}
|
||||
|
||||
DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
|
||||
fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
|
||||
fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
|
||||
|
||||
fsp->pos = pos + n;
|
||||
fsp->fh->pos = pos + n;
|
||||
|
||||
/*
|
||||
* If we have active cache and it isn't contiguous then we flush.
|
||||
@ -589,7 +589,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
|
||||
*/
|
||||
|
||||
DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \
|
||||
len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||
len = %u\n",fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||
|
||||
/*
|
||||
* If write would fit in the cache, and is larger than
|
||||
@ -612,7 +612,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
|
||||
if ((pos <= wcp->offset) &&
|
||||
(pos + n >= wcp->offset + wcp->data_size) ) {
|
||||
DEBUG(9,("write_file: discarding overwritten write \
|
||||
cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||
cache: fd = %d, off=%.0f, size=%u\n", fsp->fh->fd, (double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||
wcp->data_size = 0;
|
||||
}
|
||||
|
||||
@ -635,7 +635,7 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in
|
||||
if (cache_flush_needed) {
|
||||
DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
|
||||
n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
|
||||
write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n,
|
||||
write_path, fsp->fh->fd, (double)wcp->file_size, (double)pos, (unsigned int)n,
|
||||
(double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||
|
||||
flush_write_cache(fsp, WRITE_FLUSH);
|
||||
@ -809,7 +809,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
|
||||
DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]);
|
||||
|
||||
DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
|
||||
fsp->fd, (double)wcp->offset, (unsigned int)data_size));
|
||||
fsp->fh->fd, (double)wcp->offset, (unsigned int)data_size));
|
||||
|
||||
#ifdef WITH_PROFILE
|
||||
if(data_size == wcp->alloc_size) {
|
||||
@ -836,9 +836,9 @@ sync a file
|
||||
|
||||
void sync_file(connection_struct *conn, files_struct *fsp)
|
||||
{
|
||||
if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) {
|
||||
if(lp_strict_sync(SNUM(conn)) && fsp->fh->fd != -1) {
|
||||
flush_write_cache(fsp, SYNC_FLUSH);
|
||||
SMB_VFS_FSYNC(fsp,fsp->fd);
|
||||
SMB_VFS_FSYNC(fsp,fsp->fh->fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,9 +849,9 @@ void sync_file(connection_struct *conn, files_struct *fsp)
|
||||
|
||||
int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
if (fsp->fd == -1) {
|
||||
if (fsp->fh->fd == -1) {
|
||||
return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst);
|
||||
} else {
|
||||
return SMB_VFS_FSTAT(fsp,fsp->fd, pst);
|
||||
return SMB_VFS_FSTAT(fsp,fsp->fh->fd, pst);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,19 @@ files_struct *file_new(connection_struct *conn)
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(fsp);
|
||||
fsp->fd = -1;
|
||||
|
||||
fsp->fh = SMB_MALLOC_P(struct fd_handle);
|
||||
if (!fsp->fh) {
|
||||
SAFE_FREE(fsp);
|
||||
set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(fsp->fh);
|
||||
|
||||
fsp->fh->ref_count = 1;
|
||||
fsp->fh->fd = -1;
|
||||
|
||||
fsp->conn = conn;
|
||||
fsp->file_id = get_gen_count();
|
||||
GetTimeOfDay(&fsp->open_time);
|
||||
@ -233,7 +245,7 @@ void file_dump_open_table(void)
|
||||
|
||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
||||
DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n",
|
||||
count, fsp->fnum, fsp->fsp_name, fsp->fd, (unsigned long)fsp->file_id,
|
||||
count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->file_id,
|
||||
(unsigned int)fsp->dev, (double)fsp->inode ));
|
||||
}
|
||||
}
|
||||
@ -248,7 +260,7 @@ files_struct *file_find_fd(int fd)
|
||||
files_struct *fsp;
|
||||
|
||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
||||
if (fsp->fd == fd) {
|
||||
if (fsp->fh->fd == fd) {
|
||||
if (count > 10) {
|
||||
DLIST_PROMOTE(Files, fsp);
|
||||
}
|
||||
@ -269,7 +281,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i
|
||||
files_struct *fsp;
|
||||
|
||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
||||
/* We can have a fsp->fd == -1 here as it could be a stat open. */
|
||||
/* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
|
||||
if (fsp->dev == dev &&
|
||||
fsp->inode == inode &&
|
||||
fsp->file_id == file_id ) {
|
||||
@ -277,7 +289,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i
|
||||
DLIST_PROMOTE(Files, fsp);
|
||||
}
|
||||
/* Paranoia check. */
|
||||
if (fsp->fd == -1 && fsp->oplock_type != NO_OPLOCK) {
|
||||
if (fsp->fh->fd == -1 && fsp->oplock_type != NO_OPLOCK) {
|
||||
DEBUG(0,("file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \
|
||||
oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, (unsigned int)fsp->dev,
|
||||
(double)fsp->inode, (unsigned int)fsp->file_id,
|
||||
@ -326,7 +338,7 @@ files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
|
||||
fsp_fi_cache.inode = inode;
|
||||
|
||||
for (fsp=Files;fsp;fsp=fsp->next) {
|
||||
if ( fsp->fd != -1 &&
|
||||
if ( fsp->fh->fd != -1 &&
|
||||
fsp->dev == dev &&
|
||||
fsp->inode == inode ) {
|
||||
/* Setup positive cache. */
|
||||
@ -349,7 +361,7 @@ files_struct *file_find_di_next(files_struct *start_fsp)
|
||||
files_struct *fsp;
|
||||
|
||||
for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
|
||||
if ( fsp->fd != -1 &&
|
||||
if ( fsp->fh->fd != -1 &&
|
||||
fsp->dev == start_fsp->dev &&
|
||||
fsp->inode == start_fsp->inode )
|
||||
return fsp;
|
||||
@ -389,7 +401,7 @@ void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
|
||||
}
|
||||
|
||||
for (fsp = Files;fsp;fsp=fsp->next) {
|
||||
if ( fsp->fd != -1 &&
|
||||
if ( fsp->fh->fd != -1 &&
|
||||
fsp->dev == tfsp->dev &&
|
||||
fsp->inode == tfsp->inode ) {
|
||||
fsp->pending_modtime = pmod;
|
||||
@ -410,7 +422,7 @@ void file_sync_all(connection_struct *conn)
|
||||
|
||||
for (fsp=Files;fsp;fsp=next) {
|
||||
next=fsp->next;
|
||||
if ((conn == fsp->conn) && (fsp->fd != -1)) {
|
||||
if ((conn == fsp->conn) && (fsp->fh->fd != -1)) {
|
||||
sync_file(conn,fsp);
|
||||
}
|
||||
}
|
||||
@ -430,6 +442,12 @@ void file_free(files_struct *fsp)
|
||||
destroy_fake_file_handle(&fsp->fake_file_handle);
|
||||
}
|
||||
|
||||
if (fsp->fh->ref_count == 1) {
|
||||
SAFE_FREE(fsp->fh);
|
||||
} else {
|
||||
fsp->fh->ref_count--;
|
||||
}
|
||||
|
||||
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
|
||||
files_used--;
|
||||
|
||||
@ -506,3 +524,49 @@ void file_chain_restore(void)
|
||||
{
|
||||
chain_fsp = oplock_save_chain_fsp;
|
||||
}
|
||||
|
||||
files_struct *dup_file_fsp(files_struct *fsp,
|
||||
uint32 access_mask,
|
||||
uint32 share_access,
|
||||
uint32 create_options)
|
||||
{
|
||||
files_struct *dup_fsp = file_new(fsp->conn);
|
||||
|
||||
if (!dup_fsp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SAFE_FREE(dup_fsp->fh);
|
||||
|
||||
dup_fsp->fh = fsp->fh;
|
||||
dup_fsp->fh->ref_count++;
|
||||
|
||||
dup_fsp->dev = fsp->dev;
|
||||
dup_fsp->inode = fsp->inode;
|
||||
dup_fsp->initial_allocation_size = fsp->initial_allocation_size;
|
||||
dup_fsp->mode = fsp->mode;
|
||||
dup_fsp->file_pid = fsp->file_pid;
|
||||
dup_fsp->vuid = fsp->vuid;
|
||||
dup_fsp->open_time = fsp->open_time;
|
||||
dup_fsp->access_mask = access_mask;
|
||||
dup_fsp->share_access = share_access;
|
||||
dup_fsp->pending_modtime_owner = fsp->pending_modtime_owner;
|
||||
dup_fsp->pending_modtime = fsp->pending_modtime;
|
||||
dup_fsp->last_write_time = fsp->last_write_time;
|
||||
dup_fsp->oplock_type = fsp->oplock_type;
|
||||
dup_fsp->can_lock = fsp->can_lock;
|
||||
dup_fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
|
||||
if (!CAN_WRITE(fsp->conn)) {
|
||||
dup_fsp->can_write = False;
|
||||
} else {
|
||||
dup_fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False;
|
||||
}
|
||||
dup_fsp->print_file = fsp->print_file;
|
||||
dup_fsp->modified = fsp->modified;
|
||||
dup_fsp->is_directory = fsp->is_directory;
|
||||
dup_fsp->is_stat = fsp->is_stat;
|
||||
dup_fsp->aio_write_behind = fsp->aio_write_behind;
|
||||
string_set(&dup_fsp->fsp_name,fsp->fsp_name);
|
||||
|
||||
return dup_fsp;
|
||||
}
|
||||
|
@ -259,4 +259,3 @@ void destroy_quota_handle(void **pqt_handle)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
1910
source/smbd/open.c
1910
source/smbd/open.c
File diff suppressed because it is too large
Load Diff
@ -343,6 +343,7 @@ BOOL process_local_message(char *buffer, int buf_size)
|
||||
SMB_INO_T inode;
|
||||
unsigned long file_id;
|
||||
uint16 break_cmd_type;
|
||||
struct sockaddr_in toaddr;
|
||||
|
||||
msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
|
||||
from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
|
||||
@ -366,6 +367,7 @@ BOOL process_local_message(char *buffer, int buf_size)
|
||||
}
|
||||
if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev, &file_id)) {
|
||||
DEBUG(0,("kernel oplock break parse failure!\n"));
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -449,49 +451,54 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
|
||||
* Now actually process the break request.
|
||||
*/
|
||||
|
||||
if((exclusive_oplocks_open + level_II_oplocks_open) != 0) {
|
||||
if (oplock_break(dev, inode, file_id, False) == False) {
|
||||
DEBUG(0,("process_local_message: oplock break failed.\n"));
|
||||
return False;
|
||||
}
|
||||
} else {
|
||||
if ((exclusive_oplocks_open == 0) &&
|
||||
(level_II_oplocks_open == 0)) {
|
||||
/*
|
||||
* If we have no record of any currently open oplocks,
|
||||
* it's not an error, as a close command may have
|
||||
* just been issued on the file that was oplocked.
|
||||
* Just log a message and return success in this case.
|
||||
*/
|
||||
DEBUG(3,("process_local_message: oplock break requested with no outstanding \
|
||||
oplocks. Returning success.\n"));
|
||||
DEBUG(3,("process_local_message: oplock break requested with "
|
||||
"no outstanding oplocks. Returning success.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
if (!oplock_break(dev, inode, file_id, False)) {
|
||||
DEBUG(0,("process_local_message: oplock break failed.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the appropriate reply - none in the kernel or async level II case.
|
||||
* Do the appropriate reply - none in the kernel or async level II
|
||||
* case.
|
||||
*/
|
||||
|
||||
if(break_cmd_type == OPLOCK_BREAK_CMD || break_cmd_type == LEVEL_II_OPLOCK_BREAK_CMD) {
|
||||
struct sockaddr_in toaddr;
|
||||
|
||||
/* Send the message back after OR'ing in the 'REPLY' bit. */
|
||||
SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type | CMD_REPLY);
|
||||
|
||||
memset((char *)&toaddr,'\0',sizeof(toaddr));
|
||||
toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
toaddr.sin_port = htons(from_port);
|
||||
toaddr.sin_family = AF_INET;
|
||||
|
||||
if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
|
||||
(struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) {
|
||||
DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
|
||||
(int)remotepid, strerror(errno)));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(5,("process_local_message: oplock break reply sent to \
|
||||
pid %d, port %d, for file dev = %x, inode = %.0f, file_id = %lu\n",
|
||||
(int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
|
||||
if (!((break_cmd_type == OPLOCK_BREAK_CMD) ||
|
||||
(break_cmd_type == LEVEL_II_OPLOCK_BREAK_CMD))) {
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Send the message back after OR'ing in the 'REPLY' bit. */
|
||||
SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type | CMD_REPLY);
|
||||
|
||||
memset((char *)&toaddr,'\0',sizeof(toaddr));
|
||||
toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
toaddr.sin_port = htons(from_port);
|
||||
toaddr.sin_family = AF_INET;
|
||||
|
||||
if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
|
||||
(struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) {
|
||||
DEBUG(0,("process_local_message: sendto process %d failed. "
|
||||
"Errno was %s\n", (int)remotepid, strerror(errno)));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(5,("process_local_message: oplock break reply sent to pid %d, "
|
||||
"port %d, for file dev = %x, inode = %.0f, file_id = %lu\n",
|
||||
(int)remotepid, from_port, (unsigned int)dev,
|
||||
(double)inode, file_id));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -1150,7 +1157,7 @@ BOOL attempt_close_oplocked_file(files_struct *fsp)
|
||||
{
|
||||
DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
|
||||
|
||||
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd != -1)) {
|
||||
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fh->fd != -1)) {
|
||||
/* Try and break the oplock. */
|
||||
if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) {
|
||||
if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */
|
||||
@ -1223,6 +1230,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
|
||||
pid_t pid = sys_getpid();
|
||||
int num_share_modes = 0;
|
||||
int i;
|
||||
BOOL dummy;
|
||||
|
||||
/*
|
||||
* If this file is level II oplocked then we need
|
||||
@ -1239,7 +1247,8 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
|
||||
DEBUG(0,("release_level_2_oplocks_on_change: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
|
||||
}
|
||||
|
||||
num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list);
|
||||
num_share_modes = get_share_modes(fsp->dev, fsp->inode, &share_list,
|
||||
&dummy);
|
||||
|
||||
DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
|
||||
num_share_modes ));
|
||||
|
@ -179,10 +179,10 @@ dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (doubl
|
||||
|
||||
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
|
||||
{
|
||||
if (linux_setlease(fsp->fd, F_WRLCK) == -1) {
|
||||
if (linux_setlease(fsp->fh->fd, F_WRLCK) == -1) {
|
||||
DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
|
||||
inode = %.0f. (%s)\n",
|
||||
fsp->fsp_name, fsp->fd,
|
||||
fsp->fsp_name, fsp->fh->fd,
|
||||
(unsigned int)fsp->dev, (double)fsp->inode, strerror(errno)));
|
||||
return False;
|
||||
}
|
||||
@ -204,7 +204,7 @@ static void linux_release_kernel_oplock(files_struct *fsp)
|
||||
* Check and print out the current kernel
|
||||
* oplock state of this file.
|
||||
*/
|
||||
int state = fcntl(fsp->fd, F_GETLEASE, 0);
|
||||
int state = fcntl(fsp->fh->fd, F_GETLEASE, 0);
|
||||
dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \
|
||||
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
|
||||
(double)fsp->inode, fsp->file_id, state );
|
||||
@ -213,7 +213,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
|
||||
/*
|
||||
* Remove the kernel oplock on this file.
|
||||
*/
|
||||
if (linux_setlease(fsp->fd, F_UNLCK) == -1) {
|
||||
if (linux_setlease(fsp->fh->fd, F_UNLCK) == -1) {
|
||||
if (DEBUGLVL(0)) {
|
||||
dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " );
|
||||
dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n",
|
||||
|
@ -4,6 +4,7 @@
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
|
||||
Copyright (C) Paul Ashton 1997-1998.
|
||||
Copyright (C) Jeremy Allison 2005.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -33,11 +34,11 @@
|
||||
extern struct pipe_id_info pipe_names[];
|
||||
|
||||
/****************************************************************************
|
||||
reply to an open and X on a named pipe
|
||||
|
||||
This code is basically stolen from reply_open_and_X with some
|
||||
wrinkles to handle pipes.
|
||||
Reply to an open and X on a named pipe.
|
||||
This code is basically stolen from reply_open_and_X with some
|
||||
wrinkles to handle pipes.
|
||||
****************************************************************************/
|
||||
|
||||
int reply_open_pipe_and_X(connection_struct *conn,
|
||||
char *inbuf,char *outbuf,int length,int bufsize)
|
||||
{
|
||||
@ -45,7 +46,6 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
||||
pstring pipe_name;
|
||||
uint16 vuid = SVAL(inbuf, smb_uid);
|
||||
smb_np_struct *p;
|
||||
int smb_ofun = SVAL(inbuf,smb_vwv8);
|
||||
int size=0,fmode=0,mtime=0,rmode=0;
|
||||
int i;
|
||||
|
||||
@ -55,23 +55,26 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
||||
/* If the name doesn't start \PIPE\ then this is directed */
|
||||
/* at a mailslot or something we really, really don't understand, */
|
||||
/* not just something we really don't understand. */
|
||||
if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 )
|
||||
if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
|
||||
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||
}
|
||||
|
||||
DEBUG(4,("Opening pipe %s.\n", pipe_name));
|
||||
|
||||
/* See if it is one we want to handle. */
|
||||
for( i = 0; pipe_names[i].client_pipe ; i++ )
|
||||
if( strequal(pipe_name,pipe_names[i].client_pipe) )
|
||||
for( i = 0; pipe_names[i].client_pipe ; i++ ) {
|
||||
if( strequal(pipe_name,pipe_names[i].client_pipe)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_names[i].client_pipe == NULL)
|
||||
if (pipe_names[i].client_pipe == NULL) {
|
||||
return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
|
||||
}
|
||||
|
||||
/* Strip \PIPE\ off the name. */
|
||||
pstrcpy(fname, pipe_name + PIPELEN);
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Hack for NT printers... JRA.
|
||||
@ -83,10 +86,11 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
||||
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
|
||||
/* can be opened and add it in after the open. */
|
||||
DEBUG(3,("Known pipe %s opening.\n",fname));
|
||||
smb_ofun |= FILE_CREATE_IF_NOT_EXIST;
|
||||
|
||||
p = open_rpc_pipe_p(fname, conn, vuid);
|
||||
if (!p) return(ERROR_DOS(ERRSRV,ERRnofids));
|
||||
if (!p) {
|
||||
return(ERROR_DOS(ERRSRV,ERRnofids));
|
||||
}
|
||||
|
||||
/* Prepare the reply */
|
||||
set_message(outbuf,15,0,True);
|
||||
@ -111,8 +115,9 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
reply to a write on a pipe
|
||||
Reply to a write on a pipe.
|
||||
****************************************************************************/
|
||||
|
||||
int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
|
||||
{
|
||||
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
|
||||
@ -121,25 +126,27 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
|
||||
int outsize;
|
||||
char *data;
|
||||
|
||||
if (!p)
|
||||
if (!p) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||
}
|
||||
|
||||
data = smb_buf(inbuf) + 3;
|
||||
|
||||
if (numtowrite == 0)
|
||||
if (numtowrite == 0) {
|
||||
nwritten = 0;
|
||||
else
|
||||
} else {
|
||||
nwritten = write_to_pipe(p, data, numtowrite);
|
||||
}
|
||||
|
||||
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
|
||||
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
|
||||
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,1,0,True);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,nwritten);
|
||||
|
||||
DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
|
||||
p->pnum, nwritten));
|
||||
DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
@ -158,24 +165,25 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
int nwritten = -1;
|
||||
int smb_doff = SVAL(inbuf, smb_vwv11);
|
||||
BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) ==
|
||||
(PIPE_START_MESSAGE|PIPE_RAW_MODE));
|
||||
(PIPE_START_MESSAGE|PIPE_RAW_MODE));
|
||||
char *data;
|
||||
|
||||
if (!p)
|
||||
if (!p) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||
}
|
||||
|
||||
data = smb_base(inbuf) + smb_doff;
|
||||
|
||||
if (numtowrite == 0)
|
||||
if (numtowrite == 0) {
|
||||
nwritten = 0;
|
||||
else {
|
||||
} else {
|
||||
if(pipe_start_message_raw) {
|
||||
/*
|
||||
* For the start of a message in named pipe byte mode,
|
||||
* the first two bytes are a length-of-pdu field. Ignore
|
||||
* them (we don't trust the client. JRA.
|
||||
* them (we don't trust the client). JRA.
|
||||
*/
|
||||
if(numtowrite < 2) {
|
||||
if(numtowrite < 2) {
|
||||
DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n",
|
||||
(unsigned int)numtowrite ));
|
||||
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
@ -183,30 +191,30 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
|
||||
data += 2;
|
||||
numtowrite -= 2;
|
||||
}
|
||||
}
|
||||
nwritten = write_to_pipe(p, data, numtowrite);
|
||||
}
|
||||
|
||||
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
|
||||
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
|
||||
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
set_message(outbuf,6,0,True);
|
||||
|
||||
nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
|
||||
SSVAL(outbuf,smb_vwv2,nwritten);
|
||||
|
||||
DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n",
|
||||
p->pnum, nwritten));
|
||||
DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
|
||||
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
reply to a read and X
|
||||
|
||||
This code is basically stolen from reply_read_and_X with some
|
||||
wrinkles to handle pipes.
|
||||
Reply to a read and X.
|
||||
This code is basically stolen from reply_read_and_X with some
|
||||
wrinkles to handle pipes.
|
||||
****************************************************************************/
|
||||
|
||||
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
{
|
||||
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
|
||||
@ -223,16 +231,18 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
|
||||
#endif
|
||||
|
||||
if (!p)
|
||||
if (!p) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||
}
|
||||
|
||||
set_message(outbuf,12,0,True);
|
||||
data = smb_buf(outbuf);
|
||||
|
||||
nread = read_from_pipe(p, data, smb_maxcnt, &unused);
|
||||
|
||||
if (nread < 0)
|
||||
if (nread < 0) {
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
SSVAL(outbuf,smb_vwv5,nread);
|
||||
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
|
||||
@ -247,20 +257,23 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
reply to a close
|
||||
Reply to a close.
|
||||
****************************************************************************/
|
||||
|
||||
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
|
||||
{
|
||||
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
|
||||
int outsize = set_message(outbuf,0,0,True);
|
||||
|
||||
if (!p)
|
||||
if (!p) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||
}
|
||||
|
||||
DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
|
||||
|
||||
if (!close_rpc_pipe_hnd(p))
|
||||
if (!close_rpc_pipe_hnd(p)) {
|
||||
return ERROR_DOS(ERRDOS,ERRbadfid);
|
||||
}
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
@ -229,8 +229,8 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_
|
||||
|
||||
if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) {
|
||||
/* Instead just remove the attribute if it exists. */
|
||||
if (fsp->fd != -1)
|
||||
SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
||||
if (fsp->fh->fd != -1)
|
||||
SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
||||
else
|
||||
SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
||||
return;
|
||||
@ -238,8 +238,8 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_
|
||||
|
||||
pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size);
|
||||
|
||||
if (fsp->fd != -1)
|
||||
ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
if (fsp->fh->fd != -1)
|
||||
ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
pai_buf, store_size, 0);
|
||||
else
|
||||
ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
@ -445,8 +445,8 @@ static struct pai_val *load_inherited_info(files_struct *fsp)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
if (fsp->fd != -1)
|
||||
ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
if (fsp->fh->fd != -1)
|
||||
ret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
pai_buf, pai_buf_size);
|
||||
else
|
||||
ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||
@ -2422,7 +2422,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
|
||||
* Finally apply it to the file or directory.
|
||||
*/
|
||||
|
||||
if(default_ace || fsp->is_directory || fsp->fd == -1) {
|
||||
if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
|
||||
if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
|
||||
/*
|
||||
* Some systems allow all the above calls and only fail with no ACL support
|
||||
@ -2438,7 +2438,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, the_acl) == -1) {
|
||||
if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl) == -1) {
|
||||
/*
|
||||
* Some systems allow all the above calls and only fail with no ACL support
|
||||
* when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
|
||||
@ -2668,7 +2668,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
|
||||
|
||||
DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
|
||||
|
||||
if(fsp->is_directory || fsp->fd == -1) {
|
||||
if(fsp->is_directory || fsp->fh->fd == -1) {
|
||||
|
||||
/* Get the stat struct for the owner info. */
|
||||
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
|
||||
@ -2692,13 +2692,13 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
|
||||
} else {
|
||||
|
||||
/* Get the stat struct for the owner info. */
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Get the ACL from the fd.
|
||||
*/
|
||||
posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
|
||||
posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
|
||||
}
|
||||
|
||||
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
|
||||
@ -2981,7 +2981,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
|
||||
|
||||
become_root();
|
||||
/* Keep the current file gid the same. */
|
||||
ret = SMB_VFS_FCHOWN(fsp, fsp->fd, uid, (gid_t)-1);
|
||||
ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, uid, (gid_t)-1);
|
||||
unbecome_root();
|
||||
|
||||
close_file_fchmod(fsp);
|
||||
@ -3022,11 +3022,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
|
||||
* Get the current state of the file.
|
||||
*/
|
||||
|
||||
if(fsp->is_directory || fsp->fd == -1) {
|
||||
if(fsp->is_directory || fsp->fh->fd == -1) {
|
||||
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
|
||||
return False;
|
||||
} else {
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0)
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0)
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -3081,10 +3081,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
|
||||
|
||||
int ret;
|
||||
|
||||
if(fsp->fd == -1)
|
||||
if(fsp->fh->fd == -1)
|
||||
ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
|
||||
else
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf);
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);
|
||||
|
||||
if(ret != 0)
|
||||
return False;
|
||||
@ -3683,8 +3683,8 @@ static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const c
|
||||
}
|
||||
|
||||
/* Get the current file ACL. */
|
||||
if (fsp && fsp->fd != -1) {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
|
||||
if (fsp && fsp->fh->fd != -1) {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
|
||||
} else {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
|
||||
}
|
||||
@ -3767,9 +3767,9 @@ BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *
|
||||
return False;
|
||||
}
|
||||
|
||||
if (fsp && fsp->fd != -1) {
|
||||
if (fsp && fsp->fh->fd != -1) {
|
||||
/* The preferred way - use an open fd. */
|
||||
if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, file_acl) == -1) {
|
||||
if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, file_acl) == -1) {
|
||||
DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
|
||||
fname, strerror(errno) ));
|
||||
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
|
||||
|
@ -1275,20 +1275,24 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
{
|
||||
pstring fname;
|
||||
int outsize = 0;
|
||||
int fmode=0;
|
||||
int share_mode;
|
||||
uint32 fattr=0;
|
||||
SMB_OFF_T size = 0;
|
||||
time_t mtime=0;
|
||||
int rmode=0;
|
||||
int info;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
BOOL bad_path = False;
|
||||
files_struct *fsp;
|
||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||
uint16 dos_attr = SVAL(inbuf,smb_vwv1);
|
||||
int deny_mode;
|
||||
uint32 dos_attr = SVAL(inbuf,smb_vwv1);
|
||||
uint32 access_mask;
|
||||
uint32 share_mode;
|
||||
uint32 create_disposition;
|
||||
uint32 create_options = 0;
|
||||
NTSTATUS status;
|
||||
START_PROFILE(SMBopen);
|
||||
|
||||
share_mode = SVAL(inbuf,smb_vwv0);
|
||||
deny_mode = SVAL(inbuf,smb_vwv0);
|
||||
|
||||
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -1304,8 +1308,20 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
}
|
||||
|
||||
fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
(uint32)dos_attr, oplock_request,&rmode,NULL);
|
||||
if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
|
||||
&access_mask, &share_mode, &create_disposition, &create_options)) {
|
||||
END_PROFILE(SMBopen);
|
||||
return ERROR_DOS(ERRDOS, ERRbadaccess);
|
||||
}
|
||||
|
||||
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||
access_mask,
|
||||
share_mode,
|
||||
create_disposition,
|
||||
create_options,
|
||||
dos_attr,
|
||||
oplock_request,
|
||||
&info);
|
||||
|
||||
if (!fsp) {
|
||||
END_PROFILE(SMBopen);
|
||||
@ -1317,10 +1333,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
}
|
||||
|
||||
size = sbuf.st_size;
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
fattr = dos_mode(conn,fname,&sbuf);
|
||||
mtime = sbuf.st_mtime;
|
||||
|
||||
if (fmode & aDIR) {
|
||||
if (fattr & aDIR) {
|
||||
DEBUG(3,("attempt to open a directory %s\n",fname));
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBopen);
|
||||
@ -1329,19 +1345,22 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
|
||||
outsize = set_message(outbuf,7,0,True);
|
||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
||||
SSVAL(outbuf,smb_vwv1,fmode);
|
||||
if(lp_dos_filetime_resolution(SNUM(conn)) )
|
||||
SSVAL(outbuf,smb_vwv1,fattr);
|
||||
if(lp_dos_filetime_resolution(SNUM(conn)) ) {
|
||||
put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
|
||||
else
|
||||
} else {
|
||||
put_dos_date3(outbuf,smb_vwv2,mtime);
|
||||
}
|
||||
SIVAL(outbuf,smb_vwv4,(uint32)size);
|
||||
SSVAL(outbuf,smb_vwv6,rmode);
|
||||
SSVAL(outbuf,smb_vwv6,FILE_WAS_OPENED);
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
END_PROFILE(SMBopen);
|
||||
return(outsize);
|
||||
}
|
||||
@ -1353,21 +1372,22 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
|
||||
{
|
||||
pstring fname;
|
||||
int smb_mode = SVAL(inbuf,smb_vwv3);
|
||||
int smb_attr = SVAL(inbuf,smb_vwv5);
|
||||
uint16 open_flags = SVAL(inbuf,smb_vwv2);
|
||||
int deny_mode = SVAL(inbuf,smb_vwv3);
|
||||
uint32 smb_attr = SVAL(inbuf,smb_vwv5);
|
||||
/* Breakout the oplock request bits so we can set the
|
||||
reply bits separately. */
|
||||
BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
|
||||
BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||
BOOL oplock_request = ex_oplock_request | core_oplock_request;
|
||||
#if 0
|
||||
int open_flags = SVAL(inbuf,smb_vwv2);
|
||||
int smb_sattr = SVAL(inbuf,smb_vwv4);
|
||||
uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
|
||||
#endif
|
||||
int smb_ofun = SVAL(inbuf,smb_vwv8);
|
||||
SMB_OFF_T size=0;
|
||||
int fmode=0,mtime=0,rmode=0;
|
||||
uint32 fattr=0;
|
||||
int mtime=0;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
int smb_action = 0;
|
||||
BOOL bad_path = False;
|
||||
@ -1375,6 +1395,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
NTSTATUS status;
|
||||
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
|
||||
ssize_t retval = -1;
|
||||
uint32 access_mask;
|
||||
uint32 share_mode;
|
||||
uint32 create_disposition;
|
||||
uint32 create_options = 0;
|
||||
|
||||
START_PROFILE(SMBopenX);
|
||||
|
||||
@ -1404,18 +1428,23 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
}
|
||||
|
||||
/* Strange open mode mapping. */
|
||||
if (smb_ofun == 0) {
|
||||
if (GET_OPEN_MODE(smb_mode) == DOS_OPEN_EXEC) {
|
||||
smb_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
|
||||
} else {
|
||||
END_PROFILE(SMBopenX);
|
||||
return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
|
||||
}
|
||||
if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
|
||||
&access_mask,
|
||||
&share_mode,
|
||||
&create_disposition,
|
||||
&create_options)) {
|
||||
END_PROFILE(SMBopenX);
|
||||
return ERROR_DOS(ERRDOS, ERRbadaccess);
|
||||
}
|
||||
|
||||
fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
|
||||
oplock_request, &rmode,&smb_action);
|
||||
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||
access_mask,
|
||||
share_mode,
|
||||
create_disposition,
|
||||
create_options,
|
||||
smb_attr,
|
||||
oplock_request,
|
||||
&smb_action);
|
||||
|
||||
if (!fsp) {
|
||||
END_PROFILE(SMBopenX);
|
||||
@ -1446,9 +1475,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
size = get_allocation_size(conn,fsp,&sbuf);
|
||||
}
|
||||
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
fattr = dos_mode(conn,fname,&sbuf);
|
||||
mtime = sbuf.st_mtime;
|
||||
if (fmode & aDIR) {
|
||||
if (fattr & aDIR) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBopenX);
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
@ -1459,34 +1488,47 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
correct bit for extended oplock reply.
|
||||
*/
|
||||
|
||||
if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
smb_action |= EXTENDED_OPLOCK_GRANTED;
|
||||
}
|
||||
|
||||
if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
smb_action |= EXTENDED_OPLOCK_GRANTED;
|
||||
}
|
||||
|
||||
/* If the caller set the core oplock request bit
|
||||
and we granted one (by whatever means) - set the
|
||||
correct bit for core oplock reply.
|
||||
*/
|
||||
|
||||
if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
set_message(outbuf,15,0,True);
|
||||
if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
|
||||
set_message(outbuf,19,0,True);
|
||||
} else {
|
||||
set_message(outbuf,15,0,True);
|
||||
}
|
||||
SSVAL(outbuf,smb_vwv2,fsp->fnum);
|
||||
SSVAL(outbuf,smb_vwv3,fmode);
|
||||
if(lp_dos_filetime_resolution(SNUM(conn)) )
|
||||
SSVAL(outbuf,smb_vwv3,fattr);
|
||||
if(lp_dos_filetime_resolution(SNUM(conn)) ) {
|
||||
put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
|
||||
else
|
||||
} else {
|
||||
put_dos_date3(outbuf,smb_vwv4,mtime);
|
||||
}
|
||||
SIVAL(outbuf,smb_vwv6,(uint32)size);
|
||||
SSVAL(outbuf,smb_vwv8,rmode);
|
||||
SSVAL(outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
|
||||
SSVAL(outbuf,smb_vwv11,smb_action);
|
||||
|
||||
if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
|
||||
SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
|
||||
}
|
||||
|
||||
END_PROFILE(SMBopenX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
}
|
||||
@ -1528,18 +1570,21 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
pstring fname;
|
||||
int com;
|
||||
int outsize = 0;
|
||||
int createmode;
|
||||
int ofun = 0;
|
||||
uint32 fattr = SVAL(inbuf,smb_vwv0);
|
||||
BOOL bad_path = False;
|
||||
files_struct *fsp;
|
||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
NTSTATUS status;
|
||||
uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
|
||||
uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
|
||||
uint32 create_disposition;
|
||||
uint32 create_options = 0;
|
||||
|
||||
START_PROFILE(SMBcreate);
|
||||
|
||||
com = SVAL(inbuf,smb_com);
|
||||
|
||||
createmode = SVAL(inbuf,smb_vwv0);
|
||||
srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
END_PROFILE(SMBcreate);
|
||||
@ -1554,20 +1599,27 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (createmode & aVOLID)
|
||||
if (fattr & aVOLID) {
|
||||
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
|
||||
|
||||
if(com == SMBmknew) {
|
||||
/* We should fail if file exists. */
|
||||
ofun = FILE_CREATE_IF_NOT_EXIST;
|
||||
} else {
|
||||
/* SMBcreate - Create if file doesn't exist, truncate if it does. */
|
||||
ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
|
||||
}
|
||||
|
||||
/* Open file in dos compatibility share mode. */
|
||||
fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
||||
ofun, (uint32)createmode, oplock_request, NULL, NULL);
|
||||
if(com == SMBmknew) {
|
||||
/* We should fail if file exists. */
|
||||
create_disposition = FILE_CREATE;
|
||||
} else {
|
||||
/* Create if file doesn't exist, truncate if it does. */
|
||||
create_disposition = FILE_OPEN_IF;
|
||||
}
|
||||
|
||||
/* Open file using ntcreate. */
|
||||
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||
access_mask,
|
||||
share_mode,
|
||||
create_disposition,
|
||||
create_options,
|
||||
fattr,
|
||||
oplock_request,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
END_PROFILE(SMBcreate);
|
||||
@ -1581,14 +1633,16 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
outsize = set_message(outbuf,1,0,True);
|
||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
DEBUG( 2, ( "new file %s\n", fname ) );
|
||||
DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
|
||||
DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
|
||||
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) );
|
||||
|
||||
END_PROFILE(SMBcreate);
|
||||
return(outsize);
|
||||
@ -1602,7 +1656,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
{
|
||||
pstring fname;
|
||||
int outsize = 0;
|
||||
int createattr;
|
||||
uint32 fattr = SVAL(inbuf,smb_vwv0);
|
||||
BOOL bad_path = False;
|
||||
files_struct *fsp;
|
||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||
@ -1614,7 +1668,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
|
||||
START_PROFILE(SMBctemp);
|
||||
|
||||
createattr = SVAL(inbuf,smb_vwv0);
|
||||
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
END_PROFILE(SMBctemp);
|
||||
@ -1642,12 +1695,15 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
|
||||
SMB_VFS_STAT(conn,fname,&sbuf);
|
||||
|
||||
/* Open file in dos compatibility share mode. */
|
||||
/* We should fail if file does not exist. */
|
||||
fsp = open_file_shared(conn,fname,&sbuf,
|
||||
SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
||||
FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
|
||||
(uint32)createattr, oplock_request, NULL, NULL);
|
||||
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
fattr,
|
||||
oplock_request,
|
||||
NULL);
|
||||
|
||||
/* close fd from smb_mkstemp() */
|
||||
close(tmpfd);
|
||||
@ -1666,10 +1722,11 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
|
||||
/* the returned filename is relative to the directory */
|
||||
s = strrchr_m(fname, '/');
|
||||
if (!s)
|
||||
if (!s) {
|
||||
s = fname;
|
||||
else
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
#if 0
|
||||
@ -1681,15 +1738,17 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
p += namelen;
|
||||
outsize = set_message_end(outbuf, p);
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
DEBUG( 2, ( "created temp file %s\n", fname ) );
|
||||
DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
|
||||
fname, fsp->fd, sbuf.st_mode ) );
|
||||
DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
|
||||
DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
|
||||
(unsigned int)sbuf.st_mode ) );
|
||||
|
||||
END_PROFILE(SMBctemp);
|
||||
return(outsize);
|
||||
@ -1701,26 +1760,33 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
|
||||
static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
int smb_action;
|
||||
int access_mode;
|
||||
files_struct *fsp;
|
||||
uint16 fmode;
|
||||
uint32 fmode;
|
||||
|
||||
if (!CAN_WRITE(conn))
|
||||
if (!CAN_WRITE(conn)) {
|
||||
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
fmode = dos_mode(conn,fname,pst);
|
||||
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
|
||||
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
|
||||
return NT_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
if (S_ISDIR(pst->st_mode))
|
||||
if (S_ISDIR(pst->st_mode)) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* We need a better way to return NT status codes from open... */
|
||||
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
||||
|
||||
fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
|
||||
fsp = open_file_ntcreate(conn, fname, pst,
|
||||
DELETE_ACCESS,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
NTSTATUS ret;
|
||||
@ -1742,43 +1808,46 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
|
||||
NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open)
|
||||
{
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
uint32 fmode;
|
||||
int smb_action;
|
||||
int access_mode;
|
||||
uint32 fattr;
|
||||
files_struct *fsp;
|
||||
|
||||
DEBUG(10,("can_delete: %s, dirtype = %d\n",
|
||||
fname, dirtype ));
|
||||
DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype ));
|
||||
|
||||
if (!CAN_WRITE(conn))
|
||||
if (!CAN_WRITE(conn)) {
|
||||
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
|
||||
if(errno == ENOENT) {
|
||||
if (bad_path)
|
||||
if (bad_path) {
|
||||
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
else
|
||||
} else {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
fattr = dos_mode(conn,fname,&sbuf);
|
||||
|
||||
/* Can't delete a directory. */
|
||||
if (fmode & aDIR)
|
||||
if (fattr & aDIR) {
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
#if 0 /* JRATEST */
|
||||
else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
#endif /* JRATEST */
|
||||
|
||||
if (!lp_delete_readonly(SNUM(conn))) {
|
||||
if (fmode & aRONLY)
|
||||
if (fattr & aRONLY) {
|
||||
return NT_STATUS_CANNOT_DELETE;
|
||||
}
|
||||
}
|
||||
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
|
||||
if ((fattr & ~dirtype) & (aHIDDEN | aSYSTEM)) {
|
||||
return NT_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
if (check_is_at_open) {
|
||||
if (!can_delete_file_in_directory(conn, fname)) {
|
||||
@ -1791,8 +1860,14 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
|
||||
/* We need a better way to return NT status codes from open... */
|
||||
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
||||
|
||||
fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
|
||||
fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||
DELETE_ACCESS,
|
||||
FILE_SHARE_NONE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!fsp) {
|
||||
NTSTATUS ret;
|
||||
@ -2058,7 +2133,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
|
||||
header.length = 4;
|
||||
header.free = NULL;
|
||||
|
||||
if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
|
||||
if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
|
||||
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
|
||||
if (errno == ENOSYS) {
|
||||
goto normal_readbraw;
|
||||
@ -2205,7 +2280,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
|
||||
SMB_STRUCT_STAT st;
|
||||
SMB_OFF_T size = 0;
|
||||
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) {
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
|
||||
size = st.st_size;
|
||||
}
|
||||
|
||||
@ -2251,7 +2326,9 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
|
||||
START_PROFILE(SMBlockread);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_READ(fsp);
|
||||
if (!CHECK_READ(fsp,inbuf)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
release_level_2_oplocks_on_change(fsp);
|
||||
|
||||
@ -2345,7 +2422,9 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
START_PROFILE(SMBread);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_READ(fsp);
|
||||
if (!CHECK_READ(fsp,inbuf)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
numtoread = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
@ -2413,7 +2492,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
DATA_BLOB header;
|
||||
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1)
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
|
||||
if (startpos > sbuf.st_size)
|
||||
@ -2442,7 +2521,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
|
||||
header.length = data - outbuf;
|
||||
header.free = NULL;
|
||||
|
||||
if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
|
||||
if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
|
||||
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
|
||||
if (errno == ENOSYS) {
|
||||
goto normal_read;
|
||||
@ -2530,7 +2609,9 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
}
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_READ(fsp);
|
||||
if (!CHECK_READ(fsp,inbuf)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
set_message(outbuf,12,0,True);
|
||||
|
||||
@ -2610,7 +2691,9 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
}
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
tcount = IVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
@ -2744,7 +2827,9 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
|
||||
START_PROFILE(SMBwriteunlock);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
@ -2758,10 +2843,11 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
|
||||
/* The special X/Open SMB protocol handling of
|
||||
zero length writes is *NOT* done for
|
||||
this call */
|
||||
if(numtowrite == 0)
|
||||
if(numtowrite == 0) {
|
||||
nwritten = 0;
|
||||
else
|
||||
} else {
|
||||
nwritten = write_file(fsp,data,startpos,numtowrite);
|
||||
}
|
||||
|
||||
if (lp_syncalways(SNUM(conn)))
|
||||
sync_file(conn,fsp);
|
||||
@ -2815,7 +2901,9 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
|
||||
}
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
@ -2896,7 +2984,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
|
||||
}
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
set_message(outbuf,6,0,True);
|
||||
|
||||
@ -3010,7 +3100,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
break;
|
||||
case 1:
|
||||
umode = SEEK_CUR;
|
||||
res = fsp->pos + startpos;
|
||||
res = fsp->fh->pos + startpos;
|
||||
break;
|
||||
case 2:
|
||||
umode = SEEK_END;
|
||||
@ -3022,19 +3112,19 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
}
|
||||
|
||||
if (umode == SEEK_END) {
|
||||
if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
|
||||
if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) {
|
||||
if(errno == EINVAL) {
|
||||
SMB_OFF_T current_pos = startpos;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
|
||||
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
|
||||
END_PROFILE(SMBlseek);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
current_pos += sbuf.st_size;
|
||||
if(current_pos < 0)
|
||||
res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
|
||||
res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3044,7 +3134,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
}
|
||||
}
|
||||
|
||||
fsp->pos = res;
|
||||
fsp->fh->pos = res;
|
||||
|
||||
outsize = set_message(outbuf,2,0,True);
|
||||
SIVAL(outbuf,smb_vwv0,res);
|
||||
@ -3150,7 +3240,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
pstrcpy( file_name, fsp->fsp_name);
|
||||
|
||||
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
|
||||
fsp->fd, fsp->fnum,
|
||||
fsp->fh->fd, fsp->fnum,
|
||||
conn->num_files_open));
|
||||
|
||||
/*
|
||||
@ -3201,7 +3291,9 @@ int reply_writeclose(connection_struct *conn,
|
||||
START_PROFILE(SMBwriteclose);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
@ -3276,7 +3368,7 @@ int reply_lock(connection_struct *conn,
|
||||
offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
|
||||
|
||||
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
|
||||
fsp->fd, fsp->fnum, (double)offset, (double)count));
|
||||
fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
|
||||
|
||||
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
|
||||
if (NT_STATUS_V(status)) {
|
||||
@ -3327,7 +3419,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
}
|
||||
|
||||
DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
|
||||
fsp->fd, fsp->fnum, (double)offset, (double)count ) );
|
||||
fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
|
||||
|
||||
END_PROFILE(SMBunlock);
|
||||
return(outsize);
|
||||
@ -3437,7 +3529,7 @@ int reply_printopen(connection_struct *conn,
|
||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
||||
|
||||
DEBUG(3,("openprint fd=%d fnum=%d\n",
|
||||
fsp->fd, fsp->fnum));
|
||||
fsp->fh->fd, fsp->fnum));
|
||||
|
||||
END_PROFILE(SMBsplopen);
|
||||
return(outsize);
|
||||
@ -3463,7 +3555,7 @@ int reply_printclose(connection_struct *conn,
|
||||
}
|
||||
|
||||
DEBUG(3,("printclose fd=%d fnum=%d\n",
|
||||
fsp->fd,fsp->fnum));
|
||||
fsp->fh->fd,fsp->fnum));
|
||||
|
||||
close_err = close_file(fsp,True);
|
||||
|
||||
@ -3567,7 +3659,9 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
|
||||
}
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
numtowrite = SVAL(smb_buf(inbuf),1);
|
||||
data = smb_buf(inbuf) + 3;
|
||||
@ -4484,45 +4578,66 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
||||
int count,BOOL target_is_directory, int *err_ret)
|
||||
{
|
||||
int Access,action;
|
||||
SMB_STRUCT_STAT src_sbuf, sbuf2;
|
||||
SMB_OFF_T ret=-1;
|
||||
files_struct *fsp1,*fsp2;
|
||||
pstring dest;
|
||||
uint32 dosattrs;
|
||||
uint32 new_create_disposition;
|
||||
|
||||
*err_ret = 0;
|
||||
|
||||
pstrcpy(dest,dest1);
|
||||
if (target_is_directory) {
|
||||
char *p = strrchr_m(src,'/');
|
||||
if (p)
|
||||
if (p) {
|
||||
p++;
|
||||
else
|
||||
} else {
|
||||
p = src;
|
||||
}
|
||||
pstrcat(dest,"/");
|
||||
pstrcat(dest,p);
|
||||
}
|
||||
|
||||
if (!vfs_file_exist(conn,src,&src_sbuf))
|
||||
if (!vfs_file_exist(conn,src,&src_sbuf)) {
|
||||
return(False);
|
||||
}
|
||||
|
||||
fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,INTERNAL_OPEN_ONLY,
|
||||
&Access,&action);
|
||||
if (!target_is_directory && count) {
|
||||
new_create_disposition = FILE_OPEN;
|
||||
} else {
|
||||
if (!map_open_params_to_ntcreate(dest1,0,ofun,
|
||||
NULL, NULL, &new_create_disposition, NULL)) {
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fsp1)
|
||||
fsp1 = open_file_ntcreate(conn,src,&src_sbuf,
|
||||
FILE_GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (!fsp1) {
|
||||
return(False);
|
||||
|
||||
if (!target_is_directory && count)
|
||||
ofun = FILE_EXISTS_OPEN;
|
||||
}
|
||||
|
||||
dosattrs = dos_mode(conn, src, &src_sbuf);
|
||||
if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
|
||||
if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
|
||||
ZERO_STRUCTP(&sbuf2);
|
||||
}
|
||||
|
||||
fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
|
||||
ofun,dosattrs,INTERNAL_OPEN_ONLY,&Access,&action);
|
||||
fsp2 = open_file_ntcreate(conn,dest,&sbuf2,
|
||||
FILE_GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
new_create_disposition,
|
||||
0,
|
||||
dosattrs,
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (!fsp2) {
|
||||
close_file(fsp1,False);
|
||||
@ -4530,7 +4645,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
||||
}
|
||||
|
||||
if ((ofun&3) == 1) {
|
||||
if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
|
||||
if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) {
|
||||
DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
|
||||
/*
|
||||
* Stop the copy from occurring.
|
||||
@ -4540,8 +4655,9 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
||||
}
|
||||
}
|
||||
|
||||
if (src_sbuf.st_size)
|
||||
if (src_sbuf.st_size) {
|
||||
ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
|
||||
}
|
||||
|
||||
close_file(fsp1,False);
|
||||
|
||||
@ -4955,7 +5071,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
|
||||
/* we don't support these - and CANCEL_LOCK makes w2k
|
||||
and XP reboot so I don't really want to be
|
||||
compatible! (tridge) */
|
||||
return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
||||
return ERROR_DOS(ERRDOS, ERRnoatomiclocks);
|
||||
}
|
||||
|
||||
if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
|
||||
@ -5158,7 +5274,9 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
|
||||
outsize = set_message(outbuf,8,0,True);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_READ(fsp);
|
||||
if (!CHECK_READ(fsp,inbuf)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
|
||||
maxcount = SVAL(inbuf,smb_vwv3);
|
||||
@ -5286,7 +5404,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
START_PROFILE(SMBwriteBmpx);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
if (HAS_CACHED_ERROR(fsp)) {
|
||||
return(CACHED_ERROR(fsp));
|
||||
}
|
||||
@ -5390,7 +5510,9 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
|
||||
START_PROFILE(SMBwriteBs);
|
||||
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_WRITE(fsp);
|
||||
if (!CHECK_WRITE(fsp)) {
|
||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||
}
|
||||
|
||||
tcount = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
|
@ -3,6 +3,7 @@
|
||||
SMB transaction2 handling
|
||||
Copyright (C) Jeremy Allison 1994-2003
|
||||
Copyright (C) Stefan (metze) Metzmacher 2003
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
Extensively modified by Andrew Tridgell, 1995
|
||||
|
||||
@ -119,8 +120,8 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str
|
||||
return False;
|
||||
}
|
||||
|
||||
if (fsp && fsp->fd != -1) {
|
||||
sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
|
||||
if (fsp && fsp->fh->fd != -1) {
|
||||
sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size);
|
||||
} else {
|
||||
sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
|
||||
}
|
||||
@ -171,8 +172,8 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str
|
||||
|
||||
for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6;
|
||||
ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
|
||||
if (fsp && fsp->fd != -1) {
|
||||
sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
|
||||
if (fsp && fsp->fh->fd != -1) {
|
||||
sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size);
|
||||
} else {
|
||||
sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
|
||||
}
|
||||
@ -337,10 +338,10 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s
|
||||
|
||||
if (ea_list->ea.value.length == 0) {
|
||||
/* Remove the attribute. */
|
||||
if (fsp && (fsp->fd != -1)) {
|
||||
if (fsp && (fsp->fh->fd != -1)) {
|
||||
DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
|
||||
unix_ea_name, fsp->fsp_name));
|
||||
ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
|
||||
ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, unix_ea_name);
|
||||
} else {
|
||||
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
|
||||
unix_ea_name, fname));
|
||||
@ -355,10 +356,10 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (fsp && (fsp->fd != -1)) {
|
||||
if (fsp && (fsp->fh->fd != -1)) {
|
||||
DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
|
||||
unix_ea_name, fsp->fsp_name));
|
||||
ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name,
|
||||
ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, unix_ea_name,
|
||||
ea_list->ea.value.data, ea_list->ea.value.length, 0);
|
||||
} else {
|
||||
DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
|
||||
@ -717,20 +718,20 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
{
|
||||
char *params = *pparams;
|
||||
char *pdata = *ppdata;
|
||||
int16 open_mode;
|
||||
int16 open_attr;
|
||||
int deny_mode;
|
||||
int32 open_attr;
|
||||
BOOL oplock_request;
|
||||
#if 0
|
||||
BOOL return_additional_info;
|
||||
int16 open_sattr;
|
||||
time_t open_time;
|
||||
#endif
|
||||
int16 open_ofun;
|
||||
int open_ofun;
|
||||
int32 open_size;
|
||||
char *pname;
|
||||
pstring fname;
|
||||
SMB_OFF_T size=0;
|
||||
int fmode=0,mtime=0,rmode;
|
||||
int fattr=0,mtime=0;
|
||||
SMB_INO_T inode = 0;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
int smb_action = 0;
|
||||
@ -740,6 +741,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
struct ea_list *ea_list = NULL;
|
||||
uint16 flags = 0;
|
||||
NTSTATUS status;
|
||||
uint32 access_mask;
|
||||
uint32 share_mode;
|
||||
uint32 create_disposition;
|
||||
uint32 create_options = 0;
|
||||
|
||||
/*
|
||||
* Ensure we have enough parameters to perform the operation.
|
||||
@ -750,7 +755,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
}
|
||||
|
||||
flags = SVAL(params, 0);
|
||||
open_mode = SVAL(params, 2);
|
||||
deny_mode = SVAL(params, 2);
|
||||
open_attr = SVAL(params,6);
|
||||
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
|
||||
if (oplock_request) {
|
||||
@ -766,16 +771,18 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
open_size = IVAL(params,14);
|
||||
pname = ¶ms[28];
|
||||
|
||||
if (IS_IPC(conn))
|
||||
if (IS_IPC(conn)) {
|
||||
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||
}
|
||||
|
||||
srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ERROR_NT(status);
|
||||
}
|
||||
|
||||
DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
|
||||
fname,open_mode, open_attr, open_ofun, open_size));
|
||||
DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
|
||||
fname, (unsigned int)deny_mode, (unsigned int)open_attr,
|
||||
(unsigned int)open_ofun, open_size));
|
||||
|
||||
/* XXXX we need to handle passed times, sattr and flags */
|
||||
|
||||
@ -788,11 +795,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
/* Strange open mode mapping. */
|
||||
if (open_ofun == 0) {
|
||||
if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) {
|
||||
open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
|
||||
}
|
||||
if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
|
||||
&access_mask,
|
||||
&share_mode,
|
||||
&create_disposition,
|
||||
&create_options)) {
|
||||
return ERROR_DOS(ERRDOS, ERRbadaccess);
|
||||
}
|
||||
|
||||
/* Any data in this call is an EA list. */
|
||||
@ -822,8 +830,14 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
}
|
||||
}
|
||||
|
||||
fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
|
||||
oplock_request, &rmode,&smb_action);
|
||||
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||
access_mask,
|
||||
share_mode,
|
||||
create_disposition,
|
||||
create_options,
|
||||
open_attr,
|
||||
oplock_request,
|
||||
&smb_action);
|
||||
|
||||
if (!fsp) {
|
||||
talloc_destroy(ctx);
|
||||
@ -835,10 +849,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
}
|
||||
|
||||
size = get_file_size(sbuf);
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
fattr = dos_mode(conn,fname,&sbuf);
|
||||
mtime = sbuf.st_mtime;
|
||||
inode = sbuf.st_ino;
|
||||
if (fmode & aDIR) {
|
||||
if (fattr & aDIR) {
|
||||
talloc_destroy(ctx);
|
||||
close_file(fsp,False);
|
||||
return(ERROR_DOS(ERRDOS,ERRnoaccess));
|
||||
@ -861,10 +875,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
*pparams = params;
|
||||
|
||||
SSVAL(params,0,fsp->fnum);
|
||||
SSVAL(params,2,fmode);
|
||||
SSVAL(params,2,open_attr);
|
||||
put_dos_date2(params,4, mtime);
|
||||
SIVAL(params,8, (uint32)size);
|
||||
SSVAL(params,12,rmode);
|
||||
SSVAL(params,12,open_ofun);
|
||||
SSVAL(params,16,0); /* Padding. */
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
@ -2332,7 +2346,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
|
||||
|
||||
fsp.conn = conn;
|
||||
fsp.fnum = -1;
|
||||
fsp.fd = -1;
|
||||
fsp.fh->fd = -1;
|
||||
|
||||
/* access check */
|
||||
if (current_user.uid != 0) {
|
||||
@ -2709,6 +2723,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
char *pdata = *ppdata;
|
||||
uint16 info_level;
|
||||
int mode=0;
|
||||
int nlink;
|
||||
SMB_OFF_T file_size=0;
|
||||
SMB_BIG_UINT allocation_size=0;
|
||||
unsigned int data_size = 0;
|
||||
@ -2726,7 +2741,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
files_struct *fsp = NULL;
|
||||
TALLOC_CTX *ea_ctx = NULL;
|
||||
struct ea_list *ea_list = NULL;
|
||||
uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
|
||||
uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
|
||||
|
||||
if (!params)
|
||||
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
|
||||
@ -2751,7 +2766,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
/* We know this name is ok, it's already passed the checks. */
|
||||
|
||||
} else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
|
||||
} else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
|
||||
/*
|
||||
* This is actually a QFILEINFO on a directory
|
||||
* handle (returned from an NT SMB). NT5.0 seems
|
||||
@ -2771,7 +2786,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
|
||||
delete_pending =
|
||||
get_delete_on_close_flag(sbuf.st_dev,
|
||||
sbuf.st_ino);
|
||||
} else {
|
||||
/*
|
||||
* Original code - this is an open file.
|
||||
@ -2779,13 +2796,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
CHECK_FSP(fsp,conn);
|
||||
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
|
||||
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
|
||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||
}
|
||||
pos = fsp->position_information;
|
||||
delete_pending = fsp->delete_on_close;
|
||||
desired_access = fsp->desired_access;
|
||||
pos = fsp->fh->position_information;
|
||||
delete_pending =
|
||||
get_delete_on_close_flag(sbuf.st_dev,
|
||||
sbuf.st_ino);
|
||||
access_mask = fsp->access_mask;
|
||||
}
|
||||
} else {
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
@ -2825,6 +2844,23 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
delete_pending = get_delete_on_close_flag(sbuf.st_dev,
|
||||
sbuf.st_ino);
|
||||
if (delete_pending) {
|
||||
return ERROR_NT(NT_STATUS_DELETE_PENDING);
|
||||
}
|
||||
}
|
||||
|
||||
nlink = sbuf.st_nlink;
|
||||
|
||||
if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
|
||||
/* NTFS does not seem to count ".." */
|
||||
nlink -= 1;
|
||||
}
|
||||
|
||||
if ((nlink > 0) && delete_pending) {
|
||||
nlink -= 1;
|
||||
}
|
||||
|
||||
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
|
||||
@ -3054,11 +3090,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
data_size = 24;
|
||||
SOFF_T(pdata,0,allocation_size);
|
||||
SOFF_T(pdata,8,file_size);
|
||||
if (delete_pending & sbuf.st_nlink)
|
||||
SIVAL(pdata,16,sbuf.st_nlink - 1);
|
||||
else
|
||||
SIVAL(pdata,16,sbuf.st_nlink);
|
||||
SCVAL(pdata,20,0);
|
||||
SIVAL(pdata,16,nlink);
|
||||
SCVAL(pdata,20,delete_pending?1:0);
|
||||
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
||||
SSVAL(pdata,22,0); /* Padding. */
|
||||
break;
|
||||
@ -3129,10 +3162,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
pdata += 40;
|
||||
SOFF_T(pdata,0,allocation_size);
|
||||
SOFF_T(pdata,8,file_size);
|
||||
if (delete_pending && sbuf.st_nlink)
|
||||
SIVAL(pdata,16,sbuf.st_nlink - 1);
|
||||
else
|
||||
SIVAL(pdata,16,sbuf.st_nlink);
|
||||
SIVAL(pdata,16,nlink);
|
||||
SCVAL(pdata,20,delete_pending);
|
||||
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
||||
SSVAL(pdata,22,0);
|
||||
@ -3160,7 +3190,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
|
||||
case SMB_FILE_ACCESS_INFORMATION:
|
||||
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
|
||||
SIVAL(pdata,0,desired_access);
|
||||
SIVAL(pdata,0,access_mask);
|
||||
data_size = 4;
|
||||
break;
|
||||
|
||||
@ -3343,8 +3373,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
uint16 num_file_acls = 0;
|
||||
uint16 num_def_acls = 0;
|
||||
|
||||
if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
|
||||
if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
|
||||
} else {
|
||||
file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
|
||||
}
|
||||
@ -3429,50 +3459,46 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
open_file_shared. JRA.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
|
||||
NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
|
||||
uint32 dosmode)
|
||||
{
|
||||
if (delete_on_close) {
|
||||
/*
|
||||
* Only allow delete on close for writable files.
|
||||
*/
|
||||
|
||||
if (!lp_delete_readonly(SNUM(fsp->conn))) {
|
||||
if (dosmode & aRONLY) {
|
||||
DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_CANNOT_DELETE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only allow delete on close for writable shares.
|
||||
*/
|
||||
|
||||
if (!CAN_WRITE(fsp->conn)) {
|
||||
DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only allow delete on close for files/directories opened with delete intent.
|
||||
*/
|
||||
|
||||
if (!(fsp->desired_access & DELETE_ACCESS)) {
|
||||
DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
if (!delete_on_close) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if(fsp->is_directory) {
|
||||
fsp->directory_delete_on_close = delete_on_close;
|
||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
} else {
|
||||
fsp->delete_on_close = delete_on_close;
|
||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
||||
/*
|
||||
* Only allow delete on close for writable files.
|
||||
*/
|
||||
|
||||
if ((dosmode & aRONLY) &&
|
||||
!lp_delete_readonly(SNUM(fsp->conn))) {
|
||||
DEBUG(10,("can_set_delete_on_close: file %s delete on close "
|
||||
"flag set but file attribute is readonly.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_CANNOT_DELETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only allow delete on close for writable shares.
|
||||
*/
|
||||
|
||||
if (!CAN_WRITE(fsp->conn)) {
|
||||
DEBUG(10,("can_set_delete_on_close: file %s delete on "
|
||||
"close flag set but write access denied on share.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only allow delete on close for files/directories opened with delete
|
||||
* intent.
|
||||
*/
|
||||
|
||||
if (!(fsp->access_mask & DELETE_ACCESS)) {
|
||||
DEBUG(10,("can_set_delete_on_close: file %s delete on "
|
||||
"close flag set but delete access denied.\n",
|
||||
fsp->fsp_name ));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
@ -3487,10 +3513,12 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, u
|
||||
if flag is set.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
|
||||
NTSTATUS set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
|
||||
{
|
||||
DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
|
||||
delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
|
||||
DEBUG(10,("set_delete_on_close: %s delete on close flag for "
|
||||
"fnum = %d, file %s\n",
|
||||
delete_on_close ? "Adding" : "Removing", fsp->fnum,
|
||||
fsp->fsp_name ));
|
||||
|
||||
if (fsp->is_directory || fsp->is_stat)
|
||||
return NT_STATUS_OK;
|
||||
@ -3499,8 +3527,9 @@ NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
|
||||
DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
|
||||
fsp->fsp_name ));
|
||||
DEBUG(0,("set_delete_on_close: failed to change delete "
|
||||
"on close flag for file %s\n",
|
||||
fsp->fsp_name ));
|
||||
unlock_share_entry_fsp(fsp);
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
@ -3632,7 +3661,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
fsp = file_fsp(params,0);
|
||||
info_level = SVAL(params,2);
|
||||
|
||||
if(fsp && (fsp->is_directory || fsp->fd == -1)) {
|
||||
if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
|
||||
/*
|
||||
* This is actually a SETFILEINFO on a directory
|
||||
* handle (returned from an NT SMB). NT5.0 seems
|
||||
@ -3648,7 +3677,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
* Doing a DELETE_ON_CLOSE should cancel a print job.
|
||||
*/
|
||||
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
|
||||
fsp->share_mode = FILE_DELETE_ON_CLOSE;
|
||||
fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
|
||||
|
||||
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
|
||||
|
||||
@ -3664,7 +3693,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
CHECK_FSP(fsp,conn);
|
||||
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
fd = fsp->fd;
|
||||
fd = fsp->fh->fd;
|
||||
|
||||
if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
|
||||
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
||||
@ -3881,8 +3910,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
|
||||
if (fd == -1) {
|
||||
files_struct *new_fsp = NULL;
|
||||
int access_mode = 0;
|
||||
int action = 0;
|
||||
|
||||
if(global_oplock_break) {
|
||||
/* Queue this file modify as we are the process of an oplock break. */
|
||||
@ -3894,16 +3921,20 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
|
||||
SET_OPEN_MODE(DOS_OPEN_RDWR),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||
FILE_WRITE_DATA,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY, &access_mode, &action);
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (new_fsp == NULL)
|
||||
if (new_fsp == NULL) {
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
}
|
||||
ret = vfs_allocate_file_space(new_fsp, allocation_size);
|
||||
if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
|
||||
if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
|
||||
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
|
||||
new_fsp->fnum, strerror(errno)));
|
||||
ret = -1;
|
||||
@ -3963,14 +3994,15 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
if (fsp == NULL)
|
||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||
|
||||
status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
|
||||
status = can_set_delete_on_close(fsp, delete_on_close,
|
||||
dosmode);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ERROR_NT(status);
|
||||
}
|
||||
|
||||
/* The set is across all open files on this dev/inode pair. */
|
||||
status =set_delete_on_close_over_all(fsp, delete_on_close);
|
||||
status =set_delete_on_close(fsp, delete_on_close);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ERROR_NT(status);
|
||||
}
|
||||
@ -3998,7 +4030,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
||||
DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
|
||||
fname, (double)position_information ));
|
||||
if (fsp) {
|
||||
fsp->position_information = position_information;
|
||||
fsp->fh->position_information = position_information;
|
||||
}
|
||||
|
||||
/* We're done. We only get position info in this call. */
|
||||
@ -4422,8 +4454,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
|
||||
if (fd == -1) {
|
||||
files_struct *new_fsp = NULL;
|
||||
int access_mode = 0;
|
||||
int action = 0;
|
||||
|
||||
if(global_oplock_break) {
|
||||
/* Queue this file modify as we are the process of an oplock break. */
|
||||
@ -4435,22 +4465,27 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_fsp = open_file_shared(conn, fname, &sbuf,
|
||||
SET_OPEN_MODE(DOS_OPEN_RDWR),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||
FILE_WRITE_DATA,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
INTERNAL_OPEN_ONLY, &access_mode, &action);
|
||||
INTERNAL_OPEN_ONLY,
|
||||
NULL);
|
||||
|
||||
if (new_fsp == NULL)
|
||||
if (new_fsp == NULL) {
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
}
|
||||
ret = vfs_set_filelen(new_fsp, size);
|
||||
close_file(new_fsp,True);
|
||||
} else {
|
||||
ret = vfs_set_filelen(fsp, size);
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
if (ret == -1) {
|
||||
return (UNIXERROR(ERRHRD,ERRdiskfull));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -226,7 +226,7 @@ ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void
|
||||
if (result == -1 && errno == ESPIPE) {
|
||||
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
||||
result = SMB_VFS_READ(fsp, fd, data, n);
|
||||
fsp->pos = 0;
|
||||
fsp->fh->pos = 0;
|
||||
}
|
||||
|
||||
#else /* HAVE_PREAD */
|
||||
@ -237,7 +237,7 @@ ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void
|
||||
if (curr == -1 && errno == ESPIPE) {
|
||||
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
||||
result = SMB_VFS_READ(fsp, fd, data, n);
|
||||
fsp->pos = 0;
|
||||
fsp->fh->pos = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -660,7 +660,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
|
||||
SMB_OFF_T retlen;
|
||||
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
|
||||
|
||||
retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
|
||||
retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write);
|
||||
if (retlen <= 0)
|
||||
return -1;
|
||||
|
||||
|
@ -430,7 +430,7 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
|
||||
|
||||
while (total < byte_count)
|
||||
{
|
||||
ssize_t ret = SMB_VFS_READ(fsp, fsp->fd, buf + total,
|
||||
ssize_t ret = SMB_VFS_READ(fsp, fsp->fh->fd, buf + total,
|
||||
byte_count - total);
|
||||
|
||||
if (ret == 0) return total;
|
||||
@ -452,7 +452,7 @@ ssize_t vfs_pread_data(files_struct *fsp, char *buf,
|
||||
|
||||
while (total < byte_count)
|
||||
{
|
||||
ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fd, buf + total,
|
||||
ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fh->fd, buf + total,
|
||||
byte_count - total, offset + total);
|
||||
|
||||
if (ret == 0) return total;
|
||||
@ -477,7 +477,7 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
|
||||
ssize_t ret;
|
||||
|
||||
while (total < N) {
|
||||
ret = SMB_VFS_WRITE(fsp,fsp->fd,buffer + total,N - total);
|
||||
ret = SMB_VFS_WRITE(fsp,fsp->fh->fd,buffer + total,N - total);
|
||||
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
@ -496,7 +496,7 @@ ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer,
|
||||
ssize_t ret;
|
||||
|
||||
while (total < N) {
|
||||
ret = SMB_VFS_PWRITE(fsp, fsp->fd, buffer + total,
|
||||
ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, buffer + total,
|
||||
N - total, offset + total);
|
||||
|
||||
if (ret == -1)
|
||||
@ -535,7 +535,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
|
||||
@ -549,7 +549,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
|
||||
fsp->fsp_name, (double)st.st_size ));
|
||||
|
||||
flush_write_cache(fsp, SIZECHANGE_FLUSH);
|
||||
if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
|
||||
if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) {
|
||||
set_filelen_write_cache(fsp, len);
|
||||
}
|
||||
return ret;
|
||||
@ -591,7 +591,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
|
||||
release_level_2_oplocks_on_change(fsp);
|
||||
DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
|
||||
flush_write_cache(fsp, SIZECHANGE_FLUSH);
|
||||
if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, len)) != -1)
|
||||
if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1)
|
||||
set_filelen_write_cache(fsp, len);
|
||||
|
||||
return ret;
|
||||
@ -617,7 +617,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
|
||||
ssize_t pwrite_ret;
|
||||
|
||||
release_level_2_oplocks_on_change(fsp);
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
|
||||
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
|
||||
if (ret == -1) {
|
||||
return ret;
|
||||
}
|
||||
@ -646,7 +646,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
|
||||
while (total < num_to_write) {
|
||||
size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total));
|
||||
|
||||
pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fd, sparse_buf, curr_write_size, offset + total);
|
||||
pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, sparse_buf, curr_write_size, offset + total);
|
||||
if (pwrite_ret == -1) {
|
||||
DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
|
||||
fsp->fsp_name, strerror(errno) ));
|
||||
@ -685,7 +685,7 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
|
||||
in_fsp = in;
|
||||
out_fsp = out;
|
||||
|
||||
return transfer_file_internal(in_fsp->fd, out_fsp->fd, n, read_fn, write_fn);
|
||||
return transfer_file_internal(in_fsp->fh->fd, out_fsp->fh->fd, n, read_fn, write_fn);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -286,7 +286,7 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
|
||||
|
||||
vfs->files[fd] = SMB_MALLOC_P(struct files_struct);
|
||||
vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]);
|
||||
vfs->files[fd]->fd = fd;
|
||||
vfs->files[fd]->fh->fd = fd;
|
||||
vfs->files[fd]->conn = vfs->conn;
|
||||
printf("open: fd=%d\n", fd);
|
||||
return NT_STATUS_OK;
|
||||
|
@ -111,37 +111,47 @@ static void print_share_mode(share_mode_entry *e, char *fname)
|
||||
count++;
|
||||
|
||||
if (Ucrit_checkPid(e->pid)) {
|
||||
d_printf("%-5d ",(int)e->pid);
|
||||
switch (GET_DENY_MODE(e->share_mode)) {
|
||||
case DENY_NONE: d_printf("DENY_NONE "); break;
|
||||
case DENY_ALL: d_printf("DENY_ALL "); break;
|
||||
case DENY_DOS: d_printf("DENY_DOS "); break;
|
||||
case DENY_READ: d_printf("DENY_READ "); break;
|
||||
case DENY_WRITE:printf("DENY_WRITE "); break;
|
||||
case DENY_FCB: d_printf("DENY_FCB "); break;
|
||||
}
|
||||
d_printf("0x%-8x ",(unsigned int)e->desired_access);
|
||||
switch (e->share_mode&0xF) {
|
||||
case 0: d_printf("RDONLY "); break;
|
||||
case 1: d_printf("WRONLY "); break;
|
||||
case 2: d_printf("RDWR "); break;
|
||||
}
|
||||
d_printf("%-5d ",(int)e->pid);
|
||||
switch (map_share_mode_to_deny_mode(e->share_access,
|
||||
e->private_options)) {
|
||||
case DENY_NONE: d_printf("DENY_NONE "); break;
|
||||
case DENY_ALL: d_printf("DENY_ALL "); break;
|
||||
case DENY_DOS: d_printf("DENY_DOS "); break;
|
||||
case DENY_READ: d_printf("DENY_READ "); break;
|
||||
case DENY_WRITE:printf("DENY_WRITE "); break;
|
||||
case DENY_FCB: d_printf("DENY_FCB "); break;
|
||||
default: {
|
||||
d_printf("unknown-please report ! "
|
||||
"e->share_access = 0x%x, "
|
||||
"e->private_options = 0x%x\n",
|
||||
(unsigned int)e->share_access,
|
||||
(unsigned int)e->private_options );
|
||||
break;
|
||||
}
|
||||
}
|
||||
d_printf("0x%-8x ",(unsigned int)e->access_mask);
|
||||
if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) {
|
||||
d_printf("RDWR ");
|
||||
} else if (e->access_mask & FILE_WRITE_DATA) {
|
||||
d_printf("WRONLY ");
|
||||
} else {
|
||||
d_printf("RDONLY ");
|
||||
}
|
||||
|
||||
if((e->op_type &
|
||||
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
|
||||
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
|
||||
d_printf("EXCLUSIVE+BATCH ");
|
||||
else if (e->op_type & EXCLUSIVE_OPLOCK)
|
||||
d_printf("EXCLUSIVE ");
|
||||
else if (e->op_type & BATCH_OPLOCK)
|
||||
d_printf("BATCH ");
|
||||
else if (e->op_type & LEVEL_II_OPLOCK)
|
||||
d_printf("LEVEL_II ");
|
||||
else
|
||||
d_printf("NONE ");
|
||||
if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
|
||||
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) {
|
||||
d_printf("EXCLUSIVE+BATCH ");
|
||||
} else if (e->op_type & EXCLUSIVE_OPLOCK) {
|
||||
d_printf("EXCLUSIVE ");
|
||||
} else if (e->op_type & BATCH_OPLOCK) {
|
||||
d_printf("BATCH ");
|
||||
} else if (e->op_type & LEVEL_II_OPLOCK) {
|
||||
d_printf("LEVEL_II ");
|
||||
} else {
|
||||
d_printf("NONE ");
|
||||
}
|
||||
|
||||
d_printf(" %s %s",fname,
|
||||
asctime(LocalTime((time_t *)&e->time.tv_sec)));
|
||||
d_printf(" %s %s",fname, asctime(LocalTime((time_t *)&e->time.tv_sec)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,6 +457,10 @@ static void cgi_download(char *file)
|
||||
printf("Content-Type: image/gif\r\n");
|
||||
} else if (strcmp(p,".jpg")==0) {
|
||||
printf("Content-Type: image/jpeg\r\n");
|
||||
} else if (strcmp(p,".png")==0) {
|
||||
printf("Content-Type: image/png\r\n");
|
||||
} else if (strcmp(p,".css")==0) {
|
||||
printf("Content-Type: text/css\r\n");
|
||||
} else if (strcmp(p,".txt")==0) {
|
||||
printf("Content-Type: text/plain\r\n");
|
||||
} else {
|
||||
|
@ -108,23 +108,28 @@ static char *tstring(time_t t)
|
||||
static void print_share_mode(share_mode_entry *e, char *fname)
|
||||
{
|
||||
char *utf8_fname;
|
||||
int deny_mode = map_share_mode_to_deny_mode(e->share_access,
|
||||
e->private_options);
|
||||
|
||||
printf("<tr><td>%s</td>",_(mapPid2Machine(e->pid)));
|
||||
printf("<td>");
|
||||
switch ((e->share_mode>>4)&0xF) {
|
||||
switch ((deny_mode>>4)&0xF) {
|
||||
case DENY_NONE: printf("DENY_NONE"); break;
|
||||
case DENY_ALL: printf("DENY_ALL "); break;
|
||||
case DENY_DOS: printf("DENY_DOS "); break;
|
||||
case DENY_FCB: printf("DENY_FCB "); break;
|
||||
case DENY_READ: printf("DENY_READ "); break;
|
||||
case DENY_WRITE:printf("DENY_WRITE "); break;
|
||||
}
|
||||
printf("</td>");
|
||||
|
||||
printf("<td>");
|
||||
switch (e->share_mode&0xF) {
|
||||
case 0: printf("%s", _("RDONLY ")); break;
|
||||
case 1: printf("%s", _("WRONLY ")); break;
|
||||
case 2: printf("%s", _("RDWR ")); break;
|
||||
if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) {
|
||||
printf("%s", _("RDWR "));
|
||||
} else if (e->access_mask & FILE_WRITE_DATA) {
|
||||
printf("%s", _("WRONLY "));
|
||||
} else {
|
||||
printf("%s", _("RDONLY "));
|
||||
}
|
||||
printf("</td>");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user