mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +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 ERRinvalidname 123 /* Invalid name */
|
||||||
#define ERRunknownlevel 124
|
#define ERRunknownlevel 124
|
||||||
#define ERRnotlocked 158 /* This region is not locked by this locking context. */
|
#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 ERRrename 183
|
||||||
#define ERRbadpipe 230 /* Named pipe invalid */
|
#define ERRbadpipe 230 /* Named pipe invalid */
|
||||||
#define ERRpipebusy 231 /* All instances of pipe are busy */
|
#define ERRpipebusy 231 /* All instances of pipe are busy */
|
||||||
|
@ -124,7 +124,6 @@ typedef struct ntlmssp_state
|
|||||||
*
|
*
|
||||||
* @param ntlmssp_state This structure
|
* @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 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);
|
NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge);
|
||||||
|
@ -107,44 +107,32 @@ typedef int BOOL;
|
|||||||
#define DOS_OPEN_FCB 0xF
|
#define DOS_OPEN_FCB 0xF
|
||||||
|
|
||||||
/* define shifts and masks for share and open modes. */
|
/* define shifts and masks for share and open modes. */
|
||||||
#define OPEN_MODE_MASK 0xF
|
#define OPENX_MODE_MASK 0xF
|
||||||
#define SHARE_MODE_SHIFT 4
|
#define DENY_MODE_SHIFT 4
|
||||||
#define SHARE_MODE_MASK 0x7
|
#define DENY_MODE_MASK 0x7
|
||||||
#define GET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
|
#define GET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK)
|
||||||
#define SET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
|
#define SET_OPENX_MODE(x) ((x) & OPENX_MODE_MASK)
|
||||||
#define GET_DENY_MODE(x) (((x)>>SHARE_MODE_SHIFT) & SHARE_MODE_MASK)
|
#define GET_DENY_MODE(x) (((x)>>DENY_MODE_SHIFT) & DENY_MODE_MASK)
|
||||||
#define SET_DENY_MODE(x) (((x) & SHARE_MODE_MASK) <<SHARE_MODE_SHIFT)
|
#define SET_DENY_MODE(x) (((x) & DENY_MODE_MASK) <<DENY_MODE_SHIFT)
|
||||||
|
|
||||||
/* Sync on open file (not sure if used anymore... ?) */
|
/* Sync on open file (not sure if used anymore... ?) */
|
||||||
#define FILE_SYNC_OPENMODE (1<<14)
|
#define FILE_SYNC_OPENMODE (1<<14)
|
||||||
#define GET_FILE_SYNC_OPENMODE(x) (((x) & FILE_SYNC_OPENMODE) ? True : False)
|
#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 */
|
/* open disposition values */
|
||||||
#define FILE_EXISTS_FAIL 0
|
#define OPENX_FILE_EXISTS_FAIL 0
|
||||||
#define FILE_EXISTS_OPEN 1
|
#define OPENX_FILE_EXISTS_OPEN 1
|
||||||
#define FILE_EXISTS_TRUNCATE 2
|
#define OPENX_FILE_EXISTS_TRUNCATE 2
|
||||||
|
|
||||||
/* mask for open disposition. */
|
/* 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 GET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||||
#define SET_FILE_OPEN_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
#define SET_FILE_OPENX_DISPOSITION(x) ((x) & FILE_OPEN_MASK)
|
||||||
|
|
||||||
/* The above can be OR'ed with... */
|
/* The above can be OR'ed with... */
|
||||||
#define FILE_CREATE_IF_NOT_EXIST 0x10
|
#define OPENX_FILE_CREATE_IF_NOT_EXIST 0x10
|
||||||
#define FILE_FAIL_IF_NOT_EXIST 0
|
#define OPENX_FILE_FAIL_IF_NOT_EXIST 0
|
||||||
|
|
||||||
#define GET_FILE_CREATE_DISPOSITION(x) ((x) & (FILE_CREATE_IF_NOT_EXIST|FILE_FAIL_IF_NOT_EXIST))
|
|
||||||
|
|
||||||
/* share types */
|
/* share types */
|
||||||
#define STYPE_DISKTREE 0 /* Disk drive */
|
#define STYPE_DISKTREE 0 /* Disk drive */
|
||||||
@ -407,27 +395,38 @@ typedef struct
|
|||||||
|
|
||||||
#include "fake_file.h"
|
#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 {
|
typedef struct files_struct {
|
||||||
struct files_struct *next, *prev;
|
struct files_struct *next, *prev;
|
||||||
int fnum;
|
int fnum;
|
||||||
struct connection_struct *conn;
|
struct connection_struct *conn;
|
||||||
int fd;
|
struct fd_handle *fh;
|
||||||
unsigned int num_smb_operations;
|
unsigned int num_smb_operations;
|
||||||
uint16 rap_print_jobid;
|
uint16 rap_print_jobid;
|
||||||
SMB_DEV_T dev;
|
SMB_DEV_T dev;
|
||||||
SMB_INO_T inode;
|
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 initial_allocation_size; /* Faked up initial allocation on disk. */
|
||||||
SMB_BIG_UINT position_information;
|
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
uint16 file_pid;
|
uint16 file_pid;
|
||||||
uint16 vuid;
|
uint16 vuid;
|
||||||
write_bmpx_struct *wbmpx_ptr;
|
write_bmpx_struct *wbmpx_ptr;
|
||||||
write_cache *wcp;
|
write_cache *wcp;
|
||||||
struct timeval open_time;
|
struct timeval open_time;
|
||||||
int share_mode;
|
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
|
||||||
uint32 desired_access;
|
uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
|
||||||
BOOL pending_modtime_owner;
|
BOOL pending_modtime_owner;
|
||||||
time_t pending_modtime;
|
time_t pending_modtime;
|
||||||
time_t last_write_time;
|
time_t last_write_time;
|
||||||
@ -441,7 +440,6 @@ typedef struct files_struct {
|
|||||||
BOOL modified;
|
BOOL modified;
|
||||||
BOOL is_directory;
|
BOOL is_directory;
|
||||||
BOOL is_stat;
|
BOOL is_stat;
|
||||||
BOOL directory_delete_on_close;
|
|
||||||
BOOL aio_write_behind;
|
BOOL aio_write_behind;
|
||||||
char *fsp_name;
|
char *fsp_name;
|
||||||
FAKE_FILE_HANDLE *fake_file_handle;
|
FAKE_FILE_HANDLE *fake_file_handle;
|
||||||
@ -639,8 +637,12 @@ typedef struct {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
uint16 op_port;
|
uint16 op_port;
|
||||||
uint16 op_type;
|
uint16 op_type;
|
||||||
int share_mode;
|
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
|
||||||
uint32 desired_access;
|
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;
|
struct timeval time;
|
||||||
SMB_DEV_T dev;
|
SMB_DEV_T dev;
|
||||||
SMB_INO_T inode;
|
SMB_INO_T inode;
|
||||||
@ -1079,18 +1081,18 @@ struct bitmap {
|
|||||||
#define DESIRED_ACCESS_PIPE 0x2019f
|
#define DESIRED_ACCESS_PIPE 0x2019f
|
||||||
|
|
||||||
/* Generic access masks & rights. */
|
/* Generic access masks & rights. */
|
||||||
#define DELETE_ACCESS (1L<<16) /* 0x00010000 */
|
#define DELETE_ACCESS 0x00010000 /* (1L<<16) */
|
||||||
#define READ_CONTROL_ACCESS (1L<<17) /* 0x00020000 */
|
#define READ_CONTROL_ACCESS 0x00020000 /* (1L<<17) */
|
||||||
#define WRITE_DAC_ACCESS (1L<<18) /* 0x00040000 */
|
#define WRITE_DAC_ACCESS 0x00040000 /* (1L<<18) */
|
||||||
#define WRITE_OWNER_ACCESS (1L<<19) /* 0x00080000 */
|
#define WRITE_OWNER_ACCESS 0x00080000 /* (1L<<19) */
|
||||||
#define SYNCHRONIZE_ACCESS (1L<<20) /* 0x00100000 */
|
#define SYNCHRONIZE_ACCESS 0x00100000 /* (1L<<20) */
|
||||||
|
|
||||||
#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */
|
#define SYSTEM_SECURITY_ACCESS 0x01000000 /* (1L<<24) */
|
||||||
#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */
|
#define MAXIMUM_ALLOWED_ACCESS 0x02000000 /* (1L<<25) */
|
||||||
#define GENERIC_ALL_ACCESS (1<<28) /* 0x10000000 */
|
#define GENERIC_ALL_ACCESS 0x10000000 /* (1<<28) */
|
||||||
#define GENERIC_EXECUTE_ACCESS (1<<29) /* 0x20000000 */
|
#define GENERIC_EXECUTE_ACCESS 0x20000000 /* (1<<29) */
|
||||||
#define GENERIC_WRITE_ACCESS (1<<30) /* 0x40000000 */
|
#define GENERIC_WRITE_ACCESS 0x40000000 /* (1<<30) */
|
||||||
#define GENERIC_READ_ACCESS (((unsigned)1)<<31) /* 0x80000000 */
|
#define GENERIC_READ_ACCESS ((unsigned)0x80000000) /* (((unsigned)1)<<31) */
|
||||||
|
|
||||||
/* Mapping of generic access rights for files to specific rights. */
|
/* Mapping of generic access rights for files to specific rights. */
|
||||||
|
|
||||||
@ -1172,12 +1174,12 @@ struct bitmap {
|
|||||||
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L
|
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L
|
||||||
|
|
||||||
/* CreateDisposition field. */
|
/* CreateDisposition field. */
|
||||||
#define FILE_SUPERSEDE 0
|
#define FILE_SUPERSEDE 0 /* File exists overwrite/supersede. File not exist create. */
|
||||||
#define FILE_OPEN 1
|
#define FILE_OPEN 1 /* File exists open. File not exist fail. */
|
||||||
#define FILE_CREATE 2
|
#define FILE_CREATE 2 /* File exists fail. File not exist create. */
|
||||||
#define FILE_OPEN_IF 3
|
#define FILE_OPEN_IF 3 /* File exists open. File not exist create. */
|
||||||
#define FILE_OVERWRITE 4
|
#define FILE_OVERWRITE 4 /* File exists overwrite. File not exist fail. */
|
||||||
#define FILE_OVERWRITE_IF 5
|
#define FILE_OVERWRITE_IF 5 /* File exists overwrite. File not exist create. */
|
||||||
|
|
||||||
/* CreateOptions field. */
|
/* CreateOptions field. */
|
||||||
#define FILE_DIRECTORY_FILE 0x0001
|
#define FILE_DIRECTORY_FILE 0x0001
|
||||||
@ -1190,6 +1192,10 @@ struct bitmap {
|
|||||||
#define FILE_DELETE_ON_CLOSE 0x1000
|
#define FILE_DELETE_ON_CLOSE 0x1000
|
||||||
#define FILE_OPEN_BY_FILE_ID 0x2000
|
#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. */
|
/* Responses when opening a file. */
|
||||||
#define FILE_WAS_SUPERSEDED 0
|
#define FILE_WAS_SUPERSEDED 0
|
||||||
#define FILE_WAS_OPENED 1
|
#define FILE_WAS_OPENED 1
|
||||||
@ -1335,7 +1341,7 @@ char *strdup(char *s);
|
|||||||
#define FLAGS2_IS_LONG_NAME 0x0040
|
#define FLAGS2_IS_LONG_NAME 0x0040
|
||||||
#define FLAGS2_EXTENDED_SECURITY 0x0800
|
#define FLAGS2_EXTENDED_SECURITY 0x0800
|
||||||
#define FLAGS2_DFS_PATHNAMES 0x1000
|
#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_32_BIT_ERROR_CODES 0x4000
|
||||||
#define FLAGS2_UNICODE_STRINGS 0x8000
|
#define FLAGS2_UNICODE_STRINGS 0x8000
|
||||||
|
|
||||||
@ -1442,10 +1448,6 @@ extern int chain_size;
|
|||||||
#define LOCKING_ANDX_CANCEL_LOCK 0x8
|
#define LOCKING_ANDX_CANCEL_LOCK 0x8
|
||||||
#define LOCKING_ANDX_LARGE_FILES 0x10
|
#define LOCKING_ANDX_LARGE_FILES 0x10
|
||||||
|
|
||||||
/* Oplock levels */
|
|
||||||
#define OPLOCKLEVEL_NONE 0
|
|
||||||
#define OPLOCKLEVEL_II 1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bits we test with.
|
* Bits we test with.
|
||||||
*/
|
*/
|
||||||
@ -1456,22 +1458,26 @@ extern int chain_size;
|
|||||||
#define LEVEL_II_OPLOCK 4
|
#define LEVEL_II_OPLOCK 4
|
||||||
#define INTERNAL_OPEN_ONLY 8
|
#define INTERNAL_OPEN_ONLY 8
|
||||||
|
|
||||||
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
|
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
|
||||||
#define BATCH_OPLOCK_TYPE(lck) ((lck) & BATCH_OPLOCK)
|
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
|
||||||
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & LEVEL_II_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 CORE_OPLOCK_GRANTED (1<<5)
|
||||||
#define EXTENDED_OPLOCK_GRANTED (1<<15)
|
#define EXTENDED_OPLOCK_GRANTED (1<<15)
|
||||||
|
|
||||||
/*
|
|
||||||
* Return values for oplock types.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NO_OPLOCK_RETURN 0
|
#define NO_OPLOCK_RETURN 0
|
||||||
#define EXCLUSIVE_OPLOCK_RETURN 1
|
#define EXCLUSIVE_OPLOCK_RETURN 1
|
||||||
#define BATCH_OPLOCK_RETURN 2
|
#define BATCH_OPLOCK_RETURN 2
|
||||||
#define LEVEL_II_OPLOCK_RETURN 3
|
#define LEVEL_II_OPLOCK_RETURN 3
|
||||||
|
|
||||||
|
/* Oplock levels */
|
||||||
|
#define OPLOCKLEVEL_NONE 0
|
||||||
|
#define OPLOCKLEVEL_II 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loopback command offsets.
|
* Loopback command offsets.
|
||||||
*/
|
*/
|
||||||
|
@ -101,15 +101,16 @@
|
|||||||
extern struct current_user current_user;\
|
extern struct current_user current_user;\
|
||||||
if (!FNUM_OK(fsp,conn)) \
|
if (!FNUM_OK(fsp,conn)) \
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadfid)); \
|
return(ERROR_DOS(ERRDOS,ERRbadfid)); \
|
||||||
else if((fsp)->fd == -1) \
|
else if((fsp)->fh->fd == -1) \
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadaccess));\
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));\
|
||||||
(fsp)->num_smb_operations++;\
|
(fsp)->num_smb_operations++;\
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define CHECK_READ(fsp) if (!(fsp)->can_read) \
|
#define CHECK_READ(fsp,inbuf) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadaccess))
|
((SVAL((inbuf),smb_flg2) & FLAGS2_READ_PERMIT_EXECUTE) && \
|
||||||
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
|
(fsp->access_mask & FILE_EXECUTE))))
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadaccess))
|
|
||||||
|
#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) || \
|
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
|
||||||
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
|
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 11 to include seekdir/telldir/rewinddir calls. JRA */
|
||||||
/* Changed to version 12 to add mask and attributes to opendir(). JRA
|
/* Changed to version 12 to add mask and attributes to opendir(). JRA
|
||||||
Also include aio calls. 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 */
|
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)
|
||||||
{
|
{
|
||||||
return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0,
|
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},
|
{ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE},
|
||||||
{ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED},
|
{ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED},
|
||||||
{ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED},
|
{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, 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_OVERRUN},
|
||||||
{ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR},
|
{ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR},
|
||||||
{ERRDOS, 23, NT_STATUS_DATA_ERROR},
|
{ERRDOS, 23, NT_STATUS_DATA_ERROR},
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
Locking functions
|
Locking functions
|
||||||
Copyright (C) Andrew Tridgell 1992-2000
|
Copyright (C) Andrew Tridgell 1992-2000
|
||||||
Copyright (C) Jeremy Allison 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
|
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
|
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 {
|
struct locking_data {
|
||||||
union {
|
union {
|
||||||
int num_share_mode_entries;
|
struct {
|
||||||
|
int num_share_mode_entries;
|
||||||
|
BOOL delete_on_close;
|
||||||
|
} s;
|
||||||
share_mode_entry dummy; /* Needed for alignment. */
|
share_mode_entry dummy; /* Needed for alignment. */
|
||||||
} u;
|
} u;
|
||||||
/* the following two entries are implicit
|
/* the following two entries are implicit
|
||||||
@ -432,10 +436,14 @@ char *share_mode_str(int num, share_mode_entry *e)
|
|||||||
{
|
{
|
||||||
static pstring share_str;
|
static pstring share_str;
|
||||||
|
|
||||||
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
|
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",
|
"pid = %lu, share_access = 0x%x, private_options = 0x%x, "
|
||||||
num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
|
"access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, "
|
||||||
(unsigned int)e->dev, (double)e->inode );
|
"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;
|
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)
|
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);
|
share_mode_entry *shares = (share_mode_entry *)(data + 1);
|
||||||
int i;
|
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.
|
Get all share mode entries for a dev/inode pair.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
int get_share_modes(connection_struct *conn,
|
int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode,
|
||||||
SMB_DEV_T dev, SMB_INO_T inode,
|
share_mode_entry **pp_shares,
|
||||||
share_mode_entry **pp_shares)
|
BOOL *delete_on_close)
|
||||||
{
|
{
|
||||||
TDB_DATA dbuf;
|
TDB_DATA dbuf;
|
||||||
struct locking_data *data;
|
struct locking_data *data;
|
||||||
@ -470,13 +478,18 @@ int get_share_modes(connection_struct *conn,
|
|||||||
share_mode_entry *shares = NULL;
|
share_mode_entry *shares = NULL;
|
||||||
TDB_DATA key = locking_key(dev, inode);
|
TDB_DATA key = locking_key(dev, inode);
|
||||||
*pp_shares = NULL;
|
*pp_shares = NULL;
|
||||||
|
*delete_on_close = False;
|
||||||
|
|
||||||
dbuf = tdb_fetch(tdb, key);
|
dbuf = tdb_fetch(tdb, key);
|
||||||
if (!dbuf.dptr)
|
if (!dbuf.dptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
data = (struct locking_data *)dbuf.dptr;
|
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) {
|
if(num_share_modes) {
|
||||||
pstring fname;
|
pstring fname;
|
||||||
int i;
|
int i;
|
||||||
@ -515,7 +528,7 @@ int get_share_modes(connection_struct *conn,
|
|||||||
|
|
||||||
/* Did we delete any ? If so, re-store in tdb. */
|
/* Did we delete any ? If so, re-store in tdb. */
|
||||||
if (del_count) {
|
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) {
|
if (num_share_modes) {
|
||||||
memcpy(dbuf.dptr + sizeof(*data), shares,
|
memcpy(dbuf.dptr + sizeof(*data), shares,
|
||||||
@ -527,7 +540,7 @@ int get_share_modes(connection_struct *conn,
|
|||||||
/* The record has shrunk a bit */
|
/* The record has shrunk a bit */
|
||||||
dbuf.dsize -= del_count * sizeof(share_mode_entry);
|
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) {
|
if (tdb_delete(tdb, key) == -1) {
|
||||||
SAFE_FREE(shares);
|
SAFE_FREE(shares);
|
||||||
SAFE_FREE(dbuf.dptr);
|
SAFE_FREE(dbuf.dptr);
|
||||||
@ -548,6 +561,15 @@ int get_share_modes(connection_struct *conn,
|
|||||||
return num_share_modes;
|
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.
|
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));
|
memset(e, '\0', sizeof(share_mode_entry));
|
||||||
e->pid = sys_getpid();
|
e->pid = sys_getpid();
|
||||||
e->share_mode = fsp->share_mode;
|
e->share_access = fsp->share_access;
|
||||||
e->desired_access = fsp->desired_access;
|
e->private_options = fsp->fh->private_options;
|
||||||
|
e->access_mask = fsp->access_mask;
|
||||||
e->op_port = port;
|
e->op_port = port;
|
||||||
e->op_type = op_type;
|
e->op_type = op_type;
|
||||||
memcpy(x, &fsp->open_time, sizeof(struct timeval));
|
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->share_file_id == e2->share_file_id &&
|
||||||
e1->dev == e2->dev &&
|
e1->dev == e2->dev &&
|
||||||
e1->inode == e2->inode &&
|
e1->inode == e2->inode &&
|
||||||
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
|
(e1->share_access) != (e2->share_access)) {
|
||||||
DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
|
DEBUG(0,("PANIC: share_modes_identical: share_mode "
|
||||||
(unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
|
"mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
|
||||||
(unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
|
(unsigned int)e1->share_access,
|
||||||
|
(unsigned int)e2->share_access ));
|
||||||
smb_panic("PANIC: share_modes_identical logic error.\n");
|
smb_panic("PANIC: share_modes_identical logic error.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (e1->pid == e2->pid &&
|
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->dev == e2->dev &&
|
||||||
e1->inode == e2->inode &&
|
e1->inode == e2->inode &&
|
||||||
e1->share_file_id == e2->share_file_id );
|
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.
|
Ignore if no entry deleted.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode,
|
||||||
share_mode_entry *entry, share_mode_entry **ppse)
|
share_mode_entry *entry, share_mode_entry **ppse,
|
||||||
|
BOOL *delete_on_close)
|
||||||
{
|
{
|
||||||
TDB_DATA dbuf;
|
TDB_DATA dbuf;
|
||||||
struct locking_data *data;
|
struct locking_data *data;
|
||||||
@ -621,6 +646,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
data = (struct locking_data *)dbuf.dptr;
|
data = (struct locking_data *)dbuf.dptr;
|
||||||
|
*delete_on_close = data->u.s.delete_on_close;
|
||||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
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.
|
* 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)) {
|
if (share_modes_identical(&shares[i], entry)) {
|
||||||
DEBUG(10,("del_share_entry: deleted %s\n",
|
DEBUG(10,("del_share_entry: deleted %s\n",
|
||||||
share_mode_str(i, &shares[i]) ));
|
share_mode_str(i, &shares[i]) ));
|
||||||
if (ppse)
|
if (ppse)
|
||||||
*ppse = memdup(&shares[i], sizeof(*shares));
|
*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) {
|
if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) {
|
||||||
memmove(&shares[i], &shares[i+1],
|
memmove(&shares[i], &shares[i+1],
|
||||||
dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
|
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 */
|
/* the record may have shrunk a bit */
|
||||||
dbuf.dsize -= del_count * sizeof(*shares);
|
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 */
|
/* 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)
|
if (tdb_delete(tdb, key) == -1)
|
||||||
count = -1;
|
count = -1;
|
||||||
} else {
|
} 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.
|
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;
|
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);
|
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)
|
if (!p)
|
||||||
return False;
|
return False;
|
||||||
data = (struct locking_data *)p;
|
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",
|
DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
|
||||||
fsp->fsp_name ));
|
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 */
|
/* we're adding to an existing entry - this is a bit fiddly */
|
||||||
data = (struct locking_data *)dbuf.dptr;
|
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",
|
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);
|
size = dbuf.dsize + sizeof(share_mode_entry);
|
||||||
p = SMB_MALLOC(size);
|
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));
|
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
||||||
|
|
||||||
/* find any with our pid and call the supplied function */
|
/* 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])) {
|
if (share_modes_identical(entry, &shares[i])) {
|
||||||
mod_fn(&shares[i], dev, inode, param);
|
mod_fn(&shares[i], dev, inode, param);
|
||||||
need_store=True;
|
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 the mod fn was called then store it back */
|
||||||
if (need_store) {
|
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)
|
if (tdb_delete(tdb, key) == -1)
|
||||||
ret = False;
|
ret = False;
|
||||||
} else {
|
} else {
|
||||||
@ -877,8 +906,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
|
|||||||
{
|
{
|
||||||
TDB_DATA dbuf;
|
TDB_DATA dbuf;
|
||||||
struct locking_data *data;
|
struct locking_data *data;
|
||||||
int i;
|
BOOL res;
|
||||||
share_mode_entry *shares;
|
|
||||||
TDB_DATA key = locking_key(dev, inode);
|
TDB_DATA key = locking_key(dev, inode);
|
||||||
|
|
||||||
/* read in the existing share modes */
|
/* 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;
|
return False;
|
||||||
|
|
||||||
data = (struct locking_data *)dbuf.dptr;
|
data = (struct locking_data *)dbuf.dptr;
|
||||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
|
||||||
|
|
||||||
/* Set/Unset the delete on close element. */
|
/* Set/Unset the delete on close element. */
|
||||||
for (i=0;i<data->u.num_share_mode_entries;i++,shares++) {
|
data->u.s.delete_on_close = delete_on_close;
|
||||||
shares->share_mode = (delete_on_close ?
|
|
||||||
(shares->share_mode | DELETE_ON_CLOSE_FLAG) :
|
|
||||||
(shares->share_mode & ~DELETE_ON_CLOSE_FLAG) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store it back */
|
res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1);
|
||||||
if (data->u.num_share_mode_entries) {
|
|
||||||
if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
|
|
||||||
SAFE_FREE(dbuf.dptr);
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SAFE_FREE(dbuf.dptr);
|
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)
|
if (!p)
|
||||||
return False;
|
return False;
|
||||||
data = (struct deferred_open_data *)p;
|
data = (struct deferred_open_data *)p;
|
||||||
|
ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */
|
||||||
data->u.num_deferred_open_entries = 1;
|
data->u.num_deferred_open_entries = 1;
|
||||||
|
|
||||||
DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n",
|
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;
|
data = (struct locking_data *)dbuf.dptr;
|
||||||
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
|
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);
|
traverse_callback(&shares[i], name);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -114,7 +114,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
|
|||||||
} else
|
} else
|
||||||
dbuf.dptr = tp;
|
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);
|
dbuf.dsize += sizeof(int);
|
||||||
|
|
||||||
if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
|
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.
|
* No POSIX to worry about, just close.
|
||||||
*/
|
*/
|
||||||
ret = SMB_VFS_CLOSE(fsp,fsp->fd);
|
ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
|
||||||
fsp->fd = -1;
|
fsp->fh->fd = -1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (entries[i].fd != fsp->fd) {
|
if (entries[i].fd != fsp->fh->fd) {
|
||||||
locks_on_other_fds = True;
|
locks_on_other_fds = True;
|
||||||
break;
|
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.
|
* 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)) {
|
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);
|
SAFE_FREE(entries);
|
||||||
fsp->fd = -1;
|
fsp->fh->fd = -1;
|
||||||
return 0;
|
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.
|
* 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) {
|
if (saved_errno != 0) {
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsp->fd = -1;
|
fsp->fh->fd = -1;
|
||||||
|
|
||||||
return ret;
|
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.
|
* Add new record.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pl.fd = fsp->fd;
|
pl.fd = fsp->fh->fd;
|
||||||
pl.start = start;
|
pl.start = start;
|
||||||
pl.size = size;
|
pl.size = size;
|
||||||
pl.lock_type = lock_type;
|
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++) {
|
for (i=0; i<count; i++) {
|
||||||
struct posix_lock *entry = &locks[i];
|
struct posix_lock *entry = &locks[i];
|
||||||
|
|
||||||
if (entry->fd == fsp->fd &&
|
if (entry->fd == fsp->fh->fd &&
|
||||||
entry->start == start &&
|
entry->start == start &&
|
||||||
entry->size == size) {
|
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++) {
|
for (i = 0; i < count; i++) {
|
||||||
struct posix_lock *entry = &locks[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))
|
does_lock_overlap( start, size, entry->start, entry->size))
|
||||||
num_overlapping_records++;
|
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"));
|
DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n"));
|
||||||
return F_RDLCK;
|
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.
|
* 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"));
|
DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n"));
|
||||||
return F_WRLCK;
|
return F_WRLCK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This return should be the most normal, as we attempt
|
* 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;
|
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))) {
|
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"));
|
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count &= 0x7fffffff;
|
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++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (entries[i].fd != fsp->fd )
|
if (entries[i].fd != fsp->fh->fd )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dump_entry(&entries[i]);
|
dump_entry(&entries[i]);
|
||||||
@ -1269,7 +1273,7 @@ void posix_locking_close_file(files_struct *fsp)
|
|||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
struct posix_lock *pl = &entries[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 );
|
release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size );
|
||||||
}
|
}
|
||||||
SAFE_FREE(entries);
|
SAFE_FREE(entries);
|
||||||
|
@ -605,13 +605,13 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
|
|||||||
|
|
||||||
struct afs_ace *afs_ace;
|
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. */
|
/* Get the stat struct for the owner info. */
|
||||||
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
|
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
|
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
|
||||||
return 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 */
|
/* 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",
|
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
|
||||||
fname, errno));
|
fname, errno));
|
||||||
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
|
/* 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 */
|
/* 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",
|
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
|
||||||
fname, errno));
|
fname, errno));
|
||||||
goto error_exit;
|
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. */
|
* twice, as it is simpler to read the code. */
|
||||||
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
|
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
|
||||||
/* Compute skip alignment to next long address */
|
/* 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;
|
sizeof(VS_SIGNATURE)) & 3;
|
||||||
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
|
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;
|
uint32 old_minor;
|
||||||
time_t old_create_time;
|
time_t old_create_time;
|
||||||
|
|
||||||
int access_mode;
|
|
||||||
int action;
|
|
||||||
files_struct *fsp = NULL;
|
files_struct *fsp = NULL;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT st;
|
||||||
SMB_STRUCT_STAT stat_buf;
|
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);
|
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
|
||||||
|
|
||||||
fsp = open_file_shared(conn, filepath, &stat_buf,
|
fsp = open_file_ntcreate(conn, filepath, &stat_buf,
|
||||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
FILE_GENERIC_READ,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
INTERNAL_OPEN_ONLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
/* Old file not found, so by definition new file is in fact newer */
|
/* 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",
|
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 {
|
} else {
|
||||||
int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
|
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) {
|
if (!ret) {
|
||||||
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
||||||
old_file));
|
old_file));
|
||||||
use_version = False;
|
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;
|
old_create_time = st.st_mtime;
|
||||||
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
|
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);
|
pstrcpy(filepath, new_file);
|
||||||
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
|
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
|
||||||
|
|
||||||
fsp = open_file_shared(conn, filepath, &stat_buf,
|
fsp = open_file_ntcreate(conn, filepath, &stat_buf,
|
||||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
FILE_GENERIC_READ,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
INTERNAL_OPEN_ONLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
/* New file not found, this shouldn't occur if the caller did its job */
|
/* 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",
|
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 {
|
} else {
|
||||||
int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
|
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) {
|
if (!ret) {
|
||||||
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
|
||||||
new_file));
|
new_file));
|
||||||
use_version = False;
|
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;
|
new_create_time = st.st_mtime;
|
||||||
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
|
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)
|
struct current_user *user, WERROR *perr)
|
||||||
{
|
{
|
||||||
int cversion;
|
int cversion;
|
||||||
int access_mode;
|
|
||||||
int action;
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
pstring driverpath;
|
pstring driverpath;
|
||||||
DATA_BLOB null_pw;
|
DATA_BLOB null_pw;
|
||||||
@ -1309,18 +1319,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsp = open_file_shared(conn, driverpath, &st,
|
fsp = open_file_ntcreate(conn, driverpath, &st,
|
||||||
SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
FILE_GENERIC_READ,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
INTERNAL_OPEN_ONLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
|
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
|
||||||
driverpath, errno));
|
driverpath, errno));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*perr = WERR_ACCESS_DENIED;
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32 major;
|
uint32 major;
|
||||||
uint32 minor;
|
uint32 minor;
|
||||||
int ret = get_file_version(fsp, driverpath, &major, &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);
|
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) {
|
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
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",
|
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||||
new_name, old_name));
|
new_name, old_name));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*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);
|
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) {
|
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
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",
|
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||||
new_name, old_name));
|
new_name, old_name));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*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);
|
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) {
|
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
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",
|
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||||
new_name, old_name));
|
new_name, old_name));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*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);
|
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) {
|
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
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",
|
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||||
new_name, old_name));
|
new_name, old_name));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*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]);
|
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) {
|
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||||
driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
|
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",
|
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||||
new_name, old_name));
|
new_name, old_name));
|
||||||
*perr = WERR_ACCESS_DENIED;
|
*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().
|
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;
|
int jobid;
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
@ -40,10 +40,11 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
|||||||
|
|
||||||
fstrcpy( name, "Remote Downlevel Document");
|
fstrcpy( name, "Remote Downlevel Document");
|
||||||
if (fname) {
|
if (fname) {
|
||||||
char *p = strrchr(fname, '/');
|
const char *p = strrchr(fname, '/');
|
||||||
fstrcat(name, " ");
|
fstrcat(name, " ");
|
||||||
if (!p)
|
if (!p) {
|
||||||
p = fname;
|
p = fname;
|
||||||
|
}
|
||||||
fstrcat(name, p);
|
fstrcat(name, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,24 +64,23 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup a full fsp */
|
/* 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);
|
GetTimeOfDay(&fsp->open_time);
|
||||||
fsp->vuid = current_user.vuid;
|
fsp->vuid = current_user.vuid;
|
||||||
fsp->pos = -1;
|
fsp->fh->pos = -1;
|
||||||
fsp->can_lock = True;
|
fsp->can_lock = True;
|
||||||
fsp->can_read = False;
|
fsp->can_read = False;
|
||||||
|
fsp->access_mask = FILE_GENERIC_WRITE;
|
||||||
fsp->can_write = True;
|
fsp->can_write = True;
|
||||||
fsp->share_mode = 0;
|
|
||||||
fsp->print_file = True;
|
fsp->print_file = True;
|
||||||
fsp->modified = False;
|
fsp->modified = False;
|
||||||
fsp->oplock_type = NO_OPLOCK;
|
fsp->oplock_type = NO_OPLOCK;
|
||||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||||
fsp->is_directory = False;
|
fsp->is_directory = False;
|
||||||
fsp->directory_delete_on_close = False;
|
|
||||||
string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
|
string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
|
||||||
fsp->wbmpx_ptr = NULL;
|
fsp->wbmpx_ptr = NULL;
|
||||||
fsp->wcp = 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->mode = sbuf.st_mode;
|
||||||
fsp->inode = sbuf.st_ino;
|
fsp->inode = sbuf.st_ino;
|
||||||
fsp->dev = sbuf.st_dev;
|
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)
|
void print_fsp_end(files_struct *fsp, BOOL normal_close)
|
||||||
{
|
{
|
||||||
uint32 jobid;
|
uint32 jobid;
|
||||||
fstring sharename;
|
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
|
* Truncate the job. print_job_end will take
|
||||||
* care of deleting it for us. JRA.
|
* care of deleting it for us. JRA.
|
||||||
*/
|
*/
|
||||||
sys_ftruncate(fsp->fd, 0);
|
sys_ftruncate(fsp->fh->fd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsp->fsp_name) {
|
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;
|
files_struct *fsp = NULL;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT st;
|
||||||
BOOL bad_path;
|
BOOL bad_path;
|
||||||
int access_mode;
|
|
||||||
int action;
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
struct current_user user;
|
struct current_user user;
|
||||||
connection_struct *conn = NULL;
|
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;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
fsp = open_file_stat(conn, filename, &st);
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
|
||||||
&access_mode, &action);
|
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
/* Perhaps it is a directory */
|
/* Perhaps it is a directory */
|
||||||
if (errno == EISDIR)
|
if (errno == EISDIR)
|
||||||
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
|
fsp = open_directory(conn, filename, &st,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
|
READ_CONTROL_ACCESS,
|
||||||
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
|
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;
|
files_struct *fsp = NULL;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT st;
|
||||||
BOOL bad_path;
|
BOOL bad_path;
|
||||||
int access_mode;
|
|
||||||
int action;
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
struct current_user user;
|
struct current_user user;
|
||||||
connection_struct *conn = NULL;
|
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),
|
fsp = open_file_stat(conn, filename, &st);
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
|
||||||
&access_mode, &action);
|
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
/* Perhaps it is a directory */
|
/* Perhaps it is a directory */
|
||||||
if (errno == EISDIR)
|
if (errno == EISDIR)
|
||||||
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
|
fsp = open_directory(conn, filename, &st,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
|
FILE_READ_ATTRIBUTES,
|
||||||
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
|
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
|
||||||
@ -2178,11 +2177,13 @@ error_exit:
|
|||||||
close_file(fsp, True);
|
close_file(fsp, True);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (became_user)
|
if (became_user) {
|
||||||
unbecome_user();
|
unbecome_user();
|
||||||
|
}
|
||||||
|
|
||||||
if (conn)
|
if (conn) {
|
||||||
close_cnum(conn, user.vuid);
|
close_cnum(conn, user.vuid);
|
||||||
|
}
|
||||||
|
|
||||||
return r_u->status;
|
return r_u->status;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
file closing
|
file closing
|
||||||
Copyright (C) Andrew Tridgell 1992-1998
|
Copyright (C) Andrew Tridgell 1992-1998
|
||||||
Copyright (C) Jeremy Allison 1992-2004.
|
Copyright (C) Jeremy Allison 1992-2004.
|
||||||
|
Copyright (C) Volker Lendecke 2005
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
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;
|
connection_struct *conn = fsp->conn;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (fsp->fd != -1) {
|
if (fsp->fh->fd != -1) {
|
||||||
if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
|
if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
|||||||
{
|
{
|
||||||
share_mode_entry *share_entry = NULL;
|
share_mode_entry *share_entry = NULL;
|
||||||
size_t share_entry_count = 0;
|
size_t share_entry_count = 0;
|
||||||
BOOL delete_on_close = False;
|
BOOL delete_file = False;
|
||||||
connection_struct *conn = fsp->conn;
|
connection_struct *conn = fsp->conn;
|
||||||
int saved_errno = 0;
|
int saved_errno = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@ -194,34 +195,16 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
|||||||
|
|
||||||
lock_share_entry_fsp(fsp);
|
lock_share_entry_fsp(fsp);
|
||||||
|
|
||||||
if (fsp->delete_on_close) {
|
share_entry_count = del_share_mode(fsp, &share_entry,
|
||||||
|
&delete_file);
|
||||||
/*
|
|
||||||
* Modify the share mode entry for all files open
|
|
||||||
* on this device and inode to tell other smbds we have
|
|
||||||
* changed the delete on close flag. 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);
|
|
||||||
|
|
||||||
DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
|
DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
|
||||||
(unsigned long)share_entry_count, fsp->fsp_name ));
|
(unsigned long)share_entry_count, fsp->fsp_name ));
|
||||||
|
|
||||||
/*
|
if (share_entry_count != 0) {
|
||||||
* We delete on close if it's the last open, and the
|
/* We're not the last ones -- don't delete */
|
||||||
* delete on close flag was set in the entry we just deleted.
|
delete_file = False;
|
||||||
*/
|
}
|
||||||
|
|
||||||
if ((share_entry_count == 0) && share_entry &&
|
|
||||||
GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
|
|
||||||
delete_on_close = True;
|
|
||||||
|
|
||||||
SAFE_FREE(share_entry);
|
SAFE_FREE(share_entry);
|
||||||
|
|
||||||
@ -233,7 +216,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
|||||||
* reference to a file.
|
* 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",
|
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
|
||||||
fsp->fsp_name));
|
fsp->fsp_name));
|
||||||
if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
|
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.
|
* 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);
|
BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
|
||||||
DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
|
DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
|
||||||
fsp->fsp_name, ok ? "succeeded" : "failed" ));
|
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.
|
* now fail as the directory has been deleted.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(ok)
|
if(ok) {
|
||||||
remove_pending_change_notify_requests_by_filename(fsp);
|
remove_pending_change_notify_requests_by_filename(fsp);
|
||||||
|
}
|
||||||
process_pending_change_notify_queue((time_t)0);
|
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);
|
close_filestruct(fsp);
|
||||||
|
|
||||||
if (fsp->fsp_name)
|
if (fsp->fsp_name) {
|
||||||
string_free(&fsp->fsp_name);
|
string_free(&fsp->fsp_name);
|
||||||
|
}
|
||||||
|
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -822,7 +822,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
|
|||||||
SEC_DESC *psd = NULL;
|
SEC_DESC *psd = NULL;
|
||||||
size_t sd_size;
|
size_t sd_size;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int smb_action;
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
uint32 access_granted;
|
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.
|
* we never hide files from them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (conn->admin_user)
|
if (conn->admin_user) {
|
||||||
return True;
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we can't stat it does not show it */
|
/* 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;
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pseudo-open the file (note - no fd's created). */
|
/* Pseudo-open the file (note - no fd's created). */
|
||||||
|
|
||||||
if(S_ISDIR(pst->st_mode))
|
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),
|
fsp = open_directory(conn, name, pst,
|
||||||
&smb_action);
|
READ_CONTROL_ACCESS,
|
||||||
else
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0, /* no create options. */
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
fsp = open_file_stat(conn, name, pst);
|
fsp = open_file_stat(conn, name, pst);
|
||||||
|
}
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp) {
|
||||||
return False;
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
|
/* 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);
|
(OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
|
||||||
close_file(fsp, True);
|
close_file(fsp, True);
|
||||||
|
|
||||||
/* No access if SD get failed. */
|
/* No access if SD get failed. */
|
||||||
if (!sd_size)
|
if (!sd_size) {
|
||||||
return False;
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
|
return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
|
||||||
&access_granted, &status);
|
&access_granted, &status);
|
||||||
@ -874,8 +882,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
|
|||||||
SEC_DESC *psd = NULL;
|
SEC_DESC *psd = NULL;
|
||||||
size_t sd_size;
|
size_t sd_size;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int smb_action;
|
int info;
|
||||||
int access_mode;
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
uint32 access_granted;
|
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.
|
* we never hide files from them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (conn->admin_user)
|
if (conn->admin_user) {
|
||||||
return True;
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we can't stat it does not show it */
|
/* 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;
|
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;
|
return True;
|
||||||
else
|
} else {
|
||||||
fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
|
fsp = open_file_ntcreate(conn, name, pst,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
|
FILE_WRITE_ATTRIBUTES,
|
||||||
&access_mode, &smb_action);
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
INTERNAL_OPEN_ONLY,
|
||||||
|
&info);
|
||||||
|
}
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp) {
|
||||||
return False;
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
|
/* 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);
|
(OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
|
||||||
close_file(fsp, False);
|
close_file(fsp, False);
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
|
|||||||
if (!fsp)
|
if (!fsp)
|
||||||
return -1;
|
return -1;
|
||||||
become_root();
|
become_root();
|
||||||
ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode);
|
ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode);
|
||||||
unbecome_root();
|
unbecome_root();
|
||||||
close_file_fchmod(fsp);
|
close_file_fchmod(fsp);
|
||||||
}
|
}
|
||||||
|
@ -22,77 +22,6 @@
|
|||||||
|
|
||||||
extern struct current_user current_user;
|
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[] = {
|
static FAKE_FILE fake_files[] = {
|
||||||
#ifdef WITH_QUOTAS
|
#ifdef WITH_QUOTAS
|
||||||
{FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle, destroy_quota_handle},
|
{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 }
|
{NULL, FAKE_FILE_TYPE_NONE, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
int is_fake_file(char *fname)
|
/****************************************************************************
|
||||||
{
|
Create a fake file handle
|
||||||
int i;
|
****************************************************************************/
|
||||||
|
|
||||||
if (!fname)
|
static struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
TALLOC_CTX *mem_ctx = NULL;
|
TALLOC_CTX *mem_ctx = NULL;
|
||||||
FAKE_FILE_HANDLE *fh = 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->type = type;
|
||||||
fh->mem_ctx = mem_ctx;
|
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->pd = fake_files[i].init_pd(fh->mem_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
fh->free_pd = fake_files[i].free_pd;
|
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;
|
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)
|
void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
|
||||||
{
|
{
|
||||||
if (!fh||!(*fh))
|
if (!fh||!(*fh)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*fh)->free_pd)
|
if ((*fh)->free_pd) {
|
||||||
(*fh)->free_pd(&(*fh)->pd);
|
(*fh)->free_pd(&(*fh)->pd);
|
||||||
|
}
|
||||||
|
|
||||||
talloc_destroy((*fh)->mem_ctx);
|
talloc_destroy((*fh)->mem_ctx);
|
||||||
(*fh) = NULL;
|
(*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)) {
|
if(read_from_write_cache(fsp, data, pos, n)) {
|
||||||
fsp->pos = pos + n;
|
fsp->fh->pos = pos + n;
|
||||||
fsp->position_information = fsp->pos;
|
fsp->fh->position_information = fsp->fh->pos;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_write_cache(fsp, READ_FLUSH);
|
flush_write_cache(fsp, READ_FLUSH);
|
||||||
|
|
||||||
fsp->pos = pos;
|
fsp->fh->pos = pos;
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
#ifdef DMF_FIX
|
#ifdef DMF_FIX
|
||||||
int numretries = 3;
|
int numretries = 3;
|
||||||
tryagain:
|
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 (readret == -1) {
|
||||||
if ((errno == EAGAIN) && numretries) {
|
if ((errno == EAGAIN) && numretries) {
|
||||||
@ -90,7 +90,7 @@ tryagain:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else /* NO DMF fix. */
|
#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) {
|
if (readret == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -104,8 +104,8 @@ tryagain:
|
|||||||
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
|
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
|
||||||
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
|
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
|
||||||
|
|
||||||
fsp->pos += ret;
|
fsp->fh->pos += ret;
|
||||||
fsp->position_information = fsp->pos;
|
fsp->fh->position_information = fsp->fh->pos;
|
||||||
|
|
||||||
return(ret);
|
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) {
|
if (pos == -1) {
|
||||||
ret = vfs_write_data(fsp, data, n);
|
ret = vfs_write_data(fsp, data, n);
|
||||||
} else {
|
} else {
|
||||||
fsp->pos = pos;
|
fsp->fh->pos = pos;
|
||||||
if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
|
if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
|
||||||
if (vfs_fill_sparse(fsp, pos) == -1) {
|
if (vfs_fill_sparse(fsp, pos) == -1) {
|
||||||
return -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 ));
|
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
|
||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
fsp->pos += ret;
|
fsp->fh->pos += ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It turns out that setting the last write time from a Windows
|
* 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;
|
write_cache *wcp = fsp->wcp;
|
||||||
|
|
||||||
wcp->file_size = wcp->offset + wcp->data_size;
|
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) {
|
if (ret == -1) {
|
||||||
DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
|
DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
|
||||||
fsp->fsp_name, (double)wcp->file_size, strerror(errno) ));
|
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;
|
SMB_STRUCT_STAT st;
|
||||||
fsp->modified = True;
|
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);
|
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)) {
|
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);
|
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",
|
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.
|
* 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 \
|
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
|
* 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) &&
|
if ((pos <= wcp->offset) &&
|
||||||
(pos + n >= wcp->offset + wcp->data_size) ) {
|
(pos + n >= wcp->offset + wcp->data_size) ) {
|
||||||
DEBUG(9,("write_file: discarding overwritten write \
|
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;
|
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) {
|
if (cache_flush_needed) {
|
||||||
DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
|
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",
|
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 ));
|
(double)wcp->offset, (unsigned int)wcp->data_size ));
|
||||||
|
|
||||||
flush_write_cache(fsp, WRITE_FLUSH);
|
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]);
|
DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]);
|
||||||
|
|
||||||
DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
|
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
|
#ifdef WITH_PROFILE
|
||||||
if(data_size == wcp->alloc_size) {
|
if(data_size == wcp->alloc_size) {
|
||||||
@ -836,9 +836,9 @@ sync a file
|
|||||||
|
|
||||||
void sync_file(connection_struct *conn, files_struct *fsp)
|
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);
|
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)
|
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);
|
return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst);
|
||||||
} else {
|
} 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);
|
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->conn = conn;
|
||||||
fsp->file_id = get_gen_count();
|
fsp->file_id = get_gen_count();
|
||||||
GetTimeOfDay(&fsp->open_time);
|
GetTimeOfDay(&fsp->open_time);
|
||||||
@ -233,7 +245,7 @@ void file_dump_open_table(void)
|
|||||||
|
|
||||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
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",
|
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 ));
|
(unsigned int)fsp->dev, (double)fsp->inode ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +260,7 @@ files_struct *file_find_fd(int fd)
|
|||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
|
||||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
||||||
if (fsp->fd == fd) {
|
if (fsp->fh->fd == fd) {
|
||||||
if (count > 10) {
|
if (count > 10) {
|
||||||
DLIST_PROMOTE(Files, fsp);
|
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;
|
files_struct *fsp;
|
||||||
|
|
||||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
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 &&
|
if (fsp->dev == dev &&
|
||||||
fsp->inode == inode &&
|
fsp->inode == inode &&
|
||||||
fsp->file_id == file_id ) {
|
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);
|
DLIST_PROMOTE(Files, fsp);
|
||||||
}
|
}
|
||||||
/* Paranoia check. */
|
/* 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 \
|
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,
|
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,
|
(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;
|
fsp_fi_cache.inode = inode;
|
||||||
|
|
||||||
for (fsp=Files;fsp;fsp=fsp->next) {
|
for (fsp=Files;fsp;fsp=fsp->next) {
|
||||||
if ( fsp->fd != -1 &&
|
if ( fsp->fh->fd != -1 &&
|
||||||
fsp->dev == dev &&
|
fsp->dev == dev &&
|
||||||
fsp->inode == inode ) {
|
fsp->inode == inode ) {
|
||||||
/* Setup positive cache. */
|
/* Setup positive cache. */
|
||||||
@ -349,7 +361,7 @@ files_struct *file_find_di_next(files_struct *start_fsp)
|
|||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
|
||||||
for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
|
for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
|
||||||
if ( fsp->fd != -1 &&
|
if ( fsp->fh->fd != -1 &&
|
||||||
fsp->dev == start_fsp->dev &&
|
fsp->dev == start_fsp->dev &&
|
||||||
fsp->inode == start_fsp->inode )
|
fsp->inode == start_fsp->inode )
|
||||||
return fsp;
|
return fsp;
|
||||||
@ -389,7 +401,7 @@ void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (fsp = Files;fsp;fsp=fsp->next) {
|
for (fsp = Files;fsp;fsp=fsp->next) {
|
||||||
if ( fsp->fd != -1 &&
|
if ( fsp->fh->fd != -1 &&
|
||||||
fsp->dev == tfsp->dev &&
|
fsp->dev == tfsp->dev &&
|
||||||
fsp->inode == tfsp->inode ) {
|
fsp->inode == tfsp->inode ) {
|
||||||
fsp->pending_modtime = pmod;
|
fsp->pending_modtime = pmod;
|
||||||
@ -410,7 +422,7 @@ void file_sync_all(connection_struct *conn)
|
|||||||
|
|
||||||
for (fsp=Files;fsp;fsp=next) {
|
for (fsp=Files;fsp;fsp=next) {
|
||||||
next=fsp->next;
|
next=fsp->next;
|
||||||
if ((conn == fsp->conn) && (fsp->fd != -1)) {
|
if ((conn == fsp->conn) && (fsp->fh->fd != -1)) {
|
||||||
sync_file(conn,fsp);
|
sync_file(conn,fsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,6 +442,12 @@ void file_free(files_struct *fsp)
|
|||||||
destroy_fake_file_handle(&fsp->fake_file_handle);
|
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);
|
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
|
||||||
files_used--;
|
files_used--;
|
||||||
|
|
||||||
@ -506,3 +524,49 @@ void file_chain_restore(void)
|
|||||||
{
|
{
|
||||||
chain_fsp = oplock_save_chain_fsp;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
1916
source/smbd/open.c
1916
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;
|
SMB_INO_T inode;
|
||||||
unsigned long file_id;
|
unsigned long file_id;
|
||||||
uint16 break_cmd_type;
|
uint16 break_cmd_type;
|
||||||
|
struct sockaddr_in toaddr;
|
||||||
|
|
||||||
msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
|
msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
|
||||||
from_port = SVAL(buffer,OPBRK_CMD_PORT_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)) {
|
if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev, &file_id)) {
|
||||||
DEBUG(0,("kernel oplock break parse failure!\n"));
|
DEBUG(0,("kernel oplock break parse failure!\n"));
|
||||||
|
return False;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -449,49 +451,54 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
|
|||||||
* Now actually process the break request.
|
* Now actually process the break request.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if((exclusive_oplocks_open + level_II_oplocks_open) != 0) {
|
if ((exclusive_oplocks_open == 0) &&
|
||||||
if (oplock_break(dev, inode, file_id, False) == False) {
|
(level_II_oplocks_open == 0)) {
|
||||||
DEBUG(0,("process_local_message: oplock break failed.\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* If we have no record of any currently open oplocks,
|
* If we have no record of any currently open oplocks,
|
||||||
* it's not an error, as a close command may have
|
* it's not an error, as a close command may have
|
||||||
* just been issued on the file that was oplocked.
|
* just been issued on the file that was oplocked.
|
||||||
* Just log a message and return success in this case.
|
* Just log a message and return success in this case.
|
||||||
*/
|
*/
|
||||||
DEBUG(3,("process_local_message: oplock break requested with no outstanding \
|
DEBUG(3,("process_local_message: oplock break requested with "
|
||||||
oplocks. Returning success.\n"));
|
"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) {
|
if (!((break_cmd_type == OPLOCK_BREAK_CMD) ||
|
||||||
struct sockaddr_in toaddr;
|
(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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
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));
|
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. */
|
/* Try and break the oplock. */
|
||||||
if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) {
|
if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) {
|
||||||
if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */
|
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();
|
pid_t pid = sys_getpid();
|
||||||
int num_share_modes = 0;
|
int num_share_modes = 0;
|
||||||
int i;
|
int i;
|
||||||
|
BOOL dummy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this file is level II oplocked then we need
|
* 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 ));
|
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",
|
DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
|
||||||
num_share_modes ));
|
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)
|
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, \
|
DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
|
||||||
inode = %.0f. (%s)\n",
|
inode = %.0f. (%s)\n",
|
||||||
fsp->fsp_name, fsp->fd,
|
fsp->fsp_name, fsp->fh->fd,
|
||||||
(unsigned int)fsp->dev, (double)fsp->inode, strerror(errno)));
|
(unsigned int)fsp->dev, (double)fsp->inode, strerror(errno)));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ static void linux_release_kernel_oplock(files_struct *fsp)
|
|||||||
* Check and print out the current kernel
|
* Check and print out the current kernel
|
||||||
* oplock state of this file.
|
* 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 \
|
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,
|
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
|
||||||
(double)fsp->inode, fsp->file_id, state );
|
(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.
|
* 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)) {
|
if (DEBUGLVL(0)) {
|
||||||
dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " );
|
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",
|
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) Andrew Tridgell 1992-1998
|
||||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
|
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
|
||||||
Copyright (C) Paul Ashton 1997-1998.
|
Copyright (C) Paul Ashton 1997-1998.
|
||||||
|
Copyright (C) Jeremy Allison 2005.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -33,11 +34,11 @@
|
|||||||
extern struct pipe_id_info pipe_names[];
|
extern struct pipe_id_info pipe_names[];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
reply to an open and X on a named pipe
|
Reply to an open and X on a named pipe.
|
||||||
|
This code is basically stolen from reply_open_and_X with some
|
||||||
This code is basically stolen from reply_open_and_X with some
|
wrinkles to handle pipes.
|
||||||
wrinkles to handle pipes.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int reply_open_pipe_and_X(connection_struct *conn,
|
int reply_open_pipe_and_X(connection_struct *conn,
|
||||||
char *inbuf,char *outbuf,int length,int bufsize)
|
char *inbuf,char *outbuf,int length,int bufsize)
|
||||||
{
|
{
|
||||||
@ -45,7 +46,6 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
|||||||
pstring pipe_name;
|
pstring pipe_name;
|
||||||
uint16 vuid = SVAL(inbuf, smb_uid);
|
uint16 vuid = SVAL(inbuf, smb_uid);
|
||||||
smb_np_struct *p;
|
smb_np_struct *p;
|
||||||
int smb_ofun = SVAL(inbuf,smb_vwv8);
|
|
||||||
int size=0,fmode=0,mtime=0,rmode=0;
|
int size=0,fmode=0,mtime=0,rmode=0;
|
||||||
int i;
|
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 */
|
/* If the name doesn't start \PIPE\ then this is directed */
|
||||||
/* at a mailslot or something we really, really don't understand, */
|
/* at a mailslot or something we really, really don't understand, */
|
||||||
/* not just something we 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));
|
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(4,("Opening pipe %s.\n", pipe_name));
|
DEBUG(4,("Opening pipe %s.\n", pipe_name));
|
||||||
|
|
||||||
/* See if it is one we want to handle. */
|
/* See if it is one we want to handle. */
|
||||||
for( i = 0; pipe_names[i].client_pipe ; i++ )
|
for( i = 0; pipe_names[i].client_pipe ; i++ ) {
|
||||||
if( strequal(pipe_name,pipe_names[i].client_pipe) )
|
if( strequal(pipe_name,pipe_names[i].client_pipe)) {
|
||||||
break;
|
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));
|
return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
|
||||||
|
}
|
||||||
|
|
||||||
/* Strip \PIPE\ off the name. */
|
/* Strip \PIPE\ off the name. */
|
||||||
pstrcpy(fname, pipe_name + PIPELEN);
|
pstrcpy(fname, pipe_name + PIPELEN);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Hack for NT printers... JRA.
|
* 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 */
|
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
|
||||||
/* can be opened and add it in after the open. */
|
/* can be opened and add it in after the open. */
|
||||||
DEBUG(3,("Known pipe %s opening.\n",fname));
|
DEBUG(3,("Known pipe %s opening.\n",fname));
|
||||||
smb_ofun |= FILE_CREATE_IF_NOT_EXIST;
|
|
||||||
|
|
||||||
p = open_rpc_pipe_p(fname, conn, vuid);
|
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 */
|
/* Prepare the reply */
|
||||||
set_message(outbuf,15,0,True);
|
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)
|
int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
|
||||||
{
|
{
|
||||||
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
|
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;
|
int outsize;
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||||
|
}
|
||||||
|
|
||||||
data = smb_buf(inbuf) + 3;
|
data = smb_buf(inbuf) + 3;
|
||||||
|
|
||||||
if (numtowrite == 0)
|
if (numtowrite == 0) {
|
||||||
nwritten = 0;
|
nwritten = 0;
|
||||||
else
|
} else {
|
||||||
nwritten = write_to_pipe(p, data, numtowrite);
|
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));
|
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
|
}
|
||||||
|
|
||||||
outsize = set_message(outbuf,1,0,True);
|
outsize = set_message(outbuf,1,0,True);
|
||||||
|
|
||||||
SSVAL(outbuf,smb_vwv0,nwritten);
|
SSVAL(outbuf,smb_vwv0,nwritten);
|
||||||
|
|
||||||
DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
|
DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
|
||||||
p->pnum, nwritten));
|
|
||||||
|
|
||||||
return(outsize);
|
return(outsize);
|
||||||
}
|
}
|
||||||
@ -158,24 +165,25 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
|||||||
int nwritten = -1;
|
int nwritten = -1;
|
||||||
int smb_doff = SVAL(inbuf, smb_vwv11);
|
int smb_doff = SVAL(inbuf, smb_vwv11);
|
||||||
BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) ==
|
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;
|
char *data;
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||||
|
}
|
||||||
|
|
||||||
data = smb_base(inbuf) + smb_doff;
|
data = smb_base(inbuf) + smb_doff;
|
||||||
|
|
||||||
if (numtowrite == 0)
|
if (numtowrite == 0) {
|
||||||
nwritten = 0;
|
nwritten = 0;
|
||||||
else {
|
} else {
|
||||||
if(pipe_start_message_raw) {
|
if(pipe_start_message_raw) {
|
||||||
/*
|
/*
|
||||||
* For the start of a message in named pipe byte mode,
|
* For the start of a message in named pipe byte mode,
|
||||||
* the first two bytes are a length-of-pdu field. Ignore
|
* 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",
|
DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n",
|
||||||
(unsigned int)numtowrite ));
|
(unsigned int)numtowrite ));
|
||||||
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
@ -183,30 +191,30 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
|||||||
|
|
||||||
data += 2;
|
data += 2;
|
||||||
numtowrite -= 2;
|
numtowrite -= 2;
|
||||||
}
|
}
|
||||||
nwritten = write_to_pipe(p, data, numtowrite);
|
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));
|
return (UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
|
}
|
||||||
|
|
||||||
set_message(outbuf,6,0,True);
|
set_message(outbuf,6,0,True);
|
||||||
|
|
||||||
nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
|
nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
|
||||||
SSVAL(outbuf,smb_vwv2,nwritten);
|
SSVAL(outbuf,smb_vwv2,nwritten);
|
||||||
|
|
||||||
DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n",
|
DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
|
||||||
p->pnum, nwritten));
|
|
||||||
|
|
||||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
reply to a read and X
|
Reply to a read and X.
|
||||||
|
This code is basically stolen from reply_read_and_X with some
|
||||||
This code is basically stolen from reply_read_and_X with some
|
wrinkles to handle pipes.
|
||||||
wrinkles to handle pipes.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
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);
|
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);
|
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||||
|
}
|
||||||
|
|
||||||
set_message(outbuf,12,0,True);
|
set_message(outbuf,12,0,True);
|
||||||
data = smb_buf(outbuf);
|
data = smb_buf(outbuf);
|
||||||
|
|
||||||
nread = read_from_pipe(p, data, smb_maxcnt, &unused);
|
nread = read_from_pipe(p, data, smb_maxcnt, &unused);
|
||||||
|
|
||||||
if (nread < 0)
|
if (nread < 0) {
|
||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
|
}
|
||||||
|
|
||||||
SSVAL(outbuf,smb_vwv5,nread);
|
SSVAL(outbuf,smb_vwv5,nread);
|
||||||
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
|
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)
|
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
|
||||||
{
|
{
|
||||||
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
|
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
|
||||||
int outsize = set_message(outbuf,0,0,True);
|
int outsize = set_message(outbuf,0,0,True);
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
return(ERROR_DOS(ERRDOS,ERRbadfid));
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
|
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 ERROR_DOS(ERRDOS,ERRbadfid);
|
||||||
|
}
|
||||||
|
|
||||||
return(outsize);
|
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) {
|
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. */
|
/* Instead just remove the attribute if it exists. */
|
||||||
if (fsp->fd != -1)
|
if (fsp->fh->fd != -1)
|
||||||
SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
||||||
else
|
else
|
||||||
SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
|
||||||
return;
|
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);
|
pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size);
|
||||||
|
|
||||||
if (fsp->fd != -1)
|
if (fsp->fh->fd != -1)
|
||||||
ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||||
pai_buf, store_size, 0);
|
pai_buf, store_size, 0);
|
||||||
else
|
else
|
||||||
ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
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;
|
return NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (fsp->fd != -1)
|
if (fsp->fh->fd != -1)
|
||||||
ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
ret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
|
||||||
pai_buf, pai_buf_size);
|
pai_buf, pai_buf_size);
|
||||||
else
|
else
|
||||||
ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
|
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.
|
* 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) {
|
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
|
* 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;
|
goto done;
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
* 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.
|
* 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 ));
|
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. */
|
/* Get the stat struct for the owner info. */
|
||||||
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
|
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 {
|
} else {
|
||||||
|
|
||||||
/* Get the stat struct for the owner info. */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Get the ACL from the fd.
|
* 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",
|
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();
|
become_root();
|
||||||
/* Keep the current file gid the same. */
|
/* 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();
|
unbecome_root();
|
||||||
|
|
||||||
close_file_fchmod(fsp);
|
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.
|
* 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)
|
if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
|
||||||
return False;
|
return False;
|
||||||
} else {
|
} else {
|
||||||
if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0)
|
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0)
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3081,10 +3081,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
|
|||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(fsp->fd == -1)
|
if(fsp->fh->fd == -1)
|
||||||
ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
|
ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
|
||||||
else
|
else
|
||||||
ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf);
|
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);
|
||||||
|
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return False;
|
return False;
|
||||||
@ -3683,8 +3683,8 @@ static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the current file ACL. */
|
/* Get the current file ACL. */
|
||||||
if (fsp && fsp->fd != -1) {
|
if (fsp && fsp->fh->fd != -1) {
|
||||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
|
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
|
||||||
} else {
|
} else {
|
||||||
file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
|
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;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsp && fsp->fd != -1) {
|
if (fsp && fsp->fh->fd != -1) {
|
||||||
/* The preferred way - use an open fd. */
|
/* 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",
|
DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
|
||||||
fname, strerror(errno) ));
|
fname, strerror(errno) ));
|
||||||
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
|
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;
|
pstring fname;
|
||||||
int outsize = 0;
|
int outsize = 0;
|
||||||
int fmode=0;
|
uint32 fattr=0;
|
||||||
int share_mode;
|
|
||||||
SMB_OFF_T size = 0;
|
SMB_OFF_T size = 0;
|
||||||
time_t mtime=0;
|
time_t mtime=0;
|
||||||
int rmode=0;
|
int info;
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
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;
|
NTSTATUS status;
|
||||||
START_PROFILE(SMBopen);
|
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);
|
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
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);
|
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),
|
if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
|
||||||
(uint32)dos_attr, oplock_request,&rmode,NULL);
|
&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) {
|
if (!fsp) {
|
||||||
END_PROFILE(SMBopen);
|
END_PROFILE(SMBopen);
|
||||||
@ -1317,10 +1333,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
size = sbuf.st_size;
|
size = sbuf.st_size;
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fattr = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
|
|
||||||
if (fmode & aDIR) {
|
if (fattr & aDIR) {
|
||||||
DEBUG(3,("attempt to open a directory %s\n",fname));
|
DEBUG(3,("attempt to open a directory %s\n",fname));
|
||||||
close_file(fsp,False);
|
close_file(fsp,False);
|
||||||
END_PROFILE(SMBopen);
|
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);
|
outsize = set_message(outbuf,7,0,True);
|
||||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
||||||
SSVAL(outbuf,smb_vwv1,fmode);
|
SSVAL(outbuf,smb_vwv1,fattr);
|
||||||
if(lp_dos_filetime_resolution(SNUM(conn)) )
|
if(lp_dos_filetime_resolution(SNUM(conn)) ) {
|
||||||
put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
|
put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
|
||||||
else
|
} else {
|
||||||
put_dos_date3(outbuf,smb_vwv2,mtime);
|
put_dos_date3(outbuf,smb_vwv2,mtime);
|
||||||
|
}
|
||||||
SIVAL(outbuf,smb_vwv4,(uint32)size);
|
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);
|
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);
|
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||||
|
}
|
||||||
END_PROFILE(SMBopen);
|
END_PROFILE(SMBopen);
|
||||||
return(outsize);
|
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)
|
int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
|
||||||
{
|
{
|
||||||
pstring fname;
|
pstring fname;
|
||||||
int smb_mode = SVAL(inbuf,smb_vwv3);
|
uint16 open_flags = SVAL(inbuf,smb_vwv2);
|
||||||
int smb_attr = SVAL(inbuf,smb_vwv5);
|
int deny_mode = SVAL(inbuf,smb_vwv3);
|
||||||
|
uint32 smb_attr = SVAL(inbuf,smb_vwv5);
|
||||||
/* Breakout the oplock request bits so we can set the
|
/* Breakout the oplock request bits so we can set the
|
||||||
reply bits separately. */
|
reply bits separately. */
|
||||||
BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
|
BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
|
||||||
BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||||
BOOL oplock_request = ex_oplock_request | core_oplock_request;
|
BOOL oplock_request = ex_oplock_request | core_oplock_request;
|
||||||
#if 0
|
#if 0
|
||||||
int open_flags = SVAL(inbuf,smb_vwv2);
|
|
||||||
int smb_sattr = SVAL(inbuf,smb_vwv4);
|
int smb_sattr = SVAL(inbuf,smb_vwv4);
|
||||||
uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
|
uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
|
||||||
#endif
|
#endif
|
||||||
int smb_ofun = SVAL(inbuf,smb_vwv8);
|
int smb_ofun = SVAL(inbuf,smb_vwv8);
|
||||||
SMB_OFF_T size=0;
|
SMB_OFF_T size=0;
|
||||||
int fmode=0,mtime=0,rmode=0;
|
uint32 fattr=0;
|
||||||
|
int mtime=0;
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
int smb_action = 0;
|
int smb_action = 0;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
@ -1375,6 +1395,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
|
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
|
||||||
ssize_t retval = -1;
|
ssize_t retval = -1;
|
||||||
|
uint32 access_mask;
|
||||||
|
uint32 share_mode;
|
||||||
|
uint32 create_disposition;
|
||||||
|
uint32 create_options = 0;
|
||||||
|
|
||||||
START_PROFILE(SMBopenX);
|
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);
|
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strange open mode mapping. */
|
if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
|
||||||
if (smb_ofun == 0) {
|
&access_mask,
|
||||||
if (GET_OPEN_MODE(smb_mode) == DOS_OPEN_EXEC) {
|
&share_mode,
|
||||||
smb_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
|
&create_disposition,
|
||||||
} else {
|
&create_options)) {
|
||||||
END_PROFILE(SMBopenX);
|
END_PROFILE(SMBopenX);
|
||||||
return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
|
return ERROR_DOS(ERRDOS, ERRbadaccess);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
|
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||||
oplock_request, &rmode,&smb_action);
|
access_mask,
|
||||||
|
share_mode,
|
||||||
|
create_disposition,
|
||||||
|
create_options,
|
||||||
|
smb_attr,
|
||||||
|
oplock_request,
|
||||||
|
&smb_action);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
END_PROFILE(SMBopenX);
|
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);
|
size = get_allocation_size(conn,fsp,&sbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fattr = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
if (fmode & aDIR) {
|
if (fattr & aDIR) {
|
||||||
close_file(fsp,False);
|
close_file(fsp,False);
|
||||||
END_PROFILE(SMBopenX);
|
END_PROFILE(SMBopenX);
|
||||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
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.
|
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;
|
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;
|
smb_action |= EXTENDED_OPLOCK_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the caller set the core oplock request bit
|
/* If the caller set the core oplock request bit
|
||||||
and we granted one (by whatever means) - set the
|
and we granted one (by whatever means) - set the
|
||||||
correct bit for core oplock reply.
|
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);
|
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);
|
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_vwv2,fsp->fnum);
|
||||||
SSVAL(outbuf,smb_vwv3,fmode);
|
SSVAL(outbuf,smb_vwv3,fattr);
|
||||||
if(lp_dos_filetime_resolution(SNUM(conn)) )
|
if(lp_dos_filetime_resolution(SNUM(conn)) ) {
|
||||||
put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
|
put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
|
||||||
else
|
} else {
|
||||||
put_dos_date3(outbuf,smb_vwv4,mtime);
|
put_dos_date3(outbuf,smb_vwv4,mtime);
|
||||||
|
}
|
||||||
SIVAL(outbuf,smb_vwv6,(uint32)size);
|
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);
|
SSVAL(outbuf,smb_vwv11,smb_action);
|
||||||
|
|
||||||
|
if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
|
||||||
|
SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
|
||||||
|
}
|
||||||
|
|
||||||
END_PROFILE(SMBopenX);
|
END_PROFILE(SMBopenX);
|
||||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
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;
|
pstring fname;
|
||||||
int com;
|
int com;
|
||||||
int outsize = 0;
|
int outsize = 0;
|
||||||
int createmode;
|
uint32 fattr = SVAL(inbuf,smb_vwv0);
|
||||||
int ofun = 0;
|
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
NTSTATUS status;
|
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);
|
START_PROFILE(SMBcreate);
|
||||||
|
|
||||||
com = SVAL(inbuf,smb_com);
|
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);
|
srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
END_PROFILE(SMBcreate);
|
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);
|
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));
|
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
|
||||||
|
}
|
||||||
|
|
||||||
if(com == SMBmknew) {
|
if(com == SMBmknew) {
|
||||||
/* We should fail if file exists. */
|
/* We should fail if file exists. */
|
||||||
ofun = FILE_CREATE_IF_NOT_EXIST;
|
create_disposition = FILE_CREATE;
|
||||||
} else {
|
} else {
|
||||||
/* SMBcreate - Create if file doesn't exist, truncate if it does. */
|
/* Create if file doesn't exist, truncate if it does. */
|
||||||
ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
|
create_disposition = FILE_OPEN_IF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open file in dos compatibility share mode. */
|
/* Open file using ntcreate. */
|
||||||
fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||||
ofun, (uint32)createmode, oplock_request, NULL, NULL);
|
access_mask,
|
||||||
|
share_mode,
|
||||||
|
create_disposition,
|
||||||
|
create_options,
|
||||||
|
fattr,
|
||||||
|
oplock_request,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
END_PROFILE(SMBcreate);
|
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);
|
outsize = set_message(outbuf,1,0,True);
|
||||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
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);
|
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);
|
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG( 2, ( "new file %s\n", fname ) );
|
DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
|
||||||
DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
|
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) );
|
||||||
|
|
||||||
END_PROFILE(SMBcreate);
|
END_PROFILE(SMBcreate);
|
||||||
return(outsize);
|
return(outsize);
|
||||||
@ -1602,7 +1656,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
{
|
{
|
||||||
pstring fname;
|
pstring fname;
|
||||||
int outsize = 0;
|
int outsize = 0;
|
||||||
int createattr;
|
uint32 fattr = SVAL(inbuf,smb_vwv0);
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
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);
|
START_PROFILE(SMBctemp);
|
||||||
|
|
||||||
createattr = SVAL(inbuf,smb_vwv0);
|
|
||||||
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
END_PROFILE(SMBctemp);
|
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);
|
SMB_VFS_STAT(conn,fname,&sbuf);
|
||||||
|
|
||||||
/* Open file in dos compatibility share mode. */
|
|
||||||
/* We should fail if file does not exist. */
|
/* We should fail if file does not exist. */
|
||||||
fsp = open_file_shared(conn,fname,&sbuf,
|
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||||
SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||||
FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
(uint32)createattr, oplock_request, NULL, NULL);
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
fattr,
|
||||||
|
oplock_request,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* close fd from smb_mkstemp() */
|
/* close fd from smb_mkstemp() */
|
||||||
close(tmpfd);
|
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 */
|
/* the returned filename is relative to the directory */
|
||||||
s = strrchr_m(fname, '/');
|
s = strrchr_m(fname, '/');
|
||||||
if (!s)
|
if (!s) {
|
||||||
s = fname;
|
s = fname;
|
||||||
else
|
} else {
|
||||||
s++;
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
p = smb_buf(outbuf);
|
p = smb_buf(outbuf);
|
||||||
#if 0
|
#if 0
|
||||||
@ -1681,15 +1738,17 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
p += namelen;
|
p += namelen;
|
||||||
outsize = set_message_end(outbuf, p);
|
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);
|
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);
|
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG( 2, ( "created temp file %s\n", fname ) );
|
DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
|
||||||
DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
|
DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
|
||||||
fname, fsp->fd, sbuf.st_mode ) );
|
(unsigned int)sbuf.st_mode ) );
|
||||||
|
|
||||||
END_PROFILE(SMBctemp);
|
END_PROFILE(SMBctemp);
|
||||||
return(outsize);
|
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)
|
static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, SMB_STRUCT_STAT *pst)
|
||||||
{
|
{
|
||||||
int smb_action;
|
|
||||||
int access_mode;
|
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
uint16 fmode;
|
uint32 fmode;
|
||||||
|
|
||||||
if (!CAN_WRITE(conn))
|
if (!CAN_WRITE(conn)) {
|
||||||
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
fmode = dos_mode(conn,fname,pst);
|
fmode = dos_mode(conn,fname,pst);
|
||||||
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
|
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
|
||||||
return NT_STATUS_NO_SUCH_FILE;
|
return NT_STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
if (S_ISDIR(pst->st_mode))
|
if (S_ISDIR(pst->st_mode)) {
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need a better way to return NT status codes from open... */
|
/* We need a better way to return NT status codes from open... */
|
||||||
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
||||||
|
|
||||||
fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
|
fsp = open_file_ntcreate(conn, fname, pst,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
|
DELETE_ACCESS,
|
||||||
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
NTSTATUS ret;
|
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)
|
NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open)
|
||||||
{
|
{
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
uint32 fmode;
|
uint32 fattr;
|
||||||
int smb_action;
|
|
||||||
int access_mode;
|
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
|
|
||||||
DEBUG(10,("can_delete: %s, dirtype = %d\n",
|
DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype ));
|
||||||
fname, dirtype ));
|
|
||||||
|
|
||||||
if (!CAN_WRITE(conn))
|
if (!CAN_WRITE(conn)) {
|
||||||
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
|
if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
|
||||||
if(errno == ENOENT) {
|
if(errno == ENOENT) {
|
||||||
if (bad_path)
|
if (bad_path) {
|
||||||
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
else
|
} else {
|
||||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return map_nt_error_from_unix(errno);
|
return map_nt_error_from_unix(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fattr = dos_mode(conn,fname,&sbuf);
|
||||||
|
|
||||||
/* Can't delete a directory. */
|
/* Can't delete a directory. */
|
||||||
if (fmode & aDIR)
|
if (fattr & aDIR) {
|
||||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* JRATEST */
|
#if 0 /* JRATEST */
|
||||||
else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
|
else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
|
||||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||||
#endif /* JRATEST */
|
#endif /* JRATEST */
|
||||||
|
|
||||||
if (!lp_delete_readonly(SNUM(conn))) {
|
if (!lp_delete_readonly(SNUM(conn))) {
|
||||||
if (fmode & aRONLY)
|
if (fattr & aRONLY) {
|
||||||
return NT_STATUS_CANNOT_DELETE;
|
return NT_STATUS_CANNOT_DELETE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
|
if ((fattr & ~dirtype) & (aHIDDEN | aSYSTEM)) {
|
||||||
return NT_STATUS_NO_SUCH_FILE;
|
return NT_STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
if (check_is_at_open) {
|
if (check_is_at_open) {
|
||||||
if (!can_delete_file_in_directory(conn, fname)) {
|
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... */
|
/* We need a better way to return NT status codes from open... */
|
||||||
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
set_saved_error_triple(0, 0, NT_STATUS_OK);
|
||||||
|
|
||||||
fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
|
fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
|
DELETE_ACCESS,
|
||||||
|
FILE_SHARE_NONE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
@ -2058,7 +2133,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
|
|||||||
header.length = 4;
|
header.length = 4;
|
||||||
header.free = NULL;
|
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. */
|
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
|
||||||
if (errno == ENOSYS) {
|
if (errno == ENOSYS) {
|
||||||
goto normal_readbraw;
|
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_STRUCT_STAT st;
|
||||||
SMB_OFF_T size = 0;
|
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;
|
size = st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2251,7 +2326,9 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
|
|||||||
START_PROFILE(SMBlockread);
|
START_PROFILE(SMBlockread);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_READ(fsp);
|
if (!CHECK_READ(fsp,inbuf)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
release_level_2_oplocks_on_change(fsp);
|
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);
|
START_PROFILE(SMBread);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_READ(fsp);
|
if (!CHECK_READ(fsp,inbuf)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
numtoread = SVAL(inbuf,smb_vwv1);
|
numtoread = SVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
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;
|
SMB_STRUCT_STAT sbuf;
|
||||||
DATA_BLOB header;
|
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));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
|
|
||||||
if (startpos > sbuf.st_size)
|
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.length = data - outbuf;
|
||||||
header.free = NULL;
|
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. */
|
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
|
||||||
if (errno == ENOSYS) {
|
if (errno == ENOSYS) {
|
||||||
goto normal_read;
|
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_FSP(fsp,conn);
|
||||||
CHECK_READ(fsp);
|
if (!CHECK_READ(fsp,inbuf)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
set_message(outbuf,12,0,True);
|
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_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
tcount = IVAL(inbuf,smb_vwv1);
|
tcount = IVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
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);
|
START_PROFILE(SMBwriteunlock);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
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
|
/* The special X/Open SMB protocol handling of
|
||||||
zero length writes is *NOT* done for
|
zero length writes is *NOT* done for
|
||||||
this call */
|
this call */
|
||||||
if(numtowrite == 0)
|
if(numtowrite == 0) {
|
||||||
nwritten = 0;
|
nwritten = 0;
|
||||||
else
|
} else {
|
||||||
nwritten = write_file(fsp,data,startpos,numtowrite);
|
nwritten = write_file(fsp,data,startpos,numtowrite);
|
||||||
|
}
|
||||||
|
|
||||||
if (lp_syncalways(SNUM(conn)))
|
if (lp_syncalways(SNUM(conn)))
|
||||||
sync_file(conn,fsp);
|
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_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
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_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
set_message(outbuf,6,0,True);
|
set_message(outbuf,6,0,True);
|
||||||
|
|
||||||
@ -3010,7 +3100,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
umode = SEEK_CUR;
|
umode = SEEK_CUR;
|
||||||
res = fsp->pos + startpos;
|
res = fsp->fh->pos + startpos;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
umode = SEEK_END;
|
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 (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) {
|
if(errno == EINVAL) {
|
||||||
SMB_OFF_T current_pos = startpos;
|
SMB_OFF_T current_pos = startpos;
|
||||||
SMB_STRUCT_STAT sbuf;
|
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);
|
END_PROFILE(SMBlseek);
|
||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
current_pos += sbuf.st_size;
|
current_pos += sbuf.st_size;
|
||||||
if(current_pos < 0)
|
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);
|
outsize = set_message(outbuf,2,0,True);
|
||||||
SIVAL(outbuf,smb_vwv0,res);
|
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);
|
pstrcpy( file_name, fsp->fsp_name);
|
||||||
|
|
||||||
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
|
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
|
||||||
fsp->fd, fsp->fnum,
|
fsp->fh->fd, fsp->fnum,
|
||||||
conn->num_files_open));
|
conn->num_files_open));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3201,7 +3291,9 @@ int reply_writeclose(connection_struct *conn,
|
|||||||
START_PROFILE(SMBwriteclose);
|
START_PROFILE(SMBwriteclose);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
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);
|
offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
|
||||||
|
|
||||||
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
|
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);
|
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
|
||||||
if (NT_STATUS_V(status)) {
|
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",
|
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);
|
END_PROFILE(SMBunlock);
|
||||||
return(outsize);
|
return(outsize);
|
||||||
@ -3437,7 +3529,7 @@ int reply_printopen(connection_struct *conn,
|
|||||||
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
SSVAL(outbuf,smb_vwv0,fsp->fnum);
|
||||||
|
|
||||||
DEBUG(3,("openprint fd=%d fnum=%d\n",
|
DEBUG(3,("openprint fd=%d fnum=%d\n",
|
||||||
fsp->fd, fsp->fnum));
|
fsp->fh->fd, fsp->fnum));
|
||||||
|
|
||||||
END_PROFILE(SMBsplopen);
|
END_PROFILE(SMBsplopen);
|
||||||
return(outsize);
|
return(outsize);
|
||||||
@ -3463,7 +3555,7 @@ int reply_printclose(connection_struct *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3,("printclose fd=%d fnum=%d\n",
|
DEBUG(3,("printclose fd=%d fnum=%d\n",
|
||||||
fsp->fd,fsp->fnum));
|
fsp->fh->fd,fsp->fnum));
|
||||||
|
|
||||||
close_err = close_file(fsp,True);
|
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_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
numtowrite = SVAL(smb_buf(inbuf),1);
|
numtowrite = SVAL(smb_buf(inbuf),1);
|
||||||
data = smb_buf(inbuf) + 3;
|
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,
|
BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
||||||
int count,BOOL target_is_directory, int *err_ret)
|
int count,BOOL target_is_directory, int *err_ret)
|
||||||
{
|
{
|
||||||
int Access,action;
|
|
||||||
SMB_STRUCT_STAT src_sbuf, sbuf2;
|
SMB_STRUCT_STAT src_sbuf, sbuf2;
|
||||||
SMB_OFF_T ret=-1;
|
SMB_OFF_T ret=-1;
|
||||||
files_struct *fsp1,*fsp2;
|
files_struct *fsp1,*fsp2;
|
||||||
pstring dest;
|
pstring dest;
|
||||||
uint32 dosattrs;
|
uint32 dosattrs;
|
||||||
|
uint32 new_create_disposition;
|
||||||
|
|
||||||
*err_ret = 0;
|
*err_ret = 0;
|
||||||
|
|
||||||
pstrcpy(dest,dest1);
|
pstrcpy(dest,dest1);
|
||||||
if (target_is_directory) {
|
if (target_is_directory) {
|
||||||
char *p = strrchr_m(src,'/');
|
char *p = strrchr_m(src,'/');
|
||||||
if (p)
|
if (p) {
|
||||||
p++;
|
p++;
|
||||||
else
|
} else {
|
||||||
p = src;
|
p = src;
|
||||||
|
}
|
||||||
pstrcat(dest,"/");
|
pstrcat(dest,"/");
|
||||||
pstrcat(dest,p);
|
pstrcat(dest,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vfs_file_exist(conn,src,&src_sbuf))
|
if (!vfs_file_exist(conn,src,&src_sbuf)) {
|
||||||
return(False);
|
return(False);
|
||||||
|
}
|
||||||
|
|
||||||
fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
if (!target_is_directory && count) {
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,INTERNAL_OPEN_ONLY,
|
new_create_disposition = FILE_OPEN;
|
||||||
&Access,&action);
|
} 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);
|
return(False);
|
||||||
|
}
|
||||||
if (!target_is_directory && count)
|
|
||||||
ofun = FILE_EXISTS_OPEN;
|
|
||||||
|
|
||||||
dosattrs = dos_mode(conn, src, &src_sbuf);
|
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);
|
ZERO_STRUCTP(&sbuf2);
|
||||||
|
}
|
||||||
|
|
||||||
fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
|
fsp2 = open_file_ntcreate(conn,dest,&sbuf2,
|
||||||
ofun,dosattrs,INTERNAL_OPEN_ONLY,&Access,&action);
|
FILE_GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
new_create_disposition,
|
||||||
|
0,
|
||||||
|
dosattrs,
|
||||||
|
INTERNAL_OPEN_ONLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!fsp2) {
|
if (!fsp2) {
|
||||||
close_file(fsp1,False);
|
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 ((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) ));
|
DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
|
||||||
/*
|
/*
|
||||||
* Stop the copy from occurring.
|
* 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);
|
ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
|
||||||
|
}
|
||||||
|
|
||||||
close_file(fsp1,False);
|
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
|
/* we don't support these - and CANCEL_LOCK makes w2k
|
||||||
and XP reboot so I don't really want to be
|
and XP reboot so I don't really want to be
|
||||||
compatible! (tridge) */
|
compatible! (tridge) */
|
||||||
return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
return ERROR_DOS(ERRDOS, ERRnoatomiclocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
|
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);
|
outsize = set_message(outbuf,8,0,True);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
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);
|
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
|
||||||
maxcount = SVAL(inbuf,smb_vwv3);
|
maxcount = SVAL(inbuf,smb_vwv3);
|
||||||
@ -5286,7 +5404,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
|||||||
START_PROFILE(SMBwriteBmpx);
|
START_PROFILE(SMBwriteBmpx);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
if (HAS_CACHED_ERROR(fsp)) {
|
if (HAS_CACHED_ERROR(fsp)) {
|
||||||
return(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);
|
START_PROFILE(SMBwriteBs);
|
||||||
|
|
||||||
CHECK_FSP(fsp,conn);
|
CHECK_FSP(fsp,conn);
|
||||||
CHECK_WRITE(fsp);
|
if (!CHECK_WRITE(fsp)) {
|
||||||
|
return(ERROR_DOS(ERRDOS,ERRbadaccess));
|
||||||
|
}
|
||||||
|
|
||||||
tcount = SVAL(inbuf,smb_vwv1);
|
tcount = SVAL(inbuf,smb_vwv1);
|
||||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
SMB transaction2 handling
|
SMB transaction2 handling
|
||||||
Copyright (C) Jeremy Allison 1994-2003
|
Copyright (C) Jeremy Allison 1994-2003
|
||||||
Copyright (C) Stefan (metze) Metzmacher 2003
|
Copyright (C) Stefan (metze) Metzmacher 2003
|
||||||
|
Copyright (C) Volker Lendecke 2005
|
||||||
|
|
||||||
Extensively modified by Andrew Tridgell, 1995
|
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;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsp && fsp->fd != -1) {
|
if (fsp && fsp->fh->fd != -1) {
|
||||||
sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
|
sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size);
|
||||||
} else {
|
} else {
|
||||||
sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
|
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;
|
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++) {
|
ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
|
||||||
if (fsp && fsp->fd != -1) {
|
if (fsp && fsp->fh->fd != -1) {
|
||||||
sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
|
sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size);
|
||||||
} else {
|
} else {
|
||||||
sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
|
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) {
|
if (ea_list->ea.value.length == 0) {
|
||||||
/* Remove the attribute. */
|
/* 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",
|
DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
|
||||||
unix_ea_name, fsp->fsp_name));
|
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 {
|
} else {
|
||||||
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
|
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
|
||||||
unix_ea_name, fname));
|
unix_ea_name, fname));
|
||||||
@ -355,10 +356,10 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} 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",
|
DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
|
||||||
unix_ea_name, fsp->fsp_name));
|
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);
|
ea_list->ea.value.data, ea_list->ea.value.length, 0);
|
||||||
} else {
|
} else {
|
||||||
DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
|
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 *params = *pparams;
|
||||||
char *pdata = *ppdata;
|
char *pdata = *ppdata;
|
||||||
int16 open_mode;
|
int deny_mode;
|
||||||
int16 open_attr;
|
int32 open_attr;
|
||||||
BOOL oplock_request;
|
BOOL oplock_request;
|
||||||
#if 0
|
#if 0
|
||||||
BOOL return_additional_info;
|
BOOL return_additional_info;
|
||||||
int16 open_sattr;
|
int16 open_sattr;
|
||||||
time_t open_time;
|
time_t open_time;
|
||||||
#endif
|
#endif
|
||||||
int16 open_ofun;
|
int open_ofun;
|
||||||
int32 open_size;
|
int32 open_size;
|
||||||
char *pname;
|
char *pname;
|
||||||
pstring fname;
|
pstring fname;
|
||||||
SMB_OFF_T size=0;
|
SMB_OFF_T size=0;
|
||||||
int fmode=0,mtime=0,rmode;
|
int fattr=0,mtime=0;
|
||||||
SMB_INO_T inode = 0;
|
SMB_INO_T inode = 0;
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
int smb_action = 0;
|
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;
|
struct ea_list *ea_list = NULL;
|
||||||
uint16 flags = 0;
|
uint16 flags = 0;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
uint32 access_mask;
|
||||||
|
uint32 share_mode;
|
||||||
|
uint32 create_disposition;
|
||||||
|
uint32 create_options = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure we have enough parameters to perform the operation.
|
* 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);
|
flags = SVAL(params, 0);
|
||||||
open_mode = SVAL(params, 2);
|
deny_mode = SVAL(params, 2);
|
||||||
open_attr = SVAL(params,6);
|
open_attr = SVAL(params,6);
|
||||||
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
|
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
|
||||||
if (oplock_request) {
|
if (oplock_request) {
|
||||||
@ -766,16 +771,18 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
|||||||
open_size = IVAL(params,14);
|
open_size = IVAL(params,14);
|
||||||
pname = ¶ms[28];
|
pname = ¶ms[28];
|
||||||
|
|
||||||
if (IS_IPC(conn))
|
if (IS_IPC(conn)) {
|
||||||
return(ERROR_DOS(ERRSRV,ERRaccess));
|
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||||
|
}
|
||||||
|
|
||||||
srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
|
srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return ERROR_NT(status);
|
return ERROR_NT(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
|
DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
|
||||||
fname,open_mode, open_attr, open_ofun, open_size));
|
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 */
|
/* 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);
|
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strange open mode mapping. */
|
if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
|
||||||
if (open_ofun == 0) {
|
&access_mask,
|
||||||
if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) {
|
&share_mode,
|
||||||
open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
|
&create_disposition,
|
||||||
}
|
&create_options)) {
|
||||||
|
return ERROR_DOS(ERRDOS, ERRbadaccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any data in this call is an EA list. */
|
/* 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,
|
fsp = open_file_ntcreate(conn,fname,&sbuf,
|
||||||
oplock_request, &rmode,&smb_action);
|
access_mask,
|
||||||
|
share_mode,
|
||||||
|
create_disposition,
|
||||||
|
create_options,
|
||||||
|
open_attr,
|
||||||
|
oplock_request,
|
||||||
|
&smb_action);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
talloc_destroy(ctx);
|
talloc_destroy(ctx);
|
||||||
@ -835,10 +849,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
size = get_file_size(sbuf);
|
size = get_file_size(sbuf);
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fattr = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
inode = sbuf.st_ino;
|
inode = sbuf.st_ino;
|
||||||
if (fmode & aDIR) {
|
if (fattr & aDIR) {
|
||||||
talloc_destroy(ctx);
|
talloc_destroy(ctx);
|
||||||
close_file(fsp,False);
|
close_file(fsp,False);
|
||||||
return(ERROR_DOS(ERRDOS,ERRnoaccess));
|
return(ERROR_DOS(ERRDOS,ERRnoaccess));
|
||||||
@ -861,10 +875,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
|||||||
*pparams = params;
|
*pparams = params;
|
||||||
|
|
||||||
SSVAL(params,0,fsp->fnum);
|
SSVAL(params,0,fsp->fnum);
|
||||||
SSVAL(params,2,fmode);
|
SSVAL(params,2,open_attr);
|
||||||
put_dos_date2(params,4, mtime);
|
put_dos_date2(params,4, mtime);
|
||||||
SIVAL(params,8, (uint32)size);
|
SIVAL(params,8, (uint32)size);
|
||||||
SSVAL(params,12,rmode);
|
SSVAL(params,12,open_ofun);
|
||||||
SSVAL(params,16,0); /* Padding. */
|
SSVAL(params,16,0); /* Padding. */
|
||||||
|
|
||||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
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.conn = conn;
|
||||||
fsp.fnum = -1;
|
fsp.fnum = -1;
|
||||||
fsp.fd = -1;
|
fsp.fh->fd = -1;
|
||||||
|
|
||||||
/* access check */
|
/* access check */
|
||||||
if (current_user.uid != 0) {
|
if (current_user.uid != 0) {
|
||||||
@ -2709,6 +2723,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
|||||||
char *pdata = *ppdata;
|
char *pdata = *ppdata;
|
||||||
uint16 info_level;
|
uint16 info_level;
|
||||||
int mode=0;
|
int mode=0;
|
||||||
|
int nlink;
|
||||||
SMB_OFF_T file_size=0;
|
SMB_OFF_T file_size=0;
|
||||||
SMB_BIG_UINT allocation_size=0;
|
SMB_BIG_UINT allocation_size=0;
|
||||||
unsigned int data_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;
|
files_struct *fsp = NULL;
|
||||||
TALLOC_CTX *ea_ctx = NULL;
|
TALLOC_CTX *ea_ctx = NULL;
|
||||||
struct ea_list *ea_list = 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)
|
if (!params)
|
||||||
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
|
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);
|
pstrcpy(fname, fsp->fsp_name);
|
||||||
/* We know this name is ok, it's already passed the checks. */
|
/* 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
|
* This is actually a QFILEINFO on a directory
|
||||||
* handle (returned from an NT SMB). NT5.0 seems
|
* 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);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Original code - this is an open file.
|
* 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);
|
CHECK_FSP(fsp,conn);
|
||||||
|
|
||||||
pstrcpy(fname, fsp->fsp_name);
|
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)));
|
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
|
||||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||||
}
|
}
|
||||||
pos = fsp->position_information;
|
pos = fsp->fh->position_information;
|
||||||
delete_pending = fsp->delete_on_close;
|
delete_pending =
|
||||||
desired_access = fsp->desired_access;
|
get_delete_on_close_flag(sbuf.st_dev,
|
||||||
|
sbuf.st_ino);
|
||||||
|
access_mask = fsp->access_mask;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NTSTATUS status = NT_STATUS_OK;
|
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)));
|
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);
|
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())
|
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;
|
data_size = 24;
|
||||||
SOFF_T(pdata,0,allocation_size);
|
SOFF_T(pdata,0,allocation_size);
|
||||||
SOFF_T(pdata,8,file_size);
|
SOFF_T(pdata,8,file_size);
|
||||||
if (delete_pending & sbuf.st_nlink)
|
SIVAL(pdata,16,nlink);
|
||||||
SIVAL(pdata,16,sbuf.st_nlink - 1);
|
SCVAL(pdata,20,delete_pending?1:0);
|
||||||
else
|
|
||||||
SIVAL(pdata,16,sbuf.st_nlink);
|
|
||||||
SCVAL(pdata,20,0);
|
|
||||||
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
||||||
SSVAL(pdata,22,0); /* Padding. */
|
SSVAL(pdata,22,0); /* Padding. */
|
||||||
break;
|
break;
|
||||||
@ -3129,10 +3162,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
|||||||
pdata += 40;
|
pdata += 40;
|
||||||
SOFF_T(pdata,0,allocation_size);
|
SOFF_T(pdata,0,allocation_size);
|
||||||
SOFF_T(pdata,8,file_size);
|
SOFF_T(pdata,8,file_size);
|
||||||
if (delete_pending && sbuf.st_nlink)
|
SIVAL(pdata,16,nlink);
|
||||||
SIVAL(pdata,16,sbuf.st_nlink - 1);
|
|
||||||
else
|
|
||||||
SIVAL(pdata,16,sbuf.st_nlink);
|
|
||||||
SCVAL(pdata,20,delete_pending);
|
SCVAL(pdata,20,delete_pending);
|
||||||
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
SCVAL(pdata,21,(mode&aDIR)?1:0);
|
||||||
SSVAL(pdata,22,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:
|
case SMB_FILE_ACCESS_INFORMATION:
|
||||||
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
|
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
|
||||||
SIVAL(pdata,0,desired_access);
|
SIVAL(pdata,0,access_mask);
|
||||||
data_size = 4;
|
data_size = 4;
|
||||||
break;
|
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_file_acls = 0;
|
||||||
uint16 num_def_acls = 0;
|
uint16 num_def_acls = 0;
|
||||||
|
|
||||||
if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
|
if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
|
||||||
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
|
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
|
||||||
} else {
|
} else {
|
||||||
file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
|
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.
|
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) {
|
if (!delete_on_close) {
|
||||||
/*
|
return NT_STATUS_OK;
|
||||||
* 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(fsp->is_directory) {
|
/*
|
||||||
fsp->directory_delete_on_close = delete_on_close;
|
* Only allow delete on close for writable files.
|
||||||
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 {
|
if ((dosmode & aRONLY) &&
|
||||||
fsp->delete_on_close = delete_on_close;
|
!lp_delete_readonly(SNUM(fsp->conn))) {
|
||||||
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
|
DEBUG(10,("can_set_delete_on_close: file %s delete on close "
|
||||||
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
|
"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;
|
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.
|
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",
|
DEBUG(10,("set_delete_on_close: %s delete on close flag for "
|
||||||
delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
|
"fnum = %d, file %s\n",
|
||||||
|
delete_on_close ? "Adding" : "Removing", fsp->fnum,
|
||||||
|
fsp->fsp_name ));
|
||||||
|
|
||||||
if (fsp->is_directory || fsp->is_stat)
|
if (fsp->is_directory || fsp->is_stat)
|
||||||
return NT_STATUS_OK;
|
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;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
|
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",
|
DEBUG(0,("set_delete_on_close: failed to change delete "
|
||||||
fsp->fsp_name ));
|
"on close flag for file %s\n",
|
||||||
|
fsp->fsp_name ));
|
||||||
unlock_share_entry_fsp(fsp);
|
unlock_share_entry_fsp(fsp);
|
||||||
return NT_STATUS_ACCESS_DENIED;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
@ -3632,7 +3661,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
fsp = file_fsp(params,0);
|
fsp = file_fsp(params,0);
|
||||||
info_level = SVAL(params,2);
|
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
|
* This is actually a SETFILEINFO on a directory
|
||||||
* handle (returned from an NT SMB). NT5.0 seems
|
* 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.
|
* Doing a DELETE_ON_CLOSE should cancel a print job.
|
||||||
*/
|
*/
|
||||||
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
|
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
|
||||||
fsp->share_mode = FILE_DELETE_ON_CLOSE;
|
fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
|
||||||
|
|
||||||
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
|
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);
|
CHECK_FSP(fsp,conn);
|
||||||
|
|
||||||
pstrcpy(fname, fsp->fsp_name);
|
pstrcpy(fname, fsp->fsp_name);
|
||||||
fd = fsp->fd;
|
fd = fsp->fh->fd;
|
||||||
|
|
||||||
if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
|
if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
|
||||||
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
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) {
|
if (fd == -1) {
|
||||||
files_struct *new_fsp = NULL;
|
files_struct *new_fsp = NULL;
|
||||||
int access_mode = 0;
|
|
||||||
int action = 0;
|
|
||||||
|
|
||||||
if(global_oplock_break) {
|
if(global_oplock_break) {
|
||||||
/* Queue this file modify as we are the process of an 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
|
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||||
SET_OPEN_MODE(DOS_OPEN_RDWR),
|
FILE_WRITE_DATA,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
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));
|
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||||
|
}
|
||||||
ret = vfs_allocate_file_space(new_fsp, allocation_size);
|
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",
|
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
|
||||||
new_fsp->fnum, strerror(errno)));
|
new_fsp->fnum, strerror(errno)));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -3963,14 +3994,15 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
if (fsp == NULL)
|
if (fsp == NULL)
|
||||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
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)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return ERROR_NT(status);
|
return ERROR_NT(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The set is across all open files on this dev/inode pair. */
|
/* 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)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return ERROR_NT(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",
|
DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
|
||||||
fname, (double)position_information ));
|
fname, (double)position_information ));
|
||||||
if (fsp) {
|
if (fsp) {
|
||||||
fsp->position_information = position_information;
|
fsp->fh->position_information = position_information;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done. We only get position info in this call. */
|
/* 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) {
|
if (fd == -1) {
|
||||||
files_struct *new_fsp = NULL;
|
files_struct *new_fsp = NULL;
|
||||||
int access_mode = 0;
|
|
||||||
int action = 0;
|
|
||||||
|
|
||||||
if(global_oplock_break) {
|
if(global_oplock_break) {
|
||||||
/* Queue this file modify as we are the process of an 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_fsp = open_file_shared(conn, fname, &sbuf,
|
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
|
||||||
SET_OPEN_MODE(DOS_OPEN_RDWR),
|
FILE_WRITE_DATA,
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_OPEN,
|
||||||
|
0,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
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));
|
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||||
|
}
|
||||||
ret = vfs_set_filelen(new_fsp, size);
|
ret = vfs_set_filelen(new_fsp, size);
|
||||||
close_file(new_fsp,True);
|
close_file(new_fsp,True);
|
||||||
} else {
|
} else {
|
||||||
ret = vfs_set_filelen(fsp, size);
|
ret = vfs_set_filelen(fsp, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1) {
|
||||||
return (UNIXERROR(ERRHRD,ERRdiskfull));
|
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) {
|
if (result == -1 && errno == ESPIPE) {
|
||||||
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
||||||
result = SMB_VFS_READ(fsp, fd, data, n);
|
result = SMB_VFS_READ(fsp, fd, data, n);
|
||||||
fsp->pos = 0;
|
fsp->fh->pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_PREAD */
|
#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) {
|
if (curr == -1 && errno == ESPIPE) {
|
||||||
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
/* Maintain the fiction that pipes can be seeked (sought?) on. */
|
||||||
result = SMB_VFS_READ(fsp, fd, data, n);
|
result = SMB_VFS_READ(fsp, fd, data, n);
|
||||||
fsp->pos = 0;
|
fsp->fh->pos = 0;
|
||||||
return result;
|
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 retlen;
|
||||||
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
|
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)
|
if (retlen <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
|
|||||||
|
|
||||||
while (total < 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);
|
byte_count - total);
|
||||||
|
|
||||||
if (ret == 0) return total;
|
if (ret == 0) return total;
|
||||||
@ -452,7 +452,7 @@ ssize_t vfs_pread_data(files_struct *fsp, char *buf,
|
|||||||
|
|
||||||
while (total < byte_count)
|
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);
|
byte_count - total, offset + total);
|
||||||
|
|
||||||
if (ret == 0) return 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;
|
ssize_t ret;
|
||||||
|
|
||||||
while (total < N) {
|
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)
|
if (ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -496,7 +496,7 @@ ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
while (total < N) {
|
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);
|
N - total, offset + total);
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
@ -535,7 +535,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
|
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return ret;
|
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 ));
|
fsp->fsp_name, (double)st.st_size ));
|
||||||
|
|
||||||
flush_write_cache(fsp, SIZECHANGE_FLUSH);
|
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);
|
set_filelen_write_cache(fsp, len);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -591,7 +591,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
|
|||||||
release_level_2_oplocks_on_change(fsp);
|
release_level_2_oplocks_on_change(fsp);
|
||||||
DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
|
DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
|
||||||
flush_write_cache(fsp, SIZECHANGE_FLUSH);
|
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);
|
set_filelen_write_cache(fsp, len);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -617,7 +617,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
|
|||||||
ssize_t pwrite_ret;
|
ssize_t pwrite_ret;
|
||||||
|
|
||||||
release_level_2_oplocks_on_change(fsp);
|
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) {
|
if (ret == -1) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -646,7 +646,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
|
|||||||
while (total < num_to_write) {
|
while (total < num_to_write) {
|
||||||
size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total));
|
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) {
|
if (pwrite_ret == -1) {
|
||||||
DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
|
DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
|
||||||
fsp->fsp_name, strerror(errno) ));
|
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;
|
in_fsp = in;
|
||||||
out_fsp = out;
|
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] = SMB_MALLOC_P(struct files_struct);
|
||||||
vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]);
|
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;
|
vfs->files[fd]->conn = vfs->conn;
|
||||||
printf("open: fd=%d\n", fd);
|
printf("open: fd=%d\n", fd);
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
|
@ -111,37 +111,47 @@ static void print_share_mode(share_mode_entry *e, char *fname)
|
|||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (Ucrit_checkPid(e->pid)) {
|
if (Ucrit_checkPid(e->pid)) {
|
||||||
d_printf("%-5d ",(int)e->pid);
|
d_printf("%-5d ",(int)e->pid);
|
||||||
switch (GET_DENY_MODE(e->share_mode)) {
|
switch (map_share_mode_to_deny_mode(e->share_access,
|
||||||
case DENY_NONE: d_printf("DENY_NONE "); break;
|
e->private_options)) {
|
||||||
case DENY_ALL: d_printf("DENY_ALL "); break;
|
case DENY_NONE: d_printf("DENY_NONE "); break;
|
||||||
case DENY_DOS: d_printf("DENY_DOS "); break;
|
case DENY_ALL: d_printf("DENY_ALL "); break;
|
||||||
case DENY_READ: d_printf("DENY_READ "); break;
|
case DENY_DOS: d_printf("DENY_DOS "); break;
|
||||||
case DENY_WRITE:printf("DENY_WRITE "); break;
|
case DENY_READ: d_printf("DENY_READ "); break;
|
||||||
case DENY_FCB: d_printf("DENY_FCB "); 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);
|
default: {
|
||||||
switch (e->share_mode&0xF) {
|
d_printf("unknown-please report ! "
|
||||||
case 0: d_printf("RDONLY "); break;
|
"e->share_access = 0x%x, "
|
||||||
case 1: d_printf("WRONLY "); break;
|
"e->private_options = 0x%x\n",
|
||||||
case 2: d_printf("RDWR "); break;
|
(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 &
|
if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
|
||||||
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
|
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) {
|
||||||
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
|
d_printf("EXCLUSIVE+BATCH ");
|
||||||
d_printf("EXCLUSIVE+BATCH ");
|
} else if (e->op_type & EXCLUSIVE_OPLOCK) {
|
||||||
else if (e->op_type & EXCLUSIVE_OPLOCK)
|
d_printf("EXCLUSIVE ");
|
||||||
d_printf("EXCLUSIVE ");
|
} else if (e->op_type & BATCH_OPLOCK) {
|
||||||
else if (e->op_type & BATCH_OPLOCK)
|
d_printf("BATCH ");
|
||||||
d_printf("BATCH ");
|
} else if (e->op_type & LEVEL_II_OPLOCK) {
|
||||||
else if (e->op_type & LEVEL_II_OPLOCK)
|
d_printf("LEVEL_II ");
|
||||||
d_printf("LEVEL_II ");
|
} else {
|
||||||
else
|
d_printf("NONE ");
|
||||||
d_printf("NONE ");
|
}
|
||||||
|
|
||||||
d_printf(" %s %s",fname,
|
d_printf(" %s %s",fname, asctime(LocalTime((time_t *)&e->time.tv_sec)));
|
||||||
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");
|
printf("Content-Type: image/gif\r\n");
|
||||||
} else if (strcmp(p,".jpg")==0) {
|
} else if (strcmp(p,".jpg")==0) {
|
||||||
printf("Content-Type: image/jpeg\r\n");
|
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) {
|
} else if (strcmp(p,".txt")==0) {
|
||||||
printf("Content-Type: text/plain\r\n");
|
printf("Content-Type: text/plain\r\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,23 +108,28 @@ static char *tstring(time_t t)
|
|||||||
static void print_share_mode(share_mode_entry *e, char *fname)
|
static void print_share_mode(share_mode_entry *e, char *fname)
|
||||||
{
|
{
|
||||||
char *utf8_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("<tr><td>%s</td>",_(mapPid2Machine(e->pid)));
|
||||||
printf("<td>");
|
printf("<td>");
|
||||||
switch ((e->share_mode>>4)&0xF) {
|
switch ((deny_mode>>4)&0xF) {
|
||||||
case DENY_NONE: printf("DENY_NONE"); break;
|
case DENY_NONE: printf("DENY_NONE"); break;
|
||||||
case DENY_ALL: printf("DENY_ALL "); break;
|
case DENY_ALL: printf("DENY_ALL "); break;
|
||||||
case DENY_DOS: printf("DENY_DOS "); break;
|
case DENY_DOS: printf("DENY_DOS "); break;
|
||||||
|
case DENY_FCB: printf("DENY_FCB "); break;
|
||||||
case DENY_READ: printf("DENY_READ "); break;
|
case DENY_READ: printf("DENY_READ "); break;
|
||||||
case DENY_WRITE:printf("DENY_WRITE "); break;
|
case DENY_WRITE:printf("DENY_WRITE "); break;
|
||||||
}
|
}
|
||||||
printf("</td>");
|
printf("</td>");
|
||||||
|
|
||||||
printf("<td>");
|
printf("<td>");
|
||||||
switch (e->share_mode&0xF) {
|
if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) {
|
||||||
case 0: printf("%s", _("RDONLY ")); break;
|
printf("%s", _("RDWR "));
|
||||||
case 1: printf("%s", _("WRONLY ")); break;
|
} else if (e->access_mask & FILE_WRITE_DATA) {
|
||||||
case 2: printf("%s", _("RDWR ")); break;
|
printf("%s", _("WRONLY "));
|
||||||
|
} else {
|
||||||
|
printf("%s", _("RDONLY "));
|
||||||
}
|
}
|
||||||
printf("</td>");
|
printf("</td>");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user