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