static NTSTATUS get_file_handle_for_metadata(connection_struct *conn, struct smb_filename *smb_fname, files_struct **ret_fsp, bool *need_close) { NTSTATUS status; files_struct *fsp; struct file_id file_id; *need_close = false; if (!VALID_STAT(smb_fname->st)) { return NT_STATUS_INVALID_PARAMETER; } file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st); for(fsp = file_find_di_first(conn->sconn, file_id); fsp; fsp = file_find_di_next(fsp)) { if (fsp->fh->fd != -1) { *ret_fsp = fsp; return NT_STATUS_OK; } } /* Opens an INTERNAL_OPEN_ONLY write handle. */ status = SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ smb_fname, /* fname */ FILE_WRITE_DATA, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ FILE_SHARE_DELETE), FILE_OPEN, /* create_disposition*/ 0, /* create_options */ 0, /* file_attributes */ INTERNAL_OPEN_ONLY, /* oplock_request */ NULL, /* lease */ 0, /* allocation_size */ 0, /* private_flags */ NULL, /* sd */ NULL, /* ea_list */ ret_fsp, /* result */ NULL, /* pinfo */ NULL, NULL); /* create context */ if (NT_STATUS_IS_OK(status)) { *need_close = true; } return status; }
static files_struct *irix_oplock_receive_message(fd_set *fds) { extern int smb_read_error; oplock_stat_t os; char dummy; files_struct *fsp; /* Ensure we only get one call per select fd set. */ FD_CLR(oplock_pipe_read, fds); /* * Read one byte of zero to clear the * kernel break notify message. */ if(read(oplock_pipe_read, &dummy, 1) != 1) { DEBUG(0,("irix_oplock_receive_message: read of kernel " "notification failed. Error was %s.\n", strerror(errno) )); smb_read_error = READ_ERROR; return NULL; } /* * Do a query to get the * device and inode of the file that has the break * request outstanding. */ if(sys_fcntl_ptr(oplock_pipe_read, F_OPLKSTAT, &os) < 0) { DEBUG(0,("irix_oplock_receive_message: fcntl of kernel " "notification failed. Error was %s.\n", strerror(errno) )); if(errno == EAGAIN) { /* * Duplicate kernel break message - ignore. */ return NULL; } smb_read_error = READ_ERROR; return NULL; } /* * We only have device and inode info here - we have to guess that this * is the first fsp open with this dev,ino pair. */ if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev, (SMB_INO_T)os.os_ino)) == NULL) { DEBUG(0,("irix_oplock_receive_message: unable to find open " "file with dev = %x, inode = %.0f\n", (unsigned int)os.os_dev, (double)os.os_ino )); return NULL; } DEBUG(5,("irix_oplock_receive_message: kernel oplock break request " "received for dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id )); return fsp; }
static files_struct *irix_oplock_receive_message(struct kernel_oplocks *_ctx) { struct irix_oplocks_context *ctx = talloc_get_type(_ctx->private_data, struct irix_oplocks_context); oplock_stat_t os; char dummy; struct file_id fileid; files_struct *fsp; /* * TODO: is it correct to assume we only get one * oplock break, for each byte we read from the pipe? */ ctx->pending = false; /* * Read one byte of zero to clear the * kernel break notify message. */ if(read(ctx->read_fd, &dummy, 1) != 1) { DEBUG(0,("irix_oplock_receive_message: read of kernel " "notification failed. Error was %s.\n", strerror(errno) )); return NULL; } /* * Do a query to get the * device and inode of the file that has the break * request outstanding. */ if(sys_fcntl_ptr(ctx->read_fd, F_OPLKSTAT, &os) < 0) { DEBUG(0,("irix_oplock_receive_message: fcntl of kernel " "notification failed. Error was %s.\n", strerror(errno) )); if(errno == EAGAIN) { /* * Duplicate kernel break message - ignore. */ return NULL; } return NULL; } /* * We only have device and inode info here - we have to guess that this * is the first fsp open with this dev,ino pair. * * NOTE: this doesn't work if any VFS modules overloads * the file_id_create() hook! */ fileid = file_id_create_dev((SMB_DEV_T)os.os_dev, (SMB_INO_T)os.os_ino); if ((fsp = file_find_di_first(smbd_server_conn, fileid)) == NULL) { DEBUG(0,("irix_oplock_receive_message: unable to find open " "file with dev = %x, inode = %.0f\n", (unsigned int)os.os_dev, (double)os.os_ino )); return NULL; } DEBUG(5,("irix_oplock_receive_message: kernel oplock break request " "received for file_id %s gen_id = %ul", file_id_string_tos(&fsp->file_id), fsp->fh->gen_id )); return fsp; }
static int acl_common_remove_object(vfs_handle_struct *handle, const char *path, bool is_directory) { connection_struct *conn = handle->conn; struct file_id id; files_struct *fsp = NULL; int ret = 0; char *parent_dir = NULL; const char *final_component = NULL; struct smb_filename local_fname; int saved_errno = 0; if (!parent_dirname(talloc_tos(), path, &parent_dir, &final_component)) { saved_errno = ENOMEM; goto out; } DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n", is_directory ? "directory" : "file", parent_dir, final_component )); /* cd into the parent dir to pin it. */ ret = SMB_VFS_CHDIR(conn, parent_dir); if (ret == -1) { saved_errno = errno; goto out; } ZERO_STRUCT(local_fname); local_fname.base_name = CONST_DISCARD(char *,final_component); /* Must use lstat here. */ ret = SMB_VFS_LSTAT(conn, &local_fname); if (ret == -1) { saved_errno = errno; goto out; } /* Ensure we have this file open with DELETE access. */ id = vfs_file_id_from_sbuf(conn, &local_fname.st); for (fsp = file_find_di_first(id); fsp; file_find_di_next(fsp)) { if (fsp->access_mask & DELETE_ACCESS && fsp->delete_on_close) { /* We did open this for delete, * allow the delete as root. */ break; } } if (!fsp) { DEBUG(10,("acl_common_remove_object: %s %s/%s " "not an open file\n", is_directory ? "directory" : "file", parent_dir, final_component )); saved_errno = EACCES; goto out; } become_root(); if (is_directory) { ret = SMB_VFS_NEXT_RMDIR(handle, final_component); } else { ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname); } unbecome_root(); if (ret == -1) { saved_errno = errno; } out: TALLOC_FREE(parent_dir); vfs_ChDir(conn, conn->connectpath); if (saved_errno) { errno = saved_errno; } return ret; }