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