Пример #1
0
static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status)
{
	switch(blr->com_type) {
	case SMBlock:
	case SMBlockread:
		generic_blocking_lock_error(blr, status);
		break;
	case SMBlockingX:
		reply_lockingX_error(blr, status);
		break;
	default:
		DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
		exit_server("PANIC - unknown type on blocking lock queue");
	}
}
Пример #2
0
static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)
{
	files_struct *fsp = blr->fsp;
	uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
	uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
	uint32 lock_pid;
	unsigned char locktype = CVAL(blr->req->vwv+3, 0);
	bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
	uint8_t *data;
	int i;

	data = (uint8_t *)blr->req->buf
		+ ((large_file_format ? 20 : 10)*num_ulocks);

	/* 
	 * Data now points at the beginning of the list
	 * of smb_lkrng structs.
	 */

	/*
	 * Ensure we don't do a remove on the lock that just failed,
	 * as under POSIX rules, if we have a lock already there, we
	 * will delete it (and we shouldn't) .....
	 */

	for(i = blr->lock_num - 1; i >= 0; i--) {
		bool err;

		lock_pid = get_lock_pid( data, i, large_file_format);
		count = get_lock_count( data, i, large_file_format);
		offset = get_lock_offset( data, i, large_file_format, &err);

		/*
		 * We know err cannot be set as if it was the lock
		 * request would never have been queued. JRA.
		 */

		do_unlock(smbd_messaging_context(),
			fsp,
			lock_pid,
			count,
			offset,
			WINDOWS_LOCK);
	}

	generic_blocking_lock_error(blr, status);
}
Пример #3
0
static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
{
	char *inbuf = blr->inbuf;
	files_struct *fsp = blr->fsp;
	connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
	uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
	SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0;
	uint16 lock_pid;
	unsigned char locktype = CVAL(inbuf,smb_vwv3);
	BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
	char *data;
	int i;

	data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
	
	/* 
	 * Data now points at the beginning of the list
	 * of smb_lkrng structs.
	 */

	/*
	 * Ensure we don't do a remove on the lock that just failed,
	 * as under POSIX rules, if we have a lock already there, we
	 * will delete it (and we shouldn't) .....
	 */
	
	for(i = blr->lock_num - 1; i >= 0; i--) {
		BOOL err;
		
		lock_pid = get_lock_pid( data, i, large_file_format);
		count = get_lock_count( data, i, large_file_format);
		offset = get_lock_offset( data, i, large_file_format, &err);
		
		/*
		 * We know err cannot be set as if it was the lock
		 * request would never have been queued. JRA.
		 */
		
		do_unlock(fsp,conn,lock_pid,count,offset);
	}
	
	generic_blocking_lock_error(blr, status);
}
Пример #4
0
static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS status)
{
	DEBUG(10, ("Replying with error=%s. BLR = %p\n", nt_errstr(status), blr));

	switch(blr->req->cmd) {
	case SMBlockingX:
		/*
		 * This code can be called during the rundown of a
		 * file after it was already closed. In that case,
		 * blr->fsp==NULL and we do not need to undo any
		 * locks, they are already gone.
		 */
		if (blr->fsp != NULL) {
			undo_locks_obtained(blr);
		}
		generic_blocking_lock_error(blr, status);
		break;
	case SMBtrans2:
	case SMBtranss2:
		reply_nterror(blr->req, status);

		/*
		 * construct_reply_common has done us the favor to pre-fill
		 * the command field with SMBtranss2 which is wrong :-)
		 */
		SCVAL(blr->req->outbuf,smb_com,SMBtrans2);

		if (!srv_send_smb(blr->req->sconn,
				  (char *)blr->req->outbuf,
				  true, blr->req->seqnum+1,
				  IS_CONN_ENCRYPTED(blr->fsp->conn),
				  NULL)) {
			exit_server_cleanly("blocking_lock_reply_error: "
					    "srv_send_smb failed.");
		}
		TALLOC_FREE(blr->req->outbuf);
		break;
	default:
		DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
		exit_server("PANIC - unknown type on blocking lock queue");
	}
}
Пример #5
0
static BOOL process_lockread(blocking_lock_record *blr)
{
	char *outbuf = OutBuffer;
	char *inbuf = blr->inbuf;
	ssize_t nread = -1;
	char *data, *p;
	int outsize = 0;
	SMB_BIG_UINT startpos;
	size_t numtoread;
	NTSTATUS status;
	connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
	files_struct *fsp = blr->fsp;
	BOOL my_lock_ctx = False;

	numtoread = SVAL(inbuf,smb_vwv1);
	startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2);
	
	numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
	data = smb_buf(outbuf) + 3;
 
	status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, &my_lock_ctx);
	if (NT_STATUS_V(status)) {
		if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
			!NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
			/*
			 * We have other than a "can't get lock"
			 * error. Send an error.
			 * Return True so we get dequeued.
			 */
			generic_blocking_lock_error(blr, status);
			return True;
		}

		/*
		 * Still waiting for lock....
		 */
		
		DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n",
			  fsp->fsp_name));
		return False;
	}

	nread = read_file(fsp,data,startpos,numtoread);

	if (nread < 0) {
		generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED);
		return True;
	}
	
	construct_reply_common(inbuf, outbuf);
	outsize = set_message(outbuf,5,0,True);
	
	outsize += nread;
	SSVAL(outbuf,smb_vwv0,nread);
	SSVAL(outbuf,smb_vwv5,nread+3);
	p = smb_buf(outbuf);
	*p++ = 1;
	SSVAL(p,0,nread); p += 2;
	set_message_end(outbuf, p+nread);
	
	DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
		   fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
	
	send_blocking_reply(outbuf,outsize);
	return True;
}