TODO anon? s3:smb3_sesssetup: close the previous SMB2 session if requested and allowed
[metze/samba/wip.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         if (!srv_send_smb(req->sconn,
286                         (char *)req->outbuf,
287                         true, req->seqnum+1,
288                         IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
289                         &req->pcd)) {
290                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
291         }
292
293         TALLOC_FREE(req->outbuf);
294 }
295
296 /****************************************************************************
297  Return a generic lock fail error blocking call.
298 *****************************************************************************/
299
300 static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTATUS status)
301 {
302         /* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
303            FILE_LOCK_CONFLICT! (tridge) */
304         if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) {
305                 status = NT_STATUS_FILE_LOCK_CONFLICT;
306         }
307
308         if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
309                 /* Store the last lock error. */
310                 files_struct *fsp = blr->fsp;
311
312                 if (fsp) {
313                         fsp->last_lock_failure.context.smblctx = blr->smblctx;
314                         fsp->last_lock_failure.context.tid = fsp->conn->cnum;
315                         fsp->last_lock_failure.context.pid =
316                                 messaging_server_id(fsp->conn->sconn->msg_ctx);
317                         fsp->last_lock_failure.start = blr->offset;
318                         fsp->last_lock_failure.size = blr->count;
319                         fsp->last_lock_failure.fnum = fsp->fnum;
320                         fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
321                         fsp->last_lock_failure.lock_flav = blr->lock_flav;
322                 }
323         }
324
325         reply_nterror(blr->req, status);
326         if (!srv_send_smb(blr->req->sconn, (char *)blr->req->outbuf,
327                           true, blr->req->seqnum+1,
328                           blr->req->encrypted, NULL)) {
329                 exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
330         }
331         TALLOC_FREE(blr->req->outbuf);
332 }
333
334 /****************************************************************************
335  Return a lock fail error for a lockingX call. Undo all the locks we have 
336  obtained first.
337 *****************************************************************************/
338
339 static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)
340 {
341         files_struct *fsp = blr->fsp;
342         uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
343         uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
344         uint64_t smblctx;
345         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
346         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
347         uint8_t *data;
348         int i;
349
350         data = discard_const_p(uint8_t, blr->req->buf)
351                 + ((large_file_format ? 20 : 10)*num_ulocks);
352
353         /* 
354          * Data now points at the beginning of the list
355          * of smb_lkrng structs.
356          */
357
358         /*
359          * Ensure we don't do a remove on the lock that just failed,
360          * as under POSIX rules, if we have a lock already there, we
361          * will delete it (and we shouldn't) .....
362          */
363
364         for(i = blr->lock_num - 1; i >= 0; i--) {
365                 bool err;
366
367                 smblctx = get_lock_pid( data, i, large_file_format);
368                 count = get_lock_count( data, i, large_file_format);
369                 offset = get_lock_offset( data, i, large_file_format, &err);
370
371                 /*
372                  * We know err cannot be set as if it was the lock
373                  * request would never have been queued. JRA.
374                  */
375
376                 do_unlock(fsp->conn->sconn->msg_ctx,
377                         fsp,
378                         smblctx,
379                         count,
380                         offset,
381                         WINDOWS_LOCK);
382         }
383
384         generic_blocking_lock_error(blr, status);
385 }
386
387 /****************************************************************************
388  Return a lock fail error.
389 *****************************************************************************/
390
391 static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS status)
392 {
393         DEBUG(10, ("Replying with error=%s. BLR = %p\n", nt_errstr(status), blr));
394
395         switch(blr->req->cmd) {
396         case SMBlockingX:
397                 reply_lockingX_error(blr, status);
398                 break;
399         case SMBtrans2:
400         case SMBtranss2:
401                 reply_nterror(blr->req, status);
402
403                 /*
404                  * construct_reply_common has done us the favor to pre-fill
405                  * the command field with SMBtranss2 which is wrong :-)
406                  */
407                 SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
408
409                 if (!srv_send_smb(blr->req->sconn,
410                                   (char *)blr->req->outbuf,
411                                   true, blr->req->seqnum+1,
412                                   IS_CONN_ENCRYPTED(blr->fsp->conn),
413                                   NULL)) {
414                         exit_server_cleanly("blocking_lock_reply_error: "
415                                             "srv_send_smb failed.");
416                 }
417                 TALLOC_FREE(blr->req->outbuf);
418                 break;
419         default:
420                 DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
421                 exit_server("PANIC - unknown type on blocking lock queue");
422         }
423 }
424
425 /****************************************************************************
426  Attempt to finish off getting all pending blocking locks for a lockingX call.
427  Returns True if we want to be removed from the list.
428 *****************************************************************************/
429
430 static bool process_lockingX(struct blocking_lock_record *blr)
431 {
432         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
433         files_struct *fsp = blr->fsp;
434         uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
435         uint16 num_locks = SVAL(blr->req->vwv+7, 0);
436         uint64_t count = (uint64_t)0, offset = (uint64_t)0;
437         uint64_t smblctx;
438         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
439         uint8_t *data;
440         NTSTATUS status = NT_STATUS_OK;
441
442         data = discard_const_p(uint8_t, blr->req->buf)
443                 + ((large_file_format ? 20 : 10)*num_ulocks);
444
445         /* 
446          * Data now points at the beginning of the list
447          * of smb_lkrng structs.
448          */
449
450         for(; blr->lock_num < num_locks; blr->lock_num++) {
451                 struct byte_range_lock *br_lck = NULL;
452                 bool err;
453
454                 smblctx = get_lock_pid( data, blr->lock_num, large_file_format);
455                 count = get_lock_count( data, blr->lock_num, large_file_format);
456                 offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
457
458                 /*
459                  * We know err cannot be set as if it was the lock
460                  * request would never have been queued. JRA.
461                  */
462                 errno = 0;
463                 br_lck = do_lock(fsp->conn->sconn->msg_ctx,
464                                 fsp,
465                                 smblctx,
466                                 count,
467                                 offset,
468                                 ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
469                                         READ_LOCK : WRITE_LOCK),
470                                 WINDOWS_LOCK,
471                                 True,
472                                 &status,
473                                 &blr->blocking_smblctx,
474                                 blr);
475
476                 TALLOC_FREE(br_lck);
477
478                 if (NT_STATUS_IS_ERR(status)) {
479                         break;
480                 }
481         }
482
483         if(blr->lock_num == num_locks) {
484                 /*
485                  * Success - we got all the locks.
486                  */
487
488                 DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
489                          "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
490                          (unsigned int)locktype, num_locks));
491
492                 reply_lockingX_success(blr);
493                 return True;
494         }
495
496         if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
497             !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
498                 /*
499                  * We have other than a "can't get lock"
500                  * error. Free any locks we had and return an error.
501                  * Return True so we get dequeued.
502                  */
503                 blocking_lock_reply_error(blr, status);
504                 return True;
505         }
506
507         /*
508          * Still can't get all the locks - keep waiting.
509          */
510
511         DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
512 Waiting....\n", 
513                  blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
514
515         return False;
516 }
517
518 /****************************************************************************
519  Attempt to get the posix lock request from a SMBtrans2 call.
520  Returns True if we want to be removed from the list.
521 *****************************************************************************/
522
523 static bool process_trans2(struct blocking_lock_record *blr)
524 {
525         char params[2];
526         NTSTATUS status;
527         struct byte_range_lock *br_lck = do_lock(
528                                                 blr->fsp->conn->sconn->msg_ctx,
529                                                 blr->fsp,
530                                                 blr->smblctx,
531                                                 blr->count,
532                                                 blr->offset,
533                                                 blr->lock_type,
534                                                 blr->lock_flav,
535                                                 True,
536                                                 &status,
537                                                 &blr->blocking_smblctx,
538                                                 blr);
539         TALLOC_FREE(br_lck);
540
541         if (!NT_STATUS_IS_OK(status)) {
542                 if (ERROR_WAS_LOCK_DENIED(status)) {
543                         /* Still can't get the lock, just keep waiting. */
544                         return False;
545                 }       
546                 /*
547                  * We have other than a "can't get lock"
548                  * error. Send an error and return True so we get dequeued.
549                  */
550                 blocking_lock_reply_error(blr, status);
551                 return True;
552         }
553
554         /* We finally got the lock, return success. */
555
556         SSVAL(params,0,0);
557         /* Fake up max_data_bytes here - we know it fits. */
558         send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
559         return True;
560 }
561
562
563 /****************************************************************************
564  Process a blocking lock SMB.
565  Returns True if we want to be removed from the list.
566 *****************************************************************************/
567
568 static bool blocking_lock_record_process(struct blocking_lock_record *blr)
569 {
570         switch(blr->req->cmd) {
571                 case SMBlockingX:
572                         return process_lockingX(blr);
573                 case SMBtrans2:
574                 case SMBtranss2:
575                         return process_trans2(blr);
576                 default:
577                         DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
578                         exit_server("PANIC - unknown type on blocking lock queue");
579         }
580         return False; /* Keep compiler happy. */
581 }
582
583 /****************************************************************************
584  Cancel entries by fnum from the blocking lock pending queue.
585  Called when a file is closed.
586 *****************************************************************************/
587
588 void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp,
589                                               struct byte_range_lock *br_lck,
590                                               enum file_close_type close_type)
591 {
592         struct smbd_server_connection *sconn = fsp->conn->sconn;
593         struct blocking_lock_record *blr, *blr_cancelled, *next = NULL;
594
595         if (sconn->using_smb2) {
596                 cancel_pending_lock_requests_by_fid_smb2(fsp,
597                                         br_lck,
598                                         close_type);
599                 return;
600         }
601
602         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
603                 unsigned char locktype = 0;
604
605                 next = blr->next;
606                 if (blr->fsp->fnum != fsp->fnum) {
607                         continue;
608                 }
609
610                 if (blr->req->cmd == SMBlockingX) {
611                         locktype = CVAL(blr->req->vwv+3, 0);
612                 }
613
614                 DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
615                            "request type %d for file %s fnum = %d\n",
616                            blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
617
618                 blr_cancelled = blocking_lock_cancel_smb1(fsp,
619                                      blr->smblctx,
620                                      blr->offset,
621                                      blr->count,
622                                      blr->lock_flav,
623                                      locktype,
624                                      NT_STATUS_RANGE_NOT_LOCKED);
625
626                 SMB_ASSERT(blr_cancelled == blr);
627
628                 brl_lock_cancel(br_lck,
629                                 blr->smblctx,
630                                 messaging_server_id(sconn->msg_ctx),
631                                 blr->offset,
632                                 blr->count,
633                                 blr->lock_flav,
634                                 blr);
635
636                 /* We're closing the file fsp here, so ensure
637                  * we don't have a dangling pointer. */
638                 blr->fsp = NULL;
639         }
640 }
641
642 /****************************************************************************
643  Delete entries by mid from the blocking lock pending queue. Always send reply.
644  Only called from the SMB1 cancel code.
645 *****************************************************************************/
646
647 void remove_pending_lock_requests_by_mid_smb1(
648         struct smbd_server_connection *sconn, uint64_t mid)
649 {
650         struct blocking_lock_record *blr, *next = NULL;
651
652         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
653                 files_struct *fsp;
654                 struct byte_range_lock *br_lck;
655
656                 next = blr->next;
657
658                 if (blr->req->mid != mid) {
659                         continue;
660                 }
661
662                 fsp = blr->fsp;
663                 br_lck = brl_get_locks(talloc_tos(), fsp);
664
665                 if (br_lck) {
666                         DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - "
667                                    "removing request type %d for file %s fnum "
668                                    "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
669                                    fsp->fnum ));
670
671                         brl_lock_cancel(br_lck,
672                                         blr->smblctx,
673                                         messaging_server_id(sconn->msg_ctx),
674                                         blr->offset,
675                                         blr->count,
676                                         blr->lock_flav,
677                                         blr);
678                         TALLOC_FREE(br_lck);
679                 }
680
681                 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
682                 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
683                 TALLOC_FREE(blr);
684         }
685 }
686
687 /****************************************************************************
688  Is this mid a blocking lock request on the queue ?
689  Currently only called from the SMB1 unix extensions POSIX lock code.
690 *****************************************************************************/
691
692 bool blocking_lock_was_deferred_smb1(
693         struct smbd_server_connection *sconn, uint64_t mid)
694 {
695         struct blocking_lock_record *blr, *next = NULL;
696
697         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
698                 next = blr->next;
699                 if(blr->req->mid == mid) {
700                         return True;
701                 }
702         }
703         return False;
704 }
705
706 /****************************************************************************
707   Set a flag as an unlock request affects one of our pending locks.
708 *****************************************************************************/
709
710 static void received_unlock_msg(struct messaging_context *msg,
711                                 void *private_data,
712                                 uint32_t msg_type,
713                                 struct server_id server_id,
714                                 DATA_BLOB *data)
715 {
716         struct smbd_server_connection *sconn =
717                 talloc_get_type_abort(private_data,
718                 struct smbd_server_connection);
719
720         DEBUG(10,("received_unlock_msg\n"));
721         process_blocking_lock_queue(sconn);
722 }
723
724 /****************************************************************************
725  Process the blocking lock queue. Note that this is only called as root.
726 *****************************************************************************/
727
728 void process_blocking_lock_queue(struct smbd_server_connection *sconn)
729 {
730         struct timeval tv_curr = timeval_current();
731         struct blocking_lock_record *blr, *next = NULL;
732
733         if (sconn->using_smb2) {
734                 process_blocking_lock_queue_smb2(sconn, tv_curr);
735                 return;
736         }
737
738         /*
739          * Go through the queue and see if we can get any of the locks.
740          */
741
742         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
743
744                 next = blr->next;
745
746                 /*
747                  * Go through the remaining locks and try and obtain them.
748                  * The call returns True if all locks were obtained successfully
749                  * and False if we still need to wait.
750                  */
751
752                 DEBUG(10, ("Processing BLR = %p\n", blr));
753
754                 /* We use set_current_service so connections with
755                  * pending locks are not marked as idle.
756                  */
757
758                 set_current_service(blr->fsp->conn,
759                                 SVAL(blr->req->inbuf,smb_flg),
760                                 false);
761
762                 if(blocking_lock_record_process(blr)) {
763                         struct byte_range_lock *br_lck = brl_get_locks(
764                                 talloc_tos(), blr->fsp);
765
766                         DEBUG(10, ("BLR_process returned true: cancelling and "
767                             "removing lock. BLR = %p\n", blr));
768
769                         if (br_lck) {
770                                 brl_lock_cancel(br_lck,
771                                         blr->smblctx,
772                                         messaging_server_id(sconn->msg_ctx),
773                                         blr->offset,
774                                         blr->count,
775                                         blr->lock_flav,
776                                         blr);
777                                 TALLOC_FREE(br_lck);
778                         }
779
780                         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
781                         TALLOC_FREE(blr);
782                         continue;
783                 }
784
785                 /*
786                  * We couldn't get the locks for this record on the list.
787                  * If the time has expired, return a lock error.
788                  */
789
790                 if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
791                         struct byte_range_lock *br_lck = brl_get_locks(
792                                 talloc_tos(), blr->fsp);
793
794                         DEBUG(10, ("Lock timed out! BLR = %p\n", blr));
795
796                         /*
797                          * Lock expired - throw away all previously
798                          * obtained locks and return lock error.
799                          */
800
801                         if (br_lck) {
802                                 DEBUG(5,("process_blocking_lock_queue: "
803                                          "pending lock fnum = %d for file %s "
804                                          "timed out.\n", blr->fsp->fnum,
805                                          fsp_str_dbg(blr->fsp)));
806
807                                 brl_lock_cancel(br_lck,
808                                         blr->smblctx,
809                                         messaging_server_id(sconn->msg_ctx),
810                                         blr->offset,
811                                         blr->count,
812                                         blr->lock_flav,
813                                         blr);
814                                 TALLOC_FREE(br_lck);
815                         }
816
817                         blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
818                         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
819                         TALLOC_FREE(blr);
820                 }
821         }
822
823         recalc_brl_timeout(sconn);
824 }
825
826 /****************************************************************************
827  Handle a cancel message. Lock already moved onto the cancel queue.
828 *****************************************************************************/
829
830 #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(struct blocking_lock_record *) + sizeof(NTSTATUS))
831
832 static void process_blocking_lock_cancel_message(struct messaging_context *ctx,
833                                                  void *private_data,
834                                                  uint32_t msg_type,
835                                                  struct server_id server_id,
836                                                  DATA_BLOB *data)
837 {
838         NTSTATUS err;
839         const char *msg = (const char *)data->data;
840         struct blocking_lock_record *blr;
841         struct smbd_server_connection *sconn =
842                 talloc_get_type_abort(private_data,
843                 struct smbd_server_connection);
844
845         if (data->data == NULL) {
846                 smb_panic("process_blocking_lock_cancel_message: null msg");
847         }
848
849         if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) {
850                 DEBUG(0, ("process_blocking_lock_cancel_message: "
851                           "Got invalid msg len %d\n", (int)data->length));
852                 smb_panic("process_blocking_lock_cancel_message: bad msg");
853         }
854
855         memcpy(&blr, msg, sizeof(blr));
856         memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS));
857
858         DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n",
859                 nt_errstr(err) ));
860
861         blocking_lock_reply_error(blr, err);
862         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
863         TALLOC_FREE(blr);
864 }
865
866 /****************************************************************************
867  Send ourselves a blocking lock cancelled message. Handled asynchronously above.
868  Returns the blocking_lock_record that is being cancelled.
869  Only called from the SMB1 code.
870 *****************************************************************************/
871
872 struct blocking_lock_record *blocking_lock_cancel_smb1(files_struct *fsp,
873                         uint64_t smblctx,
874                         uint64_t offset,
875                         uint64_t count,
876                         enum brl_flavour lock_flav,
877                         unsigned char locktype,
878                         NTSTATUS err)
879 {
880         struct smbd_server_connection *sconn = fsp->conn->sconn;
881         char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE];
882         struct blocking_lock_record *blr;
883
884         if (!sconn->smb1.locks.blocking_lock_cancel_state) {
885                 /* Register our message. */
886                 messaging_register(sconn->msg_ctx, sconn,
887                                    MSG_SMB_BLOCKING_LOCK_CANCEL,
888                                    process_blocking_lock_cancel_message);
889
890                 sconn->smb1.locks.blocking_lock_cancel_state = True;
891         }
892
893         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
894                 if (fsp == blr->fsp &&
895                                 smblctx == blr->smblctx &&
896                                 offset == blr->offset &&
897                                 count == blr->count &&
898                                 lock_flav == blr->lock_flav) {
899                         break;
900                 }
901         }
902
903         if (!blr) {
904                 return NULL;
905         }
906
907         /* Check the flags are right. */
908         if (blr->req->cmd == SMBlockingX &&
909                 (locktype & LOCKING_ANDX_LARGE_FILES) !=
910                         (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
911                 return NULL;
912         }
913
914         /* Move to cancelled queue. */
915         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
916         DLIST_ADD(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
917
918         /* Create the message. */
919         memcpy(msg, &blr, sizeof(blr));
920         memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS));
921
922         messaging_send_buf(sconn->msg_ctx, messaging_server_id(sconn->msg_ctx),
923                            MSG_SMB_BLOCKING_LOCK_CANCEL,
924                            (uint8 *)&msg, sizeof(msg));
925
926         return blr;
927 }