summaryrefslogtreecommitdiff
path: root/source3/smbd/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r--source3/smbd/open.c144
1 files changed, 45 insertions, 99 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index cee2b37184..d5521f7f47 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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.
-
-/*******************************************************************
- Check if the share mode on a file allows it to be deleted or unlinked.
- Return True if sharing doesn't prevent the operation.
-********************************************************************/
+/****************************************************************************
+ Open a pseudo-file (no locking checks - a 'stat' open).
+****************************************************************************/
-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;
-
- if (vfs_stat(conn,fname,&sbuf) == -1)
- return(True);
-
- dev = sbuf.st_dev;
- inode = sbuf.st_ino;
-
- lock_share_entry(conn, dev, inode);
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
-
- /*
- * Check if the share modes will give us access.
- */
-
- 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));
+ extern struct current_user current_user;
+ BOOL got_stat = False;
+ files_struct *fsp = NULL;
- /* Oplock break.... */
- unlock_share_entry(conn, dev, inode);
+ if (!VALID_STAT(*psbuf))
+ return NULL;
- 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));
+ /* Can't 'stat' open directories. */
+ if(S_ISDIR(psbuf->st_mode))
+ return NULL;
- SAFE_FREE(old_shares);
- return False;
- }
- lock_share_entry(conn, dev, inode);
- broke_oplock = True;
- break;
- }
+ fsp = file_new(conn);
+ if(!fsp)
+ return NULL;
- /*
- * 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 */
+ fsp->conn = conn; /* The vfs_fXXX() macros need this. */
- if(broke_oplock) {
- SAFE_FREE(old_shares);
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
- }
- } while(broke_oplock);
- }
+ DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
/*
- * XXXX exactly what share mode combinations should be allowed for
- * deleting/renaming?
+ * Setup the files_struct for it.
*/
-
+
+ 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;
-
-free_and_exit:
+ conn->num_files_open++;
- unlock_share_entry(conn, dev, inode);
- SAFE_FREE(old_shares);
- return(ret);
+ return fsp;
}
-#endif