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