Exemplo n.º 1
0
struct byte_range_lock *do_lock(files_struct *fsp,
			uint32 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			BOOL blocking_lock,
			NTSTATUS *perr,
			uint32 *plock_pid)
{
	struct byte_range_lock *br_lck = NULL;

	if (!fsp->can_lock) {
		*perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
		return NULL;
	}

	if (!lp_locking(fsp->conn->params)) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(NULL, fsp);
	if (!br_lck) {
		*perr = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	*perr = brl_lock(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count, 
			lock_type,
			lock_flav,
			blocking_lock,
			plock_pid);

	if (lock_flav == WINDOWS_LOCK &&
			fsp->current_lock_count != NO_LOCKING_COUNT) {
		/* blocking ie. pending, locks also count here,
		 * as this is an efficiency counter to avoid checking
		 * the lock db. on close. JRA. */

		fsp->current_lock_count++;
	} else {
		/* Notice that this has had a POSIX lock request.
		 * We can't count locks after this so forget them.
		 */
		fsp->current_lock_count = NO_LOCKING_COUNT;
	}

	return br_lck;
}
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
NTSTATUS do_lock(files_struct *fsp,
			uint16 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			BOOL *my_lock_ctx)
{
	struct byte_range_lock *br_lck = NULL;
	NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;

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

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

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	status = brl_lock(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count, 
			lock_type,
			lock_flav,
			my_lock_ctx);

	byte_range_lock_destructor(br_lck);
	return status;
}
Exemplo n.º 4
0
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
		struct smb_request *req,
		files_struct *fsp,
		int lock_timeout,
		int lock_num,
		uint32_t lock_pid,
		enum brl_type lock_type,
		enum brl_flavour lock_flav,
		uint64_t offset,
		uint64_t count,
		uint32_t blocking_pid)
{
	struct blocking_lock_record *blr;
	NTSTATUS status;

	if(req_is_in_chain(req)) {
		DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
		return False;
	}

	/*
	 * Now queue an entry on the blocking lock queue. We setup
	 * the expiration time here.
	 */

	blr = talloc(NULL, struct blocking_lock_record);
	if (blr == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
		return False;
	}

	blr->next = NULL;
	blr->prev = NULL;

	blr->fsp = fsp;
	if (lock_timeout == -1) {
		blr->expire_time.tv_sec = 0;
		blr->expire_time.tv_usec = 0; /* Never expire. */
	} else {
		blr->expire_time = timeval_current_ofs(lock_timeout/1000,
					(lock_timeout % 1000) * 1000);
	}
	blr->lock_num = lock_num;
	blr->lock_pid = lock_pid;
	blr->blocking_pid = blocking_pid;
	blr->lock_flav = lock_flav;
	blr->lock_type = lock_type;
	blr->offset = offset;
	blr->count = count;
      
	/* Specific brl_lock() implementations can fill this in. */
	blr->blr_private = NULL;

	/* Add a pending lock record for this. */
	status = brl_lock(smbd_messaging_context(),
			br_lck,
			lock_pid,
			procid_self(),
			offset,
			count,
			lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
			blr->lock_flav,
			lock_timeout ? True : False, /* blocking_lock. */
			NULL,
			blr);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
		TALLOC_FREE(blr);
		return False;
	}

	SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
	blr->req = talloc_move(blr, &req);

	DLIST_ADD_END(blocking_lock_queue, blr, struct blocking_lock_record *);
	recalc_brl_timeout();

	/* Ensure we'll receive messages when this is unlocked. */
	if (!blocking_lock_unlock_state) {
		messaging_register(smbd_messaging_context(), NULL,
				   MSG_SMB_UNLOCK, received_unlock_msg);
		blocking_lock_unlock_state = true;
	}

	DEBUG(3,("push_blocking_lock_request: lock request blocked with "
		"expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
		(unsigned int)blr->expire_time.tv_sec,
		(unsigned int)blr->expire_time.tv_usec, lock_timeout,
		blr->fsp->fnum, blr->fsp->fsp_name ));

	return True;
}
Exemplo n.º 5
0
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
		int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count)
{
	static BOOL set_lock_msg;
	blocking_lock_record *blr, *tmp;
	BOOL my_lock_ctx = False;
	NTSTATUS status;

	if(in_chained_smb() ) {
		DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
		return False;
	}

	/*
	 * Now queue an entry on the blocking lock queue. We setup
	 * the expiration time here.
	 */

	if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
		return False;
	}

	if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
		SAFE_FREE(blr);
		return False;
	}

	blr->com_type = CVAL(inbuf,smb_com);
	blr->fsp = get_fsp_from_pkt(inbuf);
	blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
	blr->lock_num = lock_num;
	blr->lock_pid = lock_pid;
	blr->offset = offset;
	blr->count = count;
	memcpy(blr->inbuf, inbuf, length);
	blr->length = length;

	/* Add a pending lock record for this. */
	status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
			lock_pid, sys_getpid(), blr->fsp->conn->cnum,
			offset, count, PENDING_LOCK, &my_lock_ctx);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
		free_blocking_lock_record(blr);
		return False;
	}

	DLIST_ADD_END(blocking_lock_queue, blr, tmp);

	/* Ensure we'll receive messages when this is unlocked. */
	if (!set_lock_msg) {
		message_register(MSG_SMB_UNLOCK, received_unlock_msg);
		set_lock_msg = True;
	}

	DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
		blr->fsp->fnum, blr->fsp->fsp_name ));

	/* Push the MID of this packet on the signing queue. */
	srv_defer_sign_response(SVAL(inbuf,smb_mid));

	return True;
}
Exemplo n.º 6
0
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
		struct smb_request *req,
		files_struct *fsp,
		int lock_timeout,
		int lock_num,
		uint64_t smblctx,
		enum brl_type lock_type,
		enum brl_flavour lock_flav,
		uint64_t offset,
		uint64_t count,
		uint64_t blocking_smblctx)
{
	struct smbd_server_connection *sconn = req->sconn;
	struct blocking_lock_record *blr;
	NTSTATUS status;

	if (req->smb2req) {
		return push_blocking_lock_request_smb2(br_lck,
				req,
				fsp,
				lock_timeout,
				lock_num,
				smblctx,
				lock_type,
				lock_flav,
				offset,
				count,
				blocking_smblctx);
	}

	if(req_is_in_chain(req)) {
		DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
		return False;
	}

	/*
	 * Now queue an entry on the blocking lock queue. We setup
	 * the expiration time here.
	 */

	blr = talloc(NULL, struct blocking_lock_record);
	if (blr == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
		return False;
	}

	blr->next = NULL;
	blr->prev = NULL;

	blr->fsp = fsp;
	if (lock_timeout == -1) {
		blr->expire_time.tv_sec = 0;
		blr->expire_time.tv_usec = 0; /* Never expire. */
	} else {
		blr->expire_time = timeval_current_ofs_msec(lock_timeout);
	}
	blr->lock_num = lock_num;
	blr->smblctx = smblctx;
	blr->blocking_smblctx = blocking_smblctx;
	blr->lock_flav = lock_flav;
	blr->lock_type = lock_type;
	blr->offset = offset;
	blr->count = count;

	/* Specific brl_lock() implementations can fill this in. */
	blr->blr_private = NULL;

	/* Add a pending lock record for this. */
	status = brl_lock(req->sconn->msg_ctx,
			br_lck,
			smblctx,
			messaging_server_id(req->sconn->msg_ctx),
			offset,
			count,
			lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
			blr->lock_flav,
			True,
			NULL,
			blr);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
		TALLOC_FREE(blr);
		return False;
	}

	SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
	blr->req = talloc_move(blr, &req);

	DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr, struct blocking_lock_record *);
	recalc_brl_timeout(sconn);

	/* Ensure we'll receive messages when this is unlocked. */
	if (!sconn->smb1.locks.blocking_lock_unlock_state) {
		messaging_register(sconn->msg_ctx, sconn,
				   MSG_SMB_UNLOCK, received_unlock_msg);
		sconn->smb1.locks.blocking_lock_unlock_state = true;
	}

	DEBUG(3,("push_blocking_lock_request: lock request blocked with "
		"expiry time (%u sec. %u usec) (+%d msec) for %s, name = %s\n",
		(unsigned int)blr->expire_time.tv_sec,
		(unsigned int)blr->expire_time.tv_usec, lock_timeout,
		fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp)));

	return True;
}
Exemplo n.º 7
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.º 8
0
struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
			files_struct *fsp,
			uint64_t smblctx,
			uint64_t count,
			uint64_t offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			bool blocking_lock,
			NTSTATUS *perr,
			uint64_t *psmblctx,
			struct blocking_lock_record *blr)
{
	struct byte_range_lock *br_lck = NULL;

	/* silently return ok on print files as we don't do locking there */
	if (fsp->print_file) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	if (!fsp->can_lock) {
		*perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
		return NULL;
	}

	if (!lp_locking(fsp->conn->params)) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
		"blocking_lock=%s requested for %s file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, blocking_lock ? "true" :
		"false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));

	br_lck = brl_get_locks(talloc_tos(), fsp);
	if (!br_lck) {
		*perr = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	*perr = brl_lock(msg_ctx,
			br_lck,
			smblctx,
			messaging_server_id(fsp->conn->sconn->msg_ctx),
			offset,
			count,
			lock_type,
			lock_flav,
			blocking_lock,
			psmblctx,
			blr);

	DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));

	increment_current_lock_count(fsp, lock_flav);
	return br_lck;
}