s3-messages: only include messages.h where needed.
[obnox/samba/samba-obnox.git] / source3 / smbd / blocking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Blocking Locking functions
4    Copyright (C) Jeremy Allison 1998-2003
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "smbd/smbd.h"
22 #include "smbd/globals.h"
23 #include "librpc/gen_ndr/messaging.h"
24 #include "messages.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_LOCKING
28
29 /****************************************************************************
30  Determine if this is a secondary element of a chained SMB.
31   **************************************************************************/
32
33 static void received_unlock_msg(struct messaging_context *msg,
34                                 void *private_data,
35                                 uint32_t msg_type,
36                                 struct server_id server_id,
37                                 DATA_BLOB *data);
38
39 void brl_timeout_fn(struct event_context *event_ctx,
40                            struct timed_event *te,
41                            struct timeval now,
42                            void *private_data)
43 {
44         struct smbd_server_connection *sconn = talloc_get_type_abort(
45                 private_data, struct smbd_server_connection);
46
47         if (sconn->using_smb2) {
48                 SMB_ASSERT(sconn->smb2.locks.brl_timeout == te);
49                 TALLOC_FREE(sconn->smb2.locks.brl_timeout);
50         } else {
51                 SMB_ASSERT(sconn->smb1.locks.brl_timeout == te);
52                 TALLOC_FREE(sconn->smb1.locks.brl_timeout);
53         }
54
55         change_to_root_user();  /* TODO: Possibly run all timed events as
56                                  * root */
57
58         process_blocking_lock_queue(sconn);
59 }
60
61 /****************************************************************************
62  We need a version of timeval_min that treats zero timval as infinite.
63 ****************************************************************************/
64
65 struct timeval timeval_brl_min(const struct timeval *tv1,
66                                         const struct timeval *tv2)
67 {
68         if (timeval_is_zero(tv1)) {
69                 return *tv2;
70         }
71         if (timeval_is_zero(tv2)) {
72                 return *tv1;
73         }
74         return timeval_min(tv1, tv2);
75 }
76
77 /****************************************************************************
78  After a change to blocking_lock_queue, recalculate the timed_event for the
79  next processing.
80 ****************************************************************************/
81
82 static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
83 {
84         struct blocking_lock_record *blr;
85         struct timeval next_timeout;
86         int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5);
87
88         TALLOC_FREE(sconn->smb1.locks.brl_timeout);
89
90         next_timeout = timeval_zero();
91
92         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
93                 if (timeval_is_zero(&blr->expire_time)) {
94                         /*
95                          * If we're blocked on pid 0xFFFFFFFFFFFFFFFFLL this is
96                          * a POSIX lock, so calculate a timeout of
97                          * 10 seconds into the future.
98                          */
99                         if (blr->blocking_smblctx == 0xFFFFFFFFFFFFFFFFLL) {
100                                 struct timeval psx_to = timeval_current_ofs(10, 0);
101                                 next_timeout = timeval_brl_min(&next_timeout, &psx_to);
102                         }
103
104                         continue;
105                 }
106
107                 next_timeout = timeval_brl_min(&next_timeout, &blr->expire_time);
108         }
109
110         if (timeval_is_zero(&next_timeout)) {
111                 DEBUG(10, ("Next timeout = Infinite.\n"));
112                 return True;
113         }
114
115         /* 
116          to account for unclean shutdowns by clients we need a
117          maximum timeout that we use for checking pending locks. If
118          we have any pending locks at all, then check if the pending
119          lock can continue at least every brl:recalctime seconds
120          (default 5 seconds).
121
122          This saves us needing to do a message_send_all() in the
123          SIGCHLD handler in the parent daemon. That
124          message_send_all() caused O(n^2) work to be done when IP
125          failovers happened in clustered Samba, which could make the
126          entire system unusable for many minutes.
127         */
128
129         if (max_brl_timeout > 0) {
130                 struct timeval min_to = timeval_current_ofs(max_brl_timeout, 0);
131                 next_timeout = timeval_min(&next_timeout, &min_to);
132         }
133
134         if (DEBUGLVL(10)) {
135                 struct timeval cur, from_now;
136
137                 cur = timeval_current();
138                 from_now = timeval_until(&cur, &next_timeout);
139                 DEBUG(10, ("Next timeout = %d.%d seconds from now.\n",
140                     (int)from_now.tv_sec, (int)from_now.tv_usec));
141         }
142
143         sconn->smb1.locks.brl_timeout = event_add_timed(smbd_event_context(),
144                                                         NULL, next_timeout,
145                                                         brl_timeout_fn, sconn);
146         if (sconn->smb1.locks.brl_timeout == NULL) {
147                 return False;
148         }
149
150         return True;
151 }
152
153
154 /****************************************************************************
155  Function to push a blocking lock request onto the lock queue.
156 ****************************************************************************/
157
158 bool push_blocking_lock_request( struct byte_range_lock *br_lck,
159                 struct smb_request *req,
160                 files_struct *fsp,
161                 int lock_timeout,
162                 int lock_num,
163                 uint64_t smblctx,
164                 enum brl_type lock_type,
165                 enum brl_flavour lock_flav,
166                 uint64_t offset,
167                 uint64_t count,
168                 uint64_t blocking_smblctx)
169 {
170         struct smbd_server_connection *sconn = req->sconn;
171         struct blocking_lock_record *blr;
172         NTSTATUS status;
173
174         if (req->smb2req) {
175                 return push_blocking_lock_request_smb2(br_lck,
176                                 req,
177                                 fsp,
178                                 lock_timeout,
179                                 lock_num,
180                                 smblctx,
181                                 lock_type,
182                                 lock_flav,
183                                 offset,
184                                 count,
185                                 blocking_smblctx);
186         }
187
188         if(req_is_in_chain(req)) {
189                 DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
190                 return False;
191         }
192
193         /*
194          * Now queue an entry on the blocking lock queue. We setup
195          * the expiration time here.
196          */
197
198         blr = talloc(NULL, struct blocking_lock_record);
199         if (blr == NULL) {
200                 DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
201                 return False;
202         }
203
204         blr->next = NULL;
205         blr->prev = NULL;
206
207         blr->fsp = fsp;
208         if (lock_timeout == -1) {
209                 blr->expire_time.tv_sec = 0;
210                 blr->expire_time.tv_usec = 0; /* Never expire. */
211         } else {
212                 blr->expire_time = timeval_current_ofs(lock_timeout/1000,
213                                         (lock_timeout % 1000) * 1000);
214         }
215         blr->lock_num = lock_num;
216         blr->smblctx = smblctx;
217         blr->blocking_smblctx = blocking_smblctx;
218         blr->lock_flav = lock_flav;
219         blr->lock_type = lock_type;
220         blr->offset = offset;
221         blr->count = count;
222       
223         /* Specific brl_lock() implementations can fill this in. */
224         blr->blr_private = NULL;
225
226         /* Add a pending lock record for this. */
227         status = brl_lock(req->sconn->msg_ctx,
228                         br_lck,
229                         smblctx,
230                         sconn_server_id(req->sconn),
231                         offset,
232                         count,
233                         lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
234                         blr->lock_flav,
235                         True,
236                         NULL,
237                         blr);
238
239         if (!NT_STATUS_IS_OK(status)) {
240                 DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
241                 TALLOC_FREE(blr);
242                 return False;
243         }
244
245         SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
246         blr->req = talloc_move(blr, &req);
247
248         DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr, struct blocking_lock_record *);
249         recalc_brl_timeout(sconn);
250
251         /* Ensure we'll receive messages when this is unlocked. */
252         if (!sconn->smb1.locks.blocking_lock_unlock_state) {
253                 messaging_register(sconn->msg_ctx, NULL,
254                                    MSG_SMB_UNLOCK, received_unlock_msg);
255                 sconn->smb1.locks.blocking_lock_unlock_state = true;
256         }
257
258         DEBUG(3,("push_blocking_lock_request: lock request blocked with "
259                 "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
260                 (unsigned int)blr->expire_time.tv_sec,
261                 (unsigned int)blr->expire_time.tv_usec, lock_timeout,
262                 blr->fsp->fnum, fsp_str_dbg(blr->fsp)));
263
264         return True;
265 }
266
267 /****************************************************************************
268  Return a lockingX success SMB.
269 *****************************************************************************/
270
271 static void reply_lockingX_success(struct blocking_lock_record *blr)
272 {
273         reply_outbuf(blr->req, 2, 0);
274
275         /*
276          * As this message is a lockingX call we must handle
277          * any following chained message correctly.
278          * This is normally handled in construct_reply(),
279          * but as that calls switch_message, we can't use
280          * that here and must set up the chain info manually.
281          */
282
283         chain_reply(blr->req);
284         TALLOC_FREE(blr->req->outbuf);
285 }
286
287 /****************************************************************************
288  Return a generic lock fail error blocking call.
289 *****************************************************************************/
290
291 static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTATUS status)
292 {
293         /* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
294            FILE_LOCK_CONFLICT! (tridge) */
295         if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) {
296                 status = NT_STATUS_FILE_LOCK_CONFLICT;
297         }
298
299         if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
300                 /* Store the last lock error. */
301                 files_struct *fsp = blr->fsp;
302
303                 if (fsp) {
304                         fsp->last_lock_failure.context.smblctx = blr->smblctx;
305                         fsp->last_lock_failure.context.tid = fsp->conn->cnum;
306                         fsp->last_lock_failure.context.pid =
307                                 sconn_server_id(fsp->conn->sconn);
308                         fsp->last_lock_failure.start = blr->offset;
309                         fsp->last_lock_failure.size = blr->count;
310                         fsp->last_lock_failure.fnum = fsp->fnum;
311                         fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
312                         fsp->last_lock_failure.lock_flav = blr->lock_flav;
313                 }
314         }
315
316         reply_nterror(blr->req, status);
317         if (!srv_send_smb(blr->req->sconn, (char *)blr->req->outbuf,
318                           true, blr->req->seqnum+1,
319                           blr->req->encrypted, NULL)) {
320                 exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
321         }
322         TALLOC_FREE(blr->req->outbuf);
323 }
324
325 /****************************************************************************
326  Return a lock fail error for a lockingX call. Undo all the locks we have 
327  obtained first.
328 *****************************************************************************/
329
330 static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)
331 {
332         files_struct *fsp = blr->fsp;
333         uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
334         uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
335         uint64_t smblctx;
336         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
337         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
338         uint8_t *data;
339         int i;
340
341         data = (uint8_t *)blr->req->buf
342                 + ((large_file_format ? 20 : 10)*num_ulocks);
343
344         /* 
345          * Data now points at the beginning of the list
346          * of smb_lkrng structs.
347          */
348
349         /*
350          * Ensure we don't do a remove on the lock that just failed,
351          * as under POSIX rules, if we have a lock already there, we
352          * will delete it (and we shouldn't) .....
353          */
354
355         for(i = blr->lock_num - 1; i >= 0; i--) {
356                 bool err;
357
358                 smblctx = get_lock_pid( data, i, large_file_format);
359                 count = get_lock_count( data, i, large_file_format);
360                 offset = get_lock_offset( data, i, large_file_format, &err);
361
362                 /*
363                  * We know err cannot be set as if it was the lock
364                  * request would never have been queued. JRA.
365                  */
366
367                 do_unlock(fsp->conn->sconn->msg_ctx,
368                         fsp,
369                         smblctx,
370                         count,
371                         offset,
372                         WINDOWS_LOCK);
373         }
374
375         generic_blocking_lock_error(blr, status);
376 }
377
378 /****************************************************************************
379  Return a lock fail error.
380 *****************************************************************************/
381
382 static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS status)
383 {
384         DEBUG(10, ("Replying with error=%s. BLR = %p\n", nt_errstr(status), blr));
385
386         switch(blr->req->cmd) {
387         case SMBlockingX:
388                 reply_lockingX_error(blr, status);
389                 break;
390         case SMBtrans2:
391         case SMBtranss2:
392                 reply_nterror(blr->req, status);
393
394                 /*
395                  * construct_reply_common has done us the favor to pre-fill
396                  * the command field with SMBtranss2 which is wrong :-)
397                  */
398                 SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
399
400                 if (!srv_send_smb(blr->req->sconn,
401                                   (char *)blr->req->outbuf,
402                                   true, blr->req->seqnum+1,
403                                   IS_CONN_ENCRYPTED(blr->fsp->conn),
404                                   NULL)) {
405                         exit_server_cleanly("blocking_lock_reply_error: "
406                                             "srv_send_smb failed.");
407                 }
408                 TALLOC_FREE(blr->req->outbuf);
409                 break;
410         default:
411                 DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
412                 exit_server("PANIC - unknown type on blocking lock queue");
413         }
414 }
415
416 /****************************************************************************
417  Attempt to finish off getting all pending blocking locks for a lockingX call.
418  Returns True if we want to be removed from the list.
419 *****************************************************************************/
420
421 static bool process_lockingX(struct blocking_lock_record *blr)
422 {
423         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
424         files_struct *fsp = blr->fsp;
425         uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
426         uint16 num_locks = SVAL(blr->req->vwv+7, 0);
427         uint64_t count = (uint64_t)0, offset = (uint64_t)0;
428         uint64_t smblctx;
429         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
430         uint8_t *data;
431         NTSTATUS status = NT_STATUS_OK;
432
433         data = (uint8_t *)blr->req->buf
434                 + ((large_file_format ? 20 : 10)*num_ulocks);
435
436         /* 
437          * Data now points at the beginning of the list
438          * of smb_lkrng structs.
439          */
440
441         for(; blr->lock_num < num_locks; blr->lock_num++) {
442                 struct byte_range_lock *br_lck = NULL;
443                 bool err;
444
445                 smblctx = get_lock_pid( data, blr->lock_num, large_file_format);
446                 count = get_lock_count( data, blr->lock_num, large_file_format);
447                 offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
448
449                 /*
450                  * We know err cannot be set as if it was the lock
451                  * request would never have been queued. JRA.
452                  */
453                 errno = 0;
454                 br_lck = do_lock(fsp->conn->sconn->msg_ctx,
455                                 fsp,
456                                 smblctx,
457                                 count,
458                                 offset,
459                                 ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
460                                         READ_LOCK : WRITE_LOCK),
461                                 WINDOWS_LOCK,
462                                 True,
463                                 &status,
464                                 &blr->blocking_smblctx,
465                                 blr);
466
467                 TALLOC_FREE(br_lck);
468
469                 if (NT_STATUS_IS_ERR(status)) {
470                         break;
471                 }
472         }
473
474         if(blr->lock_num == num_locks) {
475                 /*
476                  * Success - we got all the locks.
477                  */
478
479                 DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
480                          "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
481                          (unsigned int)locktype, num_locks));
482
483                 reply_lockingX_success(blr);
484                 return True;
485         }
486
487         if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
488             !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
489                 /*
490                  * We have other than a "can't get lock"
491                  * error. Free any locks we had and return an error.
492                  * Return True so we get dequeued.
493                  */
494                 blocking_lock_reply_error(blr, status);
495                 return True;
496         }
497
498         /*
499          * Still can't get all the locks - keep waiting.
500          */
501
502         DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
503 Waiting....\n", 
504                  blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
505
506         return False;
507 }
508
509 /****************************************************************************
510  Attempt to get the posix lock request from a SMBtrans2 call.
511  Returns True if we want to be removed from the list.
512 *****************************************************************************/
513
514 static bool process_trans2(struct blocking_lock_record *blr)
515 {
516         char params[2];
517         NTSTATUS status;
518         struct byte_range_lock *br_lck = do_lock(
519                                                 blr->fsp->conn->sconn->msg_ctx,
520                                                 blr->fsp,
521                                                 blr->smblctx,
522                                                 blr->count,
523                                                 blr->offset,
524                                                 blr->lock_type,
525                                                 blr->lock_flav,
526                                                 True,
527                                                 &status,
528                                                 &blr->blocking_smblctx,
529                                                 blr);
530         TALLOC_FREE(br_lck);
531
532         if (!NT_STATUS_IS_OK(status)) {
533                 if (ERROR_WAS_LOCK_DENIED(status)) {
534                         /* Still can't get the lock, just keep waiting. */
535                         return False;
536                 }       
537                 /*
538                  * We have other than a "can't get lock"
539                  * error. Send an error and return True so we get dequeued.
540                  */
541                 blocking_lock_reply_error(blr, status);
542                 return True;
543         }
544
545         /* We finally got the lock, return success. */
546
547         SSVAL(params,0,0);
548         /* Fake up max_data_bytes here - we know it fits. */
549         send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
550         return True;
551 }
552
553
554 /****************************************************************************
555  Process a blocking lock SMB.
556  Returns True if we want to be removed from the list.
557 *****************************************************************************/
558
559 static bool blocking_lock_record_process(struct blocking_lock_record *blr)
560 {
561         switch(blr->req->cmd) {
562                 case SMBlockingX:
563                         return process_lockingX(blr);
564                 case SMBtrans2:
565                 case SMBtranss2:
566                         return process_trans2(blr);
567                 default:
568                         DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
569                         exit_server("PANIC - unknown type on blocking lock queue");
570         }
571         return False; /* Keep compiler happy. */
572 }
573
574 /****************************************************************************
575  Cancel entries by fnum from the blocking lock pending queue.
576  Called when a file is closed.
577 *****************************************************************************/
578
579 void cancel_pending_lock_requests_by_fid(files_struct *fsp,
580                         struct byte_range_lock *br_lck,
581                         enum file_close_type close_type)
582 {
583         struct smbd_server_connection *sconn = fsp->conn->sconn;
584         struct blocking_lock_record *blr, *blr_cancelled, *next = NULL;
585
586         if (sconn->using_smb2) {
587                 cancel_pending_lock_requests_by_fid_smb2(fsp,
588                                         br_lck,
589                                         close_type);
590                 return;
591         }
592
593         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
594                 unsigned char locktype = 0;
595
596                 next = blr->next;
597                 if (blr->fsp->fnum != fsp->fnum) {
598                         continue;
599                 }
600
601                 if (blr->req->cmd == SMBlockingX) {
602                         locktype = CVAL(blr->req->vwv+3, 0);
603                 }
604
605                 DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
606                            "request type %d for file %s fnum = %d\n",
607                            blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
608
609                 blr_cancelled = blocking_lock_cancel_smb1(fsp,
610                                      blr->smblctx,
611                                      blr->offset,
612                                      blr->count,
613                                      blr->lock_flav,
614                                      locktype,
615                                      NT_STATUS_RANGE_NOT_LOCKED);
616
617                 SMB_ASSERT(blr_cancelled == blr);
618
619                 brl_lock_cancel(br_lck,
620                                 blr->smblctx,
621                                 sconn_server_id(sconn),
622                                 blr->offset,
623                                 blr->count,
624                                 blr->lock_flav,
625                                 blr);
626
627                 /* We're closing the file fsp here, so ensure
628                  * we don't have a dangling pointer. */
629                 blr->fsp = NULL;
630         }
631 }
632
633 /****************************************************************************
634  Delete entries by mid from the blocking lock pending queue. Always send reply.
635  Only called from the SMB1 cancel code.
636 *****************************************************************************/
637
638 void remove_pending_lock_requests_by_mid_smb1(
639         struct smbd_server_connection *sconn, uint64_t mid)
640 {
641         struct blocking_lock_record *blr, *next = NULL;
642
643         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
644                 files_struct *fsp;
645                 struct byte_range_lock *br_lck;
646
647                 next = blr->next;
648
649                 if (blr->req->mid != mid) {
650                         continue;
651                 }
652
653                 fsp = blr->fsp;
654                 br_lck = brl_get_locks(talloc_tos(), fsp);
655
656                 if (br_lck) {
657                         DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - "
658                                    "removing request type %d for file %s fnum "
659                                    "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
660                                    fsp->fnum ));
661
662                         brl_lock_cancel(br_lck,
663                                         blr->smblctx,
664                                         sconn_server_id(sconn),
665                                         blr->offset,
666                                         blr->count,
667                                         blr->lock_flav,
668                                         blr);
669                         TALLOC_FREE(br_lck);
670                 }
671
672                 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
673                 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
674                 TALLOC_FREE(blr);
675         }
676 }
677
678 /****************************************************************************
679  Is this mid a blocking lock request on the queue ?
680  Currently only called from the SMB1 unix extensions POSIX lock code.
681 *****************************************************************************/
682
683 bool blocking_lock_was_deferred_smb1(
684         struct smbd_server_connection *sconn, uint64_t mid)
685 {
686         struct blocking_lock_record *blr, *next = NULL;
687
688         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
689                 next = blr->next;
690                 if(blr->req->mid == mid) {
691                         return True;
692                 }
693         }
694         return False;
695 }
696
697 /****************************************************************************
698   Set a flag as an unlock request affects one of our pending locks.
699 *****************************************************************************/
700
701 static void received_unlock_msg(struct messaging_context *msg,
702                                 void *private_data,
703                                 uint32_t msg_type,
704                                 struct server_id server_id,
705                                 DATA_BLOB *data)
706 {
707         struct smbd_server_connection *sconn;
708
709         sconn = msg_ctx_to_sconn(msg);
710         if (sconn == NULL) {
711                 DEBUG(1, ("could not find sconn\n"));
712                 return;
713         }
714
715         DEBUG(10,("received_unlock_msg\n"));
716         process_blocking_lock_queue(sconn);
717 }
718
719 /****************************************************************************
720  Process the blocking lock queue. Note that this is only called as root.
721 *****************************************************************************/
722
723 void process_blocking_lock_queue(struct smbd_server_connection *sconn)
724 {
725         struct timeval tv_curr = timeval_current();
726         struct blocking_lock_record *blr, *next = NULL;
727
728         if (sconn->using_smb2) {
729                 process_blocking_lock_queue_smb2(sconn, tv_curr);
730                 return;
731         }
732
733         /*
734          * Go through the queue and see if we can get any of the locks.
735          */
736
737         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
738
739                 next = blr->next;
740
741                 /*
742                  * Go through the remaining locks and try and obtain them.
743                  * The call returns True if all locks were obtained successfully
744                  * and False if we still need to wait.
745                  */
746
747                 DEBUG(10, ("Processing BLR = %p\n", blr));
748
749                 /* We use set_current_service so connections with
750                  * pending locks are not marked as idle.
751                  */
752
753                 set_current_service(blr->fsp->conn,
754                                 SVAL(blr->req->inbuf,smb_flg),
755                                 false);
756
757                 if(blocking_lock_record_process(blr)) {
758                         struct byte_range_lock *br_lck = brl_get_locks(
759                                 talloc_tos(), blr->fsp);
760
761                         DEBUG(10, ("BLR_process returned true: cancelling and "
762                             "removing lock. BLR = %p\n", blr));
763
764                         if (br_lck) {
765                                 brl_lock_cancel(br_lck,
766                                         blr->smblctx,
767                                         sconn_server_id(sconn),
768                                         blr->offset,
769                                         blr->count,
770                                         blr->lock_flav,
771                                         blr);
772                                 TALLOC_FREE(br_lck);
773                         }
774
775                         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
776                         TALLOC_FREE(blr);
777                         continue;
778                 }
779
780                 /*
781                  * We couldn't get the locks for this record on the list.
782                  * If the time has expired, return a lock error.
783                  */
784
785                 if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
786                         struct byte_range_lock *br_lck = brl_get_locks(
787                                 talloc_tos(), blr->fsp);
788
789                         DEBUG(10, ("Lock timed out! BLR = %p\n", blr));
790
791                         /*
792                          * Lock expired - throw away all previously
793                          * obtained locks and return lock error.
794                          */
795
796                         if (br_lck) {
797                                 DEBUG(5,("process_blocking_lock_queue: "
798                                          "pending lock fnum = %d for file %s "
799                                          "timed out.\n", blr->fsp->fnum,
800                                          fsp_str_dbg(blr->fsp)));
801
802                                 brl_lock_cancel(br_lck,
803                                         blr->smblctx,
804                                         sconn_server_id(sconn),
805                                         blr->offset,
806                                         blr->count,
807                                         blr->lock_flav,
808                                         blr);
809                                 TALLOC_FREE(br_lck);
810                         }
811
812                         blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
813                         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
814                         TALLOC_FREE(blr);
815                 }
816         }
817
818         recalc_brl_timeout(sconn);
819 }
820
821 /****************************************************************************
822  Handle a cancel message. Lock already moved onto the cancel queue.
823 *****************************************************************************/
824
825 #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(struct blocking_lock_record *) + sizeof(NTSTATUS))
826
827 static void process_blocking_lock_cancel_message(struct messaging_context *ctx,
828                                                  void *private_data,
829                                                  uint32_t msg_type,
830                                                  struct server_id server_id,
831                                                  DATA_BLOB *data)
832 {
833         struct smbd_server_connection *sconn;
834         NTSTATUS err;
835         const char *msg = (const char *)data->data;
836         struct blocking_lock_record *blr;
837
838         if (data->data == NULL) {
839                 smb_panic("process_blocking_lock_cancel_message: null msg");
840         }
841
842         if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) {
843                 DEBUG(0, ("process_blocking_lock_cancel_message: "
844                           "Got invalid msg len %d\n", (int)data->length));
845                 smb_panic("process_blocking_lock_cancel_message: bad msg");
846         }
847
848         sconn = msg_ctx_to_sconn(ctx);
849         if (sconn == NULL) {
850                 DEBUG(1, ("could not find sconn\n"));
851                 return;
852         }
853
854         memcpy(&blr, msg, sizeof(blr));
855         memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS));
856
857         DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n",
858                 nt_errstr(err) ));
859
860         blocking_lock_reply_error(blr, err);
861         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
862         TALLOC_FREE(blr);
863 }
864
865 /****************************************************************************
866  Send ourselves a blocking lock cancelled message. Handled asynchronously above.
867  Returns the blocking_lock_record that is being cancelled.
868  Only called from the SMB1 code.
869 *****************************************************************************/
870
871 struct blocking_lock_record *blocking_lock_cancel_smb1(files_struct *fsp,
872                         uint64_t smblctx,
873                         uint64_t offset,
874                         uint64_t count,
875                         enum brl_flavour lock_flav,
876                         unsigned char locktype,
877                         NTSTATUS err)
878 {
879         struct smbd_server_connection *sconn = fsp->conn->sconn;
880         char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE];
881         struct blocking_lock_record *blr;
882
883         if (!sconn->smb1.locks.blocking_lock_cancel_state) {
884                 /* Register our message. */
885                 messaging_register(sconn->msg_ctx, NULL,
886                                    MSG_SMB_BLOCKING_LOCK_CANCEL,
887                                    process_blocking_lock_cancel_message);
888
889                 sconn->smb1.locks.blocking_lock_cancel_state = True;
890         }
891
892         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
893                 if (fsp == blr->fsp &&
894                                 smblctx == blr->smblctx &&
895                                 offset == blr->offset &&
896                                 count == blr->count &&
897                                 lock_flav == blr->lock_flav) {
898                         break;
899                 }
900         }
901
902         if (!blr) {
903                 return NULL;
904         }
905
906         /* Check the flags are right. */
907         if (blr->req->cmd == SMBlockingX &&
908                 (locktype & LOCKING_ANDX_LARGE_FILES) !=
909                         (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
910                 return NULL;
911         }
912
913         /* Move to cancelled queue. */
914         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
915         DLIST_ADD(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
916
917         /* Create the message. */
918         memcpy(msg, &blr, sizeof(blr));
919         memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS));
920
921         messaging_send_buf(sconn->msg_ctx, sconn_server_id(sconn),
922                            MSG_SMB_BLOCKING_LOCK_CANCEL,
923                            (uint8 *)&msg, sizeof(msg));
924
925         return blr;
926 }