1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

Fix problem with "hide unreadable". stat file opens are baaack :-).

Jeremy.
(This used to be commit 62038a0abf)
This commit is contained in:
Jeremy Allison
2003-01-03 18:50:13 +00:00
parent f5d5df9644
commit 20f1cf6cdc
5 changed files with 520 additions and 562 deletions

View File

@ -392,6 +392,7 @@ typedef struct files_struct
BOOL print_file;
BOOL modified;
BOOL is_directory;
BOOL is_stat;
BOOL directory_delete_on_close;
char *fsp_name;
} files_struct;

View File

@ -100,14 +100,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
NTSTATUS status;
NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
if (!lp_locking(SNUM(conn)))
return NT_STATUS_OK;
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));

View File

@ -21,64 +21,65 @@
#include "includes.h"
/****************************************************************************
run a file if it is a magic script
Run a file if it is a magic script.
****************************************************************************/
static void check_magic(files_struct *fsp,connection_struct *conn)
{
if (!*lp_magicscript(SNUM(conn)))
return;
if (!*lp_magicscript(SNUM(conn)))
return;
DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
{
char *p;
if (!(p = strrchr_m(fsp->fsp_name,'/')))
p = fsp->fsp_name;
else
p++;
{
char *p;
if (!(p = strrchr_m(fsp->fsp_name,'/')))
p = fsp->fsp_name;
else
p++;
if (!strequal(lp_magicscript(SNUM(conn)),p))
return;
}
if (!strequal(lp_magicscript(SNUM(conn)),p))
return;
}
{
int ret;
pstring magic_output;
pstring fname;
SMB_STRUCT_STAT st;
int tmp_fd, outfd;
{
int ret;
pstring magic_output;
pstring fname;
SMB_STRUCT_STAT st;
int tmp_fd, outfd;
pstrcpy(fname,fsp->fsp_name);
if (*lp_magicoutput(SNUM(conn)))
pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
else
slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
pstrcpy(fname,fsp->fsp_name);
if (*lp_magicoutput(SNUM(conn)))
pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
else
slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
chmod(fname,0755);
ret = smbrun(fname,&tmp_fd);
DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
unlink(fname);
if (ret != 0 || tmp_fd == -1) {
if (tmp_fd != -1)
chmod(fname,0755);
ret = smbrun(fname,&tmp_fd);
DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
unlink(fname);
if (ret != 0 || tmp_fd == -1) {
if (tmp_fd != -1)
close(tmp_fd);
return;
}
outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
if (outfd == -1) {
close(tmp_fd);
return;
}
outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
if (outfd == -1) {
close(tmp_fd);
return;
}
return;
}
if (sys_fstat(tmp_fd,&st) == -1) {
if (sys_fstat(tmp_fd,&st) == -1) {
close(tmp_fd);
close(outfd);
return;
}
transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
close(tmp_fd);
close(outfd);
return;
}
transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
close(tmp_fd);
close(outfd);
}
}
/****************************************************************************
@ -97,8 +98,6 @@ static int close_filestruct(files_struct *fsp)
delete_write_cache(fsp);
}
fsp->is_directory = False;
conn->num_files_open--;
SAFE_FREE(fsp->wbmpx_ptr);
@ -258,17 +257,37 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
string_free(&fsp->fsp_name);
file_free(fsp);
return 0;
}
/****************************************************************************
Close a directory opened by an NT SMB call.
Close a 'stat file' opened internally.
****************************************************************************/
static int close_stat(files_struct *fsp)
{
/*
* Do the code common to files and directories.
*/
close_filestruct(fsp);
if (fsp->fsp_name)
string_free(&fsp->fsp_name);
file_free(fsp);
return 0;
}
/****************************************************************************
Close a files_struct.
****************************************************************************/
int close_file(files_struct *fsp, BOOL normal_close)
{
if(fsp->is_directory)
return close_directory(fsp, normal_close);
return close_normal_file(fsp, normal_close);
else if (fsp->is_stat)
return close_stat(fsp);
else
return close_normal_file(fsp, normal_close);
}

File diff suppressed because it is too large Load Diff

View File

@ -228,6 +228,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
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);
@ -1255,6 +1256,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
fsp->is_stat = False;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
@ -1271,118 +1273,62 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return fsp;
}
#if 0
Old code - I have replaced with correct desired_access checking. JRA.
/****************************************************************************
Open a pseudo-file (no locking checks - a 'stat' open).
****************************************************************************/
/*******************************************************************
Check if the share mode on a file allows it to be deleted or unlinked.
Return True if sharing doesn't prevent the operation.
********************************************************************/
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
{
int i;
int ret = False;
share_mode_entry *old_shares = 0;
int num_share_modes;
SMB_STRUCT_STAT sbuf;
pid_t pid = sys_getpid();
SMB_DEV_T dev;
SMB_INO_T inode;
extern struct current_user current_user;
BOOL got_stat = False;
files_struct *fsp = NULL;
if (vfs_stat(conn,fname,&sbuf) == -1)
return(True);
if (!VALID_STAT(*psbuf))
return NULL;
dev = sbuf.st_dev;
inode = sbuf.st_ino;
/* Can't 'stat' open directories. */
if(S_ISDIR(psbuf->st_mode))
return NULL;
lock_share_entry(conn, dev, inode);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
fsp = file_new(conn);
if(!fsp)
return NULL;
fsp->conn = conn; /* The vfs_fXXX() macros need this. */
DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
/*
* Check if the share modes will give us access.
* Setup the files_struct for it.
*/
if(num_share_modes != 0) {
BOOL broke_oplock;
do {
broke_oplock = False;
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &old_shares[i];
/*
* Break oplocks before checking share modes. See comment in
* open_file_shared for details.
* Check if someone has an oplock on this file. If so we must
* break it before continuing.
*/
if(BATCH_OPLOCK_TYPE(share_entry->op_type)) {
DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
/* Oplock break.... */
unlock_share_entry(conn, dev, inode);
if(request_oplock_break(share_entry) == False) {
DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
SAFE_FREE(old_shares);
return False;
}
lock_share_entry(conn, dev, inode);
broke_oplock = True;
break;
}
/*
* If this is a delete request and ALLOW_SHARE_DELETE is set then allow
* this to proceed. This takes precedence over share modes.
*/
if(!rename_op && GET_ALLOW_SHARE_DELETE(share_entry->share_mode))
continue;
/*
* Someone else has a share lock on it, check to see
* if we can too.
*/
if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) ||
(share_entry->pid != pid))
goto free_and_exit;
} /* end for */
if(broke_oplock) {
SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
}
} while(broke_oplock);
}
/*
* XXXX exactly what share mode combinations should be allowed for
* deleting/renaming?
*/
fsp->mode = psbuf->st_mode;
/*
* If we got here then either there were no share modes or
* all share modes were DENY_DOS and the pid == getpid() or
* delete access was requested and all share modes had the
* ALLOW_SHARE_DELETE bit set (takes precedence over other
* share modes).
* Don't store dev or inode, we don't want any iterator
* to see this.
*/
fsp->inode = (SMB_INO_T)0;
fsp->dev = (SMB_DEV_T)0;
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
fsp->pos = -1;
fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;
fsp->share_mode = 0;
fsp->desired_access = 0;
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 = True;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
ret = True;
conn->num_files_open++;
free_and_exit:
unlock_share_entry(conn, dev, inode);
SAFE_FREE(old_shares);
return(ret);
return fsp;
}
#endif