Exemplo n.º 1
0
BOOL is_locked(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	       SMB_BIG_UINT count, SMB_BIG_UINT offset,
	       enum brl_type lock_type)
{
	int snum = conn->snum;
	BOOL ret;

	if (count == 0)
		return (False);

	if (!lp_locking(snum) || !lp_strict_locking(snum))
		return (False);

	ret = !brl_locktest(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			    smbpid, sys_getpid(), conn->snum,
			    offset, count, lock_type);

	/*
	 * There is no lock held by an SMB daemon, check to
	 * see if there is a POSIX lock from a UNIX or NFS process.
	 */

	if (!ret && lp_posix_locking(snum))
		ret = is_posix_locked(fsp, offset, count, lock_type);

	return ret;
}
Exemplo n.º 2
0
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;

	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 ));

	if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
		status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
				  lock_pid, sys_getpid(), conn->cnum,
				  offset, count,
				  lock_type);

		if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {

			/*
			 * Try and get a POSIX lock on this range.
			 * Note that this is ok if it is a read lock
			 * overlapping on a different fd. JRA.
			 */

			if (!set_posix_lock(fsp, offset, count, lock_type)) {
				status = NT_STATUS_LOCK_NOT_GRANTED;
				/*
				 * We failed to map - we must now remove the brl
				 * lock entry.
				 */
				(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
								lock_pid, sys_getpid(), conn->cnum,
								offset, count, False);
			}
		}
	}

	return status;
}
Exemplo n.º 3
0
BOOL do_unlock(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	       SMB_BIG_UINT count, SMB_BIG_UINT offset, uint32 *err)
{
	BOOL ok = False;

	if (!lp_locking(conn->snum))
		return (True);

	if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn))
	{
		*err = NT_STATUS_NOT_LOCKED;
		return False;
	}

	DEBUG(10,
	      ("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
	       (double)offset, (double)count, smbstrA(fsp->fsp_name)));

	/*
	 * Remove the existing lock record from the tdb lockdb
	 * before looking at POSIX locks. If this record doesn't
	 * match then don't bother looking to remove POSIX locks.
	 */

	ok = brl_unlock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			smbpid, sys_getpid(), conn->snum, offset,
			count);

	if (!ok)
	{
		DEBUG(10, ("do_unlock: returning ERRlock.\n"));
		*err = NT_STATUS_RANGE_NOT_LOCKED;
		return False;
	}

	if (!lp_posix_locking(conn->snum))
		return True;

	(void)release_posix_lock(fsp, offset, count);

	return True;		/* Did unlock */
}
Exemplo n.º 4
0
void locking_close_file(files_struct *fsp)
{
	pid_t pid = sys_getpid();

	if (!lp_locking(SNUM(fsp->conn)))
		return;

	/*
	 * Just release all the brl locks, no need to release individually.
	 */

	brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);

	if(lp_posix_locking(SNUM(fsp->conn))) {

		/*
		 * Release all the POSIX locks.
		 */
		posix_locking_close_file(fsp);

	}
}
Exemplo n.º 5
0
void locking_close_file(files_struct *fsp)
{
	struct byte_range_lock *br_lck;
	struct process_id pid = procid_self();

	if (!lp_locking(SNUM(fsp->conn)))
		return;

	/*
	 * Just release all the brl locks, no need to release individually.
	 */

	br_lck = brl_get_locks(fsp);
	if (br_lck) {
		brl_close_fnum(br_lck, pid);
		byte_range_lock_destructor(br_lck);
	}

	if(lp_posix_locking(SNUM(fsp->conn))) {
	 	/* Release all the POSIX locks.*/
		posix_locking_close_file(fsp);

	}
}
Exemplo n.º 6
0
BOOL is_locked(files_struct *fsp,connection_struct *conn,
	       SMB_BIG_UINT count,SMB_BIG_UINT offset,
	       enum brl_type lock_type, BOOL check_self)
{
	int snum = SNUM(conn);
	BOOL ret;

	if (count == 0)
		return(False);

	if (!lp_locking(snum) || !lp_strict_locking(snum))
		return(False);

	ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
			     global_smbpid, sys_getpid(), conn->cnum,
			     offset, count, lock_type, check_self);

	DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
			(double)offset, (double)count, ret ? "locked" : "unlocked",
			fsp->fsp_name ));

	/*
	 * There is no lock held by an SMB daemon, check to
	 * see if there is a POSIX lock from a UNIX or NFS process.
	 */

	if(!ret && lp_posix_locking(snum)) {
		ret = is_posix_locked(fsp, offset, count, lock_type);

		DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
				(double)offset, (double)count, ret ? "locked" : "unlocked",
				fsp->fsp_name ));
	}

	return ret;
}
Exemplo n.º 7
0
NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
		   SMB_BIG_UINT count,SMB_BIG_UINT offset)
{
	BOOL ok = False;

	if (!lp_locking(SNUM(conn)))
		return NT_STATUS_OK;

	if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
		return NT_STATUS_INVALID_HANDLE;
	}

	DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
		  (double)offset, (double)count, fsp->fsp_name ));

	/*
	 * Remove the existing lock record from the tdb lockdb
	 * before looking at POSIX locks. If this record doesn't
	 * match then don't bother looking to remove POSIX locks.
	 */

	ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
			lock_pid, sys_getpid(), conn->cnum, offset, count, False);

	if (!ok) {
		DEBUG(10,("do_unlock: returning ERRlock.\n" ));
		return NT_STATUS_RANGE_NOT_LOCKED;
	}

	if (!lp_posix_locking(SNUM(conn)))
		return NT_STATUS_OK;

	(void)release_posix_lock(fsp, offset, count);

	return NT_STATUS_OK;
}
Exemplo n.º 8
0
BOOL do_lock(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	     SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type,
	     uint32 *err)
{
	BOOL ok = False;

	if (!lp_locking(conn->snum))
		return (True);

	if (count == 0)
	{
		*err = NT_STATUS_ACCESS_DENIED;
		return False;
	}

	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,
	       smbstrA(fsp->fsp_name)));

	if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
	{
		ok = brl_lock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			      smbpid, sys_getpid(), conn->snum,
			      offset, count, lock_type);

		if (ok && lp_posix_locking(conn->snum))
		{

			/*
			 * Try and get a POSIX lock on this range.
			 * Note that this is ok if it is a read lock
			 * overlapping on a different fd. JRA.
			 */

			ok = set_posix_lock(fsp, offset, count, lock_type);

			if (!ok)
			{
				/*
				 * We failed to map - we must now remove the brl
				 * lock entry.
				 */
				
					(void)brl_unlock(fsp->sbuf.st_dev,
							 fsp->sbuf.st_ino,
							 fsp->fnum,
							 smbpid,
							 sys_getpid(),
							 conn->snum, offset,
							 count);
			}
		}
	}

	if (!ok)
	{
		*err = NT_STATUS_LOCK_NOT_GRANTED;
		return False;
	}
	return True;		/* Got lock */
}
Exemplo n.º 9
0
Arquivo: durable.c Projeto: hef/samba
NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
				    TALLOC_CTX *mem_ctx,
				    DATA_BLOB *cookie_blob)
{
	struct connection_struct *conn = fsp->conn;
	enum ndr_err_code ndr_err;
	struct vfs_default_durable_cookie cookie;

	if (!lp_durable_handles(SNUM(conn))) {
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (lp_kernel_share_modes(SNUM(conn))) {
		/*
		 * We do not support durable handles
		 * if kernel share modes (flocks) are used
		 */
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (lp_kernel_oplocks(SNUM(conn))) {
		/*
		 * We do not support durable handles
		 * if kernel oplocks are used
		 */
		return NT_STATUS_NOT_SUPPORTED;
	}

	if ((fsp->current_lock_count > 0) &&
	    lp_posix_locking(fsp->conn->params))
	{
		/*
		 * We do not support durable handles
		 * if the handle has posix locks.
		 */
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (fsp->is_directory) {
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (fsp->fh->fd == -1) {
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (is_ntfs_stream_smb_fname(fsp->fsp_name)) {
		/*
		 * We do not support durable handles
		 * on streams for now.
		 */
		return NT_STATUS_NOT_SUPPORTED;
	}

	if (is_fake_file(fsp->fsp_name)) {
		/*
		 * We do not support durable handles
		 * on fake files.
		 */
		return NT_STATUS_NOT_SUPPORTED;
	}

	ZERO_STRUCT(cookie);
	cookie.allow_reconnect = false;
	cookie.id = fsp->file_id;
	cookie.servicepath = conn->connectpath;
	cookie.base_name = fsp->fsp_name->base_name;
	cookie.initial_allocation_size = fsp->initial_allocation_size;
	cookie.position_information = fsp->fh->position_information;
	cookie.update_write_time_triggered = fsp->update_write_time_triggered;
	cookie.update_write_time_on_close = fsp->update_write_time_on_close;
	cookie.write_time_forced = fsp->write_time_forced;
	cookie.close_write_time = fsp->close_write_time;

	cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
	cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
	cookie.stat_info.st_ex_mode = fsp->fsp_name->st.st_ex_mode;
	cookie.stat_info.st_ex_nlink = fsp->fsp_name->st.st_ex_nlink;
	cookie.stat_info.st_ex_uid = fsp->fsp_name->st.st_ex_uid;
	cookie.stat_info.st_ex_gid = fsp->fsp_name->st.st_ex_gid;
	cookie.stat_info.st_ex_rdev = fsp->fsp_name->st.st_ex_rdev;
	cookie.stat_info.st_ex_size = fsp->fsp_name->st.st_ex_size;
	cookie.stat_info.st_ex_atime = fsp->fsp_name->st.st_ex_atime;
	cookie.stat_info.st_ex_mtime = fsp->fsp_name->st.st_ex_mtime;
	cookie.stat_info.st_ex_ctime = fsp->fsp_name->st.st_ex_ctime;
	cookie.stat_info.st_ex_btime = fsp->fsp_name->st.st_ex_btime;
	cookie.stat_info.st_ex_calculated_birthtime = fsp->fsp_name->st.st_ex_calculated_birthtime;
	cookie.stat_info.st_ex_blksize = fsp->fsp_name->st.st_ex_blksize;
	cookie.stat_info.st_ex_blocks = fsp->fsp_name->st.st_ex_blocks;
	cookie.stat_info.st_ex_flags = fsp->fsp_name->st.st_ex_flags;
	cookie.stat_info.st_ex_mask = fsp->fsp_name->st.st_ex_mask;

	ndr_err = ndr_push_struct_blob(cookie_blob, mem_ctx, &cookie,
			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		return status;
	}

	return NT_STATUS_OK;
}
Exemplo n.º 10
0
int fd_close_posix(struct files_struct *fsp)
{
	int saved_errno = 0;
	int ret;
	int *fd_array = NULL;
	size_t count, i;

	if (!lp_locking(fsp->conn->params) ||
	    !lp_posix_locking(fsp->conn->params))
	{
		/*
		 * No locking or POSIX to worry about or we want POSIX semantics
		 * which will lose all locks on all fd's open on this dev/inode,
		 * just close.
		 */
		return close(fsp->fh->fd);
	}

	if (get_windows_lock_ref_count(fsp)) {

		/*
		 * There are outstanding locks on this dev/inode pair on
		 * other fds. Add our fd to the pending close tdb and set
		 * fsp->fh->fd to -1.
		 */

		add_fd_to_close_entry(fsp);
		return 0;
	}

	/*
	 * No outstanding locks. Get the pending close fd's
	 * from the tdb and close them all.
	 */

	count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array);

	if (count) {
		DEBUG(10,("fd_close_posix: doing close on %u fd's.\n",
			  (unsigned int)count));

		for(i = 0; i < count; i++) {
			if (close(fd_array[i]) == -1) {
				saved_errno = errno;
			}
		}

		/*
		 * Delete all fd's stored in the tdb
		 * for this dev/inode pair.
		 */

		delete_close_entries(fsp);
	}

	TALLOC_FREE(fd_array);

	/* Don't need a lock ref count on this dev/ino anymore. */
	delete_windows_lock_ref_count(fsp);

	/*
	 * Finally close the fd associated with this fsp.
	 */

	ret = close(fsp->fh->fd);

	if (ret == 0 && saved_errno != 0) {
		errno = saved_errno;
		ret = -1;
	}

	return ret;
}