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