summaryrefslogtreecommitdiffstats
path: root/source/smbd/trans2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/trans2.c')
-rw-r--r--source/smbd/trans2.c176
1 files changed, 93 insertions, 83 deletions
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index c9ade4b6ba1..704a610726c 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -1270,6 +1270,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
return(UNIXERROR(ERRDOS,ERRbadpath));
}
+
+ delete_pending = fsp->directory_delete_on_close;
+
} else {
/*
* Original code - this is an open file.
@@ -1674,122 +1677,129 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
if(fsp->is_directory)
- return(ERROR(ERRDOS,ERRnoaccess));
-
- /*
- * We can only set the delete on close flag if
- * the share mode contained ALLOW_SHARE_DELETE
- */
-
- if(lp_share_modes(SNUM(conn)))
{
- if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
- return(ERROR(ERRDOS,ERRnoaccess));
+ fsp->directory_delete_on_close = delete_on_close;
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+
+ }
+ else
+ {
/*
- * If the flag has been set then
- * modify the share mode entry for all files we have open
- * on this device and inode to tell other smbds we have
- * changed the delete on close flag.
+ * We can only set the delete on close flag if
+ * the share mode contained ALLOW_SHARE_DELETE
*/
- if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
+ if(lp_share_modes(SNUM(conn)))
{
- int token;
- int i;
- files_struct *iterate_fsp;
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
- int num_share_modes;
- share_mode_entry *current_shares = NULL;
-
- if(lock_share_entry(fsp->conn, dev, inode, &token) == False)
+ if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
return(ERROR(ERRDOS,ERRnoaccess));
/*
- * Before we allow this we need to ensure that all current opens
- * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
- * do not then we deny this (as we are essentially deleting the
- * file at this point.
+ * If the flag has been set then
+ * modify the share mode entry for all files we have open
+ * on this device and inode to tell other smbds we have
+ * changed the delete on close flag.
*/
- num_share_modes = get_share_modes(conn, token, dev, inode, &current_shares);
- for(i = 0; i < num_share_modes; i++)
+ if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
{
- if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+ int token;
+ int i;
+ files_struct *iterate_fsp;
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ int num_share_modes;
+ share_mode_entry *current_shares = NULL;
+
+ if(lock_share_entry(fsp->conn, dev, inode, &token) == False)
+ return(ERROR(ERRDOS,ERRnoaccess));
+
+ /*
+ * Before we allow this we need to ensure that all current opens
+ * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
+ * do not then we deny this (as we are essentially deleting the
+ * file at this point.
+ */
+
+ num_share_modes = get_share_modes(conn, token, dev, inode, &current_shares);
+ for(i = 0; i < num_share_modes; i++)
{
- DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
+ if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+ {
+ DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
file %s as a share exists that was not opened with FILE_DELETE access.\n",
- fsp->fnum, fsp->fsp_name ));
- /*
- * Release the lock.
- */
+ fsp->fnum, fsp->fsp_name ));
+ /*
+ * Release the lock.
+ */
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode, token);
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- /*
- * Even though share violation would be more appropriate here,
- * return ERRnoaccess as that's what NT does.
- */
+ /*
+ * Even though share violation would be more appropriate here,
+ * return ERRnoaccess as that's what NT does.
+ */
- return(ERROR(ERRDOS,ERRnoaccess));
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
}
- }
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+ DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
- /*
- * Go through all files we have open on the same device and
- * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
- * Other smbd's that have this file open will have to fend for themselves. We
- * take care of this (rare) case in close_file(). See the comment there.
- */
+ /*
+ * Go through all files we have open on the same device and
+ * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+ * Other smbd's that have this file open will have to fend for themselves. We
+ * take care of this (rare) case in close_file(). See the comment there.
+ */
- for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
- iterate_fsp = file_find_di_next(iterate_fsp))
- {
- int new_share_mode = (delete_on_close ?
- (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
- (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
+ for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
+ iterate_fsp = file_find_di_next(iterate_fsp))
+ {
+ int new_share_mode = (delete_on_close ?
+ (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
+ (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
- DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
+ DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
dev = %x, inode = %.0f from %x to %x\n",
- iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
- (double)inode, iterate_fsp->share_mode, new_share_mode ));
+ iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
+ (double)inode, iterate_fsp->share_mode, new_share_mode ));
- if(modify_share_mode(token, iterate_fsp, new_share_mode)==False)
- DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+ if(modify_share_mode(token, iterate_fsp, new_share_mode)==False)
+ DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
- }
-
- /*
- * Set the delete on close flag in the reference
- * counted struct. Delete when the last reference
- * goes away.
- */
- fsp->fd_ptr->delete_on_close = delete_on_close;
+ }
- unlock_share_entry(fsp->conn, dev, inode, token);
+ /*
+ * Set the delete on close flag in the reference
+ * counted struct. Delete when the last reference
+ * goes away.
+ */
+ fsp->fd_ptr->delete_on_close = delete_on_close;
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ unlock_share_entry(fsp->conn, dev, inode, token);
- } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
- } /* end if lp_share_modes() */
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
+ } /* end if lp_share_modes() */
+ } /* end if is_directory. */
} else
return(ERROR(ERRDOS,ERRunknownlevel));
break;