#include "includes.h"
+extern struct generic_mapping file_generic_mapping;
extern struct current_user current_user;
extern userdom_struct current_user_info;
extern uint16 global_smbpid;
return fd_close_posix(conn, fsp);
}
-
-/****************************************************************************
- Check a filename for the pipe string.
-****************************************************************************/
-
-static void check_for_pipe(const char *fname)
-{
- /* special case of pipe opens */
- char s[10];
- StrnCpy(s,fname,sizeof(s)-1);
- strlower_m(s);
- if (strstr(s,"pipe/")) {
- DEBUG(3,("Rejecting named pipe open for %s\n",fname));
- set_saved_error_triple(ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED);
- }
-}
-
/****************************************************************************
Change the ownership of a file to that of the parent directory.
Do this by fd if possible.
/* It's a read-only share - fail if we wanted to write. */
if(accmode != O_RDONLY) {
DEBUG(3,("Permission denied opening %s\n",fname));
- check_for_pipe(fname);
return False;
} else if(flags & O_CREAT) {
/* We don't want to write - but we must make sure that
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
"(flags=%d)\n",
fname,strerror(errno),local_flags,flags));
- check_for_pipe(fname);
return False;
}
if (delay_it) {
BOOL ret;
+ char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
+
DEBUG(10, ("Sending break request to PID %s\n",
procid_str_static(&exclusive->pid)));
exclusive->op_mid = get_current_mid();
+
+ share_mode_entry_to_message(msg, exclusive);
+
become_root();
ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
- exclusive, sizeof(*exclusive), True);
+ msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
unbecome_root();
if (!ret) {
DEBUG(3, ("Could not send oplock break message\n"));
}
-/* Map generic permissions to file object specific permissions */
-
-struct generic_mapping file_generic_mapping = {
- FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_GENERIC_ALL
-};
-
/****************************************************************************
Open a file with a share mode.
****************************************************************************/
}
set_share_mode(lck, fsp, 0, fsp->oplock_type);
- if (create_options & FILE_DELETE_ON_CLOSE) {
- uint32 dosattr= existing_dos_attributes;
- NTSTATUS result;
-
- if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
+ if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
info == FILE_WAS_SUPERSEDED) {
- dosattr = new_dos_attributes;
- }
- result = can_set_delete_on_close(fsp, True, dosattr);
-
- if (!NT_STATUS_IS_OK(result)) {
- /* Remember to delete the mode we just added. */
- del_share_mode(lck, fsp);
- talloc_free(lck);
- fd_close(conn,fsp);
- file_free(fsp);
- set_saved_ntstatus(result);
- return NULL;
+ /* Handle strange delete on close create semantics. */
+ if (create_options & FILE_DELETE_ON_CLOSE) {
+ NTSTATUS result = can_set_delete_on_close(fsp, True, new_dos_attributes);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ /* Remember to delete the mode we just added. */
+ del_share_mode(lck, fsp);
+ talloc_free(lck);
+ fd_close(conn,fsp);
+ file_free(fsp);
+ set_saved_ntstatus(result);
+ return NULL;
+ }
+ /* Note that here we set the *inital* delete on close flag,
+ not the regular one. */
+ set_delete_on_close_token(lck, ¤t_user.ut);
+ lck->initial_delete_on_close = True;
+ lck->modified = True;
}
- lck->delete_on_close = True;
- lck->modified = True;
- }
- if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
- info == FILE_WAS_SUPERSEDED) {
/* Files should be initially set as archive */
if (lp_map_archive(SNUM(conn)) ||
lp_store_dos_attributes(SNUM(conn))) {
set_share_mode(lck, fsp, 0, NO_OPLOCK);
+ /* For directories the delete on close bit at open time seems
+ always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
if (create_options & FILE_DELETE_ON_CLOSE) {
status = can_set_delete_on_close(fsp, True, 0);
if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
- lck->delete_on_close = True;
+ set_delete_on_close_token(lck, ¤t_user.ut);
+ lck->initial_delete_on_close = True;
lck->modified = True;
}
void msg_file_was_renamed(int msg_type, struct process_id src, void *buf, size_t len)
{
files_struct *fsp;
- struct file_renamed_message *frm = (struct file_renamed_message *)buf;
+ char *frm = (char *)buf;
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
const char *sharepath;
const char *newname;
size_t sp_len;
- if (buf == NULL || len < sizeof(*frm)) {
+ if (buf == NULL || len < MSG_FILE_RENAMED_MIN_SIZE + 2) {
DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n", (int)len));
return;
}
- sharepath = &frm->names[0];
+ /* Unpack the message. */
+ dev = DEV_T_VAL(frm,0);
+ inode = INO_T_VAL(frm,8);
+ sharepath = &frm[16];
newname = sharepath + strlen(sharepath) + 1;
sp_len = strlen(sharepath);
DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
"dev %x, inode %.0f\n",
- sharepath, newname, (unsigned int)frm->dev, (double)frm->inode ));
+ sharepath, newname, (unsigned int)dev, (double)inode ));
- for(fsp = file_find_di_first(frm->dev, frm->inode); fsp; fsp = file_find_di_next(fsp)) {
+ for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
fsp->fnum, fsp->fsp_name, newname ));