smbd: brl_lock_cancel does not need "blr" anymore
[samba.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2006
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewritten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
36 */
37
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "locking/proto.h"
41 #include "smbd/globals.h"
42 #include "dbwrap/dbwrap.h"
43 #include "dbwrap/dbwrap_open.h"
44 #include "../libcli/security/security.h"
45 #include "serverid.h"
46 #include "messages.h"
47 #include "util_tdb.h"
48 #include "../librpc/gen_ndr/ndr_open_files.h"
49
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_LOCKING
52
53 #define NO_LOCKING_COUNT (-1)
54
55 /****************************************************************************
56  Debugging aids :-).
57 ****************************************************************************/
58
59 const char *lock_type_name(enum brl_type lock_type)
60 {
61         switch (lock_type) {
62                 case READ_LOCK:
63                         return "READ";
64                 case WRITE_LOCK:
65                         return "WRITE";
66                 case PENDING_READ_LOCK:
67                         return "PENDING_READ";
68                 case PENDING_WRITE_LOCK:
69                         return "PENDING_WRITE";
70                 default:
71                         return "other";
72         }
73 }
74
75 const char *lock_flav_name(enum brl_flavour lock_flav)
76 {
77         return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
78 }
79
80 /****************************************************************************
81  Utility function called to see if a file region is locked.
82  Called in the read/write codepath.
83 ****************************************************************************/
84
85 void init_strict_lock_struct(files_struct *fsp,
86                                 uint64_t smblctx,
87                                 br_off start,
88                                 br_off size,
89                                 enum brl_type lock_type,
90                                 struct lock_struct *plock)
91 {
92         SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
93
94         plock->context.smblctx = smblctx;
95         plock->context.tid = fsp->conn->cnum;
96         plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
97         plock->start = start;
98         plock->size = size;
99         plock->fnum = fsp->fnum;
100         plock->lock_type = lock_type;
101         plock->lock_flav = lp_posix_cifsu_locktype(fsp);
102 }
103
104 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
105 {
106         int strict_locking = lp_strict_locking(fsp->conn->params);
107         bool ret = False;
108
109         if (plock->size == 0) {
110                 return True;
111         }
112
113         if (!lp_locking(fsp->conn->params) || !strict_locking) {
114                 return True;
115         }
116
117         if (strict_locking == Auto) {
118                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
119                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
120                         ret = True;
121                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
122                            (plock->lock_type == READ_LOCK)) {
123                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
124                         ret = True;
125                 } else {
126                         struct byte_range_lock *br_lck;
127
128                         br_lck = brl_get_locks_readonly(fsp);
129                         if (!br_lck) {
130                                 return True;
131                         }
132                         ret = brl_locktest(br_lck,
133                                         plock->context.smblctx,
134                                         plock->context.pid,
135                                         plock->start,
136                                         plock->size,
137                                         plock->lock_type,
138                                         plock->lock_flav);
139                 }
140         } else {
141                 struct byte_range_lock *br_lck;
142
143                 br_lck = brl_get_locks_readonly(fsp);
144                 if (!br_lck) {
145                         return True;
146                 }
147                 ret = brl_locktest(br_lck,
148                                 plock->context.smblctx,
149                                 plock->context.pid,
150                                 plock->start,
151                                 plock->size,
152                                 plock->lock_type,
153                                 plock->lock_flav);
154         }
155
156         DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
157                         "len=%.0f %s for fnum %llu file %s\n",
158                         lock_flav_name(plock->lock_flav),
159                         (double)plock->start, (double)plock->size,
160                         ret ? "unlocked" : "locked",
161                         (unsigned long long)plock->fnum, fsp_str_dbg(fsp)));
162
163         return ret;
164 }
165
166 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
167 {
168 }
169
170 /****************************************************************************
171  Find out if a lock could be granted - return who is blocking us if we can't.
172 ****************************************************************************/
173
174 NTSTATUS query_lock(files_struct *fsp,
175                         uint64_t *psmblctx,
176                         uint64_t *pcount,
177                         uint64_t *poffset,
178                         enum brl_type *plock_type,
179                         enum brl_flavour lock_flav)
180 {
181         struct byte_range_lock *br_lck = NULL;
182
183         if (!fsp->can_lock) {
184                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
185         }
186
187         if (!lp_locking(fsp->conn->params)) {
188                 return NT_STATUS_OK;
189         }
190
191         br_lck = brl_get_locks_readonly(fsp);
192         if (!br_lck) {
193                 return NT_STATUS_NO_MEMORY;
194         }
195
196         return brl_lockquery(br_lck,
197                         psmblctx,
198                         messaging_server_id(fsp->conn->sconn->msg_ctx),
199                         poffset,
200                         pcount,
201                         plock_type,
202                         lock_flav);
203 }
204
205 static void increment_current_lock_count(files_struct *fsp,
206     enum brl_flavour lock_flav)
207 {
208         if (lock_flav == WINDOWS_LOCK &&
209             fsp->current_lock_count != NO_LOCKING_COUNT) {
210                 /* blocking ie. pending, locks also count here,
211                  * as this is an efficiency counter to avoid checking
212                  * the lock db. on close. JRA. */
213
214                 fsp->current_lock_count++;
215         } else {
216                 /* Notice that this has had a POSIX lock request.
217                  * We can't count locks after this so forget them.
218                  */
219                 fsp->current_lock_count = NO_LOCKING_COUNT;
220         }
221 }
222
223 static void decrement_current_lock_count(files_struct *fsp,
224     enum brl_flavour lock_flav)
225 {
226         if (lock_flav == WINDOWS_LOCK &&
227             fsp->current_lock_count != NO_LOCKING_COUNT) {
228                 SMB_ASSERT(fsp->current_lock_count > 0);
229                 fsp->current_lock_count--;
230         }
231 }
232
233 /****************************************************************************
234  Utility function called by locking requests.
235 ****************************************************************************/
236
237 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
238                         files_struct *fsp,
239                         uint64_t smblctx,
240                         uint64_t count,
241                         uint64_t offset,
242                         enum brl_type lock_type,
243                         enum brl_flavour lock_flav,
244                         bool blocking_lock,
245                         NTSTATUS *perr,
246                         uint64_t *psmblctx)
247 {
248         struct byte_range_lock *br_lck = NULL;
249
250         /* silently return ok on print files as we don't do locking there */
251         if (fsp->print_file) {
252                 *perr = NT_STATUS_OK;
253                 return NULL;
254         }
255
256         if (!fsp->can_lock) {
257                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
258                 return NULL;
259         }
260
261         if (!lp_locking(fsp->conn->params)) {
262                 *perr = NT_STATUS_OK;
263                 return NULL;
264         }
265
266         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
267
268         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
269                 "blocking_lock=%s requested for %s file %s\n",
270                 lock_flav_name(lock_flav), lock_type_name(lock_type),
271                 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
272                 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
273
274         br_lck = brl_get_locks(talloc_tos(), fsp);
275         if (!br_lck) {
276                 *perr = NT_STATUS_NO_MEMORY;
277                 return NULL;
278         }
279
280         *perr = brl_lock(msg_ctx,
281                         br_lck,
282                         smblctx,
283                         messaging_server_id(fsp->conn->sconn->msg_ctx),
284                         offset,
285                         count,
286                         lock_type,
287                         lock_flav,
288                         blocking_lock,
289                         psmblctx);
290
291         DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
292
293         increment_current_lock_count(fsp, lock_flav);
294         return br_lck;
295 }
296
297 /****************************************************************************
298  Utility function called by unlocking requests.
299 ****************************************************************************/
300
301 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
302                         files_struct *fsp,
303                         uint64_t smblctx,
304                         uint64_t count,
305                         uint64_t offset,
306                         enum brl_flavour lock_flav)
307 {
308         bool ok = False;
309         struct byte_range_lock *br_lck = NULL;
310
311         if (!fsp->can_lock) {
312                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
313         }
314
315         if (!lp_locking(fsp->conn->params)) {
316                 return NT_STATUS_OK;
317         }
318
319         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for %s file %s\n",
320                   (double)offset, (double)count, fsp_fnum_dbg(fsp),
321                   fsp_str_dbg(fsp)));
322
323         br_lck = brl_get_locks(talloc_tos(), fsp);
324         if (!br_lck) {
325                 return NT_STATUS_NO_MEMORY;
326         }
327
328         ok = brl_unlock(msg_ctx,
329                         br_lck,
330                         smblctx,
331                         messaging_server_id(fsp->conn->sconn->msg_ctx),
332                         offset,
333                         count,
334                         lock_flav);
335
336         TALLOC_FREE(br_lck);
337
338         if (!ok) {
339                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
340                 return NT_STATUS_RANGE_NOT_LOCKED;
341         }
342
343         decrement_current_lock_count(fsp, lock_flav);
344         return NT_STATUS_OK;
345 }
346
347 /****************************************************************************
348  Cancel any pending blocked locks.
349 ****************************************************************************/
350
351 NTSTATUS do_lock_cancel(files_struct *fsp,
352                         uint64 smblctx,
353                         uint64_t count,
354                         uint64_t offset,
355                         enum brl_flavour lock_flav,
356                         struct blocking_lock_record *blr)
357 {
358         bool ok = False;
359         struct byte_range_lock *br_lck = NULL;
360
361         if (!fsp->can_lock) {
362                 return fsp->is_directory ?
363                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
364         }
365
366         if (!lp_locking(fsp->conn->params)) {
367                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
368         }
369
370         DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for %s file %s\n",
371                   (double)offset, (double)count, fsp_fnum_dbg(fsp),
372                   fsp_str_dbg(fsp)));
373
374         br_lck = brl_get_locks(talloc_tos(), fsp);
375         if (!br_lck) {
376                 return NT_STATUS_NO_MEMORY;
377         }
378
379         ok = brl_lock_cancel(br_lck,
380                         smblctx,
381                         messaging_server_id(fsp->conn->sconn->msg_ctx),
382                         offset,
383                         count,
384                         lock_flav);
385
386         TALLOC_FREE(br_lck);
387
388         if (!ok) {
389                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
390                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
391         }
392
393         decrement_current_lock_count(fsp, lock_flav);
394         return NT_STATUS_OK;
395 }
396
397 /****************************************************************************
398  Remove any locks on this fd. Called from file_close().
399 ****************************************************************************/
400
401 void locking_close_file(struct messaging_context *msg_ctx,
402                         files_struct *fsp,
403                         enum file_close_type close_type)
404 {
405         struct byte_range_lock *br_lck;
406
407         if (!lp_locking(fsp->conn->params)) {
408                 return;
409         }
410
411         /* If we have no outstanding locks or pending
412          * locks then we don't need to look in the lock db.
413          */
414
415         if (fsp->current_lock_count == 0) {
416                 return;
417         }
418
419         br_lck = brl_get_locks(talloc_tos(),fsp);
420
421         if (br_lck) {
422                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
423                 brl_close_fnum(msg_ctx, br_lck);
424                 TALLOC_FREE(br_lck);
425         }
426 }
427
428 /*******************************************************************
429  Print out a share mode.
430 ********************************************************************/
431
432 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
433 {
434         return talloc_asprintf(ctx, "share_mode_entry[%d]: "
435                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
436                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
437                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
438                  num,
439                  procid_str_static(&e->pid),
440                  e->share_access, e->private_options,
441                  e->access_mask, (unsigned long long)e->op_mid,
442                  e->op_type, (unsigned long long)e->share_file_id,
443                  (unsigned int)e->uid, (unsigned int)e->flags,
444                  file_id_string_tos(&e->id),
445                  (unsigned int)e->name_hash);
446 }
447
448 /*******************************************************************
449  Fetch a share mode where we know one MUST exist. This call reference
450  counts it internally to allow for nested lock fetches.
451 ********************************************************************/
452
453 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
454                                                      const struct file_id id)
455 {
456         return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
457 }
458
459 /*******************************************************************
460  Sets the service name and filename for rename.
461  At this point we emit "file renamed" messages to all
462  process id's that have this file open.
463  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
464 ********************************************************************/
465
466 bool rename_share_filename(struct messaging_context *msg_ctx,
467                         struct share_mode_lock *lck,
468                         struct file_id id,
469                         const char *servicepath,
470                         uint32_t orig_name_hash,
471                         uint32_t new_name_hash,
472                         const struct smb_filename *smb_fname_dst)
473 {
474         struct share_mode_data *d = lck->data;
475         size_t sp_len;
476         size_t bn_len;
477         size_t sn_len;
478         size_t msg_len;
479         char *frm = NULL;
480         int i;
481         bool strip_two_chars = false;
482         bool has_stream = smb_fname_dst->stream_name != NULL;
483         struct server_id self_pid = messaging_server_id(msg_ctx);
484
485         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
486                    servicepath, smb_fname_dst->base_name));
487
488         /*
489          * rename_internal_fsp() and rename_internals() add './' to
490          * head of newname if newname does not contain a '/'.
491          */
492         if (smb_fname_dst->base_name[0] &&
493             smb_fname_dst->base_name[1] &&
494             smb_fname_dst->base_name[0] == '.' &&
495             smb_fname_dst->base_name[1] == '/') {
496                 strip_two_chars = true;
497         }
498
499         d->servicepath = talloc_strdup(d, servicepath);
500         d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
501                                        (strip_two_chars ? 2 : 0));
502         d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
503         if (d->base_name == NULL ||
504             (has_stream && d->stream_name == NULL) ||
505             d->servicepath == NULL) {
506                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
507                 return False;
508         }
509         d->modified = True;
510
511         sp_len = strlen(d->servicepath);
512         bn_len = strlen(d->base_name);
513         sn_len = has_stream ? strlen(d->stream_name) : 0;
514
515         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
516             sn_len + 1;
517
518         /* Set up the name changed message. */
519         frm = talloc_array(d, char, msg_len);
520         if (!frm) {
521                 return False;
522         }
523
524         push_file_id_24(frm, &id);
525
526         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
527
528         strlcpy(&frm[24],
529                 d->servicepath ? d->servicepath : "",
530                 sp_len+1);
531         strlcpy(&frm[24 + sp_len + 1],
532                 d->base_name ? d->base_name : "",
533                 bn_len+1);
534         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
535                 d->stream_name ? d->stream_name : "",
536                 sn_len+1);
537
538         /* Send the messages. */
539         for (i=0; i<d->num_share_modes; i++) {
540                 struct share_mode_entry *se = &d->share_modes[i];
541                 if (!is_valid_share_mode_entry(se)) {
542                         continue;
543                 }
544
545                 /* If this is a hardlink to the inode
546                    with a different name, skip this. */
547                 if (se->name_hash != orig_name_hash) {
548                         continue;
549                 }
550
551                 se->name_hash = new_name_hash;
552
553                 /* But not to ourselves... */
554                 if (serverid_equal(&se->pid, &self_pid)) {
555                         continue;
556                 }
557
558                 if (share_mode_stale_pid(d, i)) {
559                         continue;
560                 }
561
562                 DEBUG(10,("rename_share_filename: sending rename message to "
563                           "pid %s file_id %s sharepath %s base_name %s "
564                           "stream_name %s\n",
565                           procid_str_static(&se->pid),
566                           file_id_string_tos(&id),
567                           d->servicepath, d->base_name,
568                         has_stream ? d->stream_name : ""));
569
570                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
571                                    (uint8 *)frm, msg_len);
572         }
573
574         return True;
575 }
576
577 void get_file_infos(struct file_id id,
578                     uint32_t name_hash,
579                     bool *delete_on_close,
580                     struct timespec *write_time)
581 {
582         struct share_mode_lock *lck;
583
584         if (delete_on_close) {
585                 *delete_on_close = false;
586         }
587
588         if (write_time) {
589                 ZERO_STRUCTP(write_time);
590         }
591
592         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
593                 return;
594         }
595
596         if (delete_on_close) {
597                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
598         }
599
600         if (write_time) {
601                 *write_time = get_share_mode_write_time(lck);
602         }
603
604         TALLOC_FREE(lck);
605 }
606
607 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
608 {
609         int num_props = 0;
610
611         if (e->stale) {
612                 return false;
613         }
614
615         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
616         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
617         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
618
619         if ((num_props > 1) && serverid_exists(&e->pid)) {
620                 smb_panic("Invalid share mode entry");
621         }
622         return (num_props != 0);
623 }
624
625 /*
626  * In case d->share_modes[i] conflicts with something or otherwise is
627  * being used, we need to make sure the corresponding process still
628  * exists.
629  */
630 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
631 {
632         struct share_mode_entry *e;
633
634         if (idx > d->num_share_modes) {
635                 DEBUG(1, ("Asking for index %u, only %u around\n",
636                           idx, (unsigned)d->num_share_modes));
637                 return false;
638         }
639         e = &d->share_modes[idx];
640         if (e->stale) {
641                 /*
642                  * Checked before
643                  */
644                 return true;
645         }
646         if (serverid_exists(&e->pid)) {
647                 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
648                            procid_str_static(&e->pid), idx,
649                            (unsigned)d->num_share_modes));
650                 return false;
651         }
652         DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
653                    procid_str_static(&e->pid), idx,
654                    (unsigned)d->num_share_modes));
655
656         e->stale = true;
657
658         if (d->num_delete_tokens != 0) {
659                 uint32_t i, num_stale;
660
661                 /*
662                  * We cannot have any delete tokens
663                  * if there are no valid share modes.
664                  */
665
666                 num_stale = 0;
667
668                 for (i=0; i<d->num_share_modes; i++) {
669                         if (d->share_modes[i].stale) {
670                                 num_stale += 1;
671                         }
672                 }
673
674                 if (num_stale == d->num_share_modes) {
675                         /*
676                          * No non-stale share mode found
677                          */
678                         TALLOC_FREE(d->delete_tokens);
679                         d->num_delete_tokens = 0;
680                 }
681         }
682
683         d->modified = true;
684         return true;
685 }
686
687 void remove_stale_share_mode_entries(struct share_mode_data *d)
688 {
689         uint32_t i;
690
691         i = 0;
692         while (i < d->num_share_modes) {
693                 if (d->share_modes[i].stale) {
694                         struct share_mode_entry *m = d->share_modes;
695                         m[i] = m[d->num_share_modes-1];
696                         d->num_share_modes -= 1;
697                 } else {
698                         i += 1;
699                 }
700         }
701 }
702
703 bool set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
704                     uid_t uid, uint64_t mid, uint16 op_type)
705 {
706         struct share_mode_data *d = lck->data;
707         struct share_mode_entry *tmp, *e;
708
709         tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
710                              d->num_share_modes+1);
711         if (tmp == NULL) {
712                 return false;
713         }
714         d->share_modes = tmp;
715         e = &d->share_modes[d->num_share_modes];
716         d->num_share_modes += 1;
717         d->modified = true;
718
719         ZERO_STRUCTP(e);
720         e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
721         e->share_access = fsp->share_access;
722         e->private_options = fsp->fh->private_options;
723         e->access_mask = fsp->access_mask;
724         e->op_mid = mid;
725         e->op_type = op_type;
726         e->time.tv_sec = fsp->open_time.tv_sec;
727         e->time.tv_usec = fsp->open_time.tv_usec;
728         e->id = fsp->file_id;
729         e->share_file_id = fsp->fh->gen_id;
730         e->uid = (uint32)uid;
731         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
732         e->name_hash = fsp->name_hash;
733
734         return true;
735 }
736
737 static struct share_mode_entry *find_share_mode_entry(
738         struct share_mode_lock *lck, files_struct *fsp)
739 {
740         struct share_mode_data *d = lck->data;
741         struct server_id pid;
742         int i;
743
744         pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
745
746         for (i=0; i<d->num_share_modes; i++) {
747                 struct share_mode_entry *e = &d->share_modes[i];
748
749                 if (!is_valid_share_mode_entry(e)) {
750                         continue;
751                 }
752                 if (!serverid_equal(&pid, &e->pid)) {
753                         continue;
754                 }
755                 if (!file_id_equal(&fsp->file_id, &e->id)) {
756                         continue;
757                 }
758                 if (fsp->fh->gen_id != e->share_file_id) {
759                         continue;
760                 }
761                 return e;
762         }
763         return NULL;
764 }
765
766 /*******************************************************************
767  Del the share mode of a file for this process. Return the number of
768  entries left.
769 ********************************************************************/
770
771 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
772 {
773         struct share_mode_entry *e;
774
775         e = find_share_mode_entry(lck, fsp);
776         if (e == NULL) {
777                 return False;
778         }
779         *e = lck->data->share_modes[lck->data->num_share_modes-1];
780         lck->data->num_share_modes -= 1;
781         lck->data->modified = True;
782         return True;
783 }
784
785 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
786                                   struct files_struct *fsp)
787 {
788         struct share_mode_entry *e;
789
790         if (lck->data->num_share_modes != 1) {
791                 return false;
792         }
793
794         if (fsp->op == NULL) {
795                 return false;
796         }
797         if (!fsp->op->global->durable) {
798                 return false;
799         }
800
801         e = find_share_mode_entry(lck, fsp);
802         if (e == NULL) {
803                 return false;
804         }
805
806         DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
807
808         server_id_set_disconnected(&e->pid);
809
810         /*
811          * On reopen the caller needs to check that
812          * the client comes with the correct handle.
813          */
814         e->share_file_id = fsp->op->global->open_persistent_id;
815
816         lck->data->modified = true;
817         return true;
818 }
819
820 /*******************************************************************
821  Remove an oplock mid and mode entry from a share mode.
822 ********************************************************************/
823
824 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
825 {
826         struct share_mode_entry *e;
827
828         e = find_share_mode_entry(lck, fsp);
829         if (e == NULL) {
830                 return False;
831         }
832
833         e->op_type = NO_OPLOCK;
834         lck->data->modified = True;
835         return True;
836 }
837
838 /*******************************************************************
839  Downgrade a oplock type from exclusive to level II.
840 ********************************************************************/
841
842 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
843 {
844         struct share_mode_entry *e;
845
846         e = find_share_mode_entry(lck, fsp);
847         if (e == NULL) {
848                 return False;
849         }
850
851         e->op_type = LEVEL_II_OPLOCK;
852         lck->data->modified = True;
853         return True;
854 }
855
856 /****************************************************************************
857  Adds a delete on close token.
858 ****************************************************************************/
859
860 static bool add_delete_on_close_token(struct share_mode_data *d,
861                         uint32_t name_hash,
862                         const struct security_token *nt_tok,
863                         const struct security_unix_token *tok)
864 {
865         struct delete_token *tmp, *dtl;
866
867         tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
868                              d->num_delete_tokens+1);
869         if (tmp == NULL) {
870                 return false;
871         }
872         d->delete_tokens = tmp;
873         dtl = &d->delete_tokens[d->num_delete_tokens];
874
875         dtl->name_hash = name_hash;
876         dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
877         if (dtl->delete_nt_token == NULL) {
878                 return false;
879         }
880         dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
881         if (dtl->delete_token == NULL) {
882                 return false;
883         }
884         d->num_delete_tokens += 1;
885         d->modified = true;
886         return true;
887 }
888
889 /****************************************************************************
890  Sets the delete on close flag over all share modes on this file.
891  Modify the share mode entry for all files open
892  on this device and inode to tell other smbds we have
893  changed the delete on close flag. This will be noticed
894  in the close code, the last closer will delete the file
895  if flag is set.
896  This makes a copy of any struct security_unix_token into the
897  lck entry. This function is used when the lock is already granted.
898 ****************************************************************************/
899
900 void set_delete_on_close_lck(files_struct *fsp,
901                         struct share_mode_lock *lck,
902                         bool delete_on_close,
903                         const struct security_token *nt_tok,
904                         const struct security_unix_token *tok)
905 {
906         struct share_mode_data *d = lck->data;
907         int i;
908         bool ret;
909
910         if (delete_on_close) {
911                 SMB_ASSERT(nt_tok != NULL);
912                 SMB_ASSERT(tok != NULL);
913         } else {
914                 SMB_ASSERT(nt_tok == NULL);
915                 SMB_ASSERT(tok == NULL);
916         }
917
918         for (i=0; i<d->num_delete_tokens; i++) {
919                 struct delete_token *dt = &d->delete_tokens[i];
920                 if (dt->name_hash == fsp->name_hash) {
921                         d->modified = true;
922                         if (delete_on_close == false) {
923                                 /* Delete this entry. */
924                                 TALLOC_FREE(dt->delete_nt_token);
925                                 TALLOC_FREE(dt->delete_token);
926                                 *dt = d->delete_tokens[
927                                         d->num_delete_tokens-1];
928                                 d->num_delete_tokens -= 1;
929                         } else {
930                                 /* Replace this token with the
931                                    given tok. */
932                                 TALLOC_FREE(dt->delete_nt_token);
933                                 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
934                                 SMB_ASSERT(dt->delete_nt_token != NULL);
935                                 TALLOC_FREE(dt->delete_token);
936                                 dt->delete_token = copy_unix_token(dt, tok);
937                                 SMB_ASSERT(dt->delete_token != NULL);
938                         }
939                         return;
940                 }
941         }
942
943         if (!delete_on_close) {
944                 /* Nothing to delete - not found. */
945                 return;
946         }
947
948         ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
949         SMB_ASSERT(ret);
950 }
951
952 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
953                         const struct security_token *nt_tok,
954                         const struct security_unix_token *tok)
955 {
956         struct share_mode_lock *lck;
957
958         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
959                   "%s, file %s\n",
960                   delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
961                   fsp_str_dbg(fsp)));
962
963         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
964         if (lck == NULL) {
965                 return False;
966         }
967
968         if (delete_on_close) {
969                 set_delete_on_close_lck(fsp, lck, true,
970                         nt_tok,
971                         tok);
972         } else {
973                 set_delete_on_close_lck(fsp, lck, false,
974                         NULL,
975                         NULL);
976         }
977
978         if (fsp->is_directory) {
979                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
980                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
981                                                fsp->fsp_name->base_name);
982         }
983
984         TALLOC_FREE(lck);
985
986         fsp->delete_on_close = delete_on_close;
987
988         return True;
989 }
990
991 static struct delete_token *find_delete_on_close_token(
992         struct share_mode_data *d, uint32_t name_hash)
993 {
994         uint32_t i;
995
996         DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
997                    (unsigned int)name_hash));
998
999         for (i=0; i<d->num_delete_tokens; i++) {
1000                 struct delete_token *dt = &d->delete_tokens[i];
1001
1002                 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1003                            (unsigned int)dt->name_hash ));
1004                 if (dt->name_hash == name_hash) {
1005                         return dt;
1006                 }
1007         }
1008         return NULL;
1009 }
1010
1011 /****************************************************************************
1012  Return the NT token and UNIX token if there's a match. Return true if
1013  found, false if not.
1014 ****************************************************************************/
1015
1016 bool get_delete_on_close_token(struct share_mode_lock *lck,
1017                                         uint32_t name_hash,
1018                                         const struct security_token **pp_nt_tok,
1019                                         const struct security_unix_token **pp_tok)
1020 {
1021         struct delete_token *dt;
1022
1023         dt = find_delete_on_close_token(lck->data, name_hash);
1024         if (dt == NULL) {
1025                 return false;
1026         }
1027         *pp_nt_tok = dt->delete_nt_token;
1028         *pp_tok =  dt->delete_token;
1029         return true;
1030 }
1031
1032 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1033 {
1034         return find_delete_on_close_token(lck->data, name_hash) != NULL;
1035 }
1036
1037 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1038 {
1039         struct share_mode_lock *lck;
1040
1041         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1042                  timestring(talloc_tos(),
1043                             convert_timespec_to_time_t(write_time)),
1044                  file_id_string_tos(&fileid)));
1045
1046         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1047         if (lck == NULL) {
1048                 return False;
1049         }
1050
1051         if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1052                 lck->data->modified = True;
1053                 lck->data->changed_write_time = write_time;
1054         }
1055
1056         TALLOC_FREE(lck);
1057         return True;
1058 }
1059
1060 bool set_write_time(struct file_id fileid, struct timespec write_time)
1061 {
1062         struct share_mode_lock *lck;
1063
1064         DEBUG(5,("set_write_time: %s id=%s\n",
1065                  timestring(talloc_tos(),
1066                             convert_timespec_to_time_t(write_time)),
1067                  file_id_string_tos(&fileid)));
1068
1069         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1070         if (lck == NULL) {
1071                 return False;
1072         }
1073
1074         if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1075                 lck->data->modified = True;
1076                 lck->data->old_write_time = write_time;
1077         }
1078
1079         TALLOC_FREE(lck);
1080         return True;
1081 }
1082
1083 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1084 {
1085         struct share_mode_data *d = lck->data;
1086
1087         if (!null_timespec(d->changed_write_time)) {
1088                 return d->changed_write_time;
1089         }
1090         return d->old_write_time;
1091 }