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