smbd: do_lock 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                         blr);
386
387         TALLOC_FREE(br_lck);
388
389         if (!ok) {
390                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
391                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
392         }
393
394         decrement_current_lock_count(fsp, lock_flav);
395         return NT_STATUS_OK;
396 }
397
398 /****************************************************************************
399  Remove any locks on this fd. Called from file_close().
400 ****************************************************************************/
401
402 void locking_close_file(struct messaging_context *msg_ctx,
403                         files_struct *fsp,
404                         enum file_close_type close_type)
405 {
406         struct byte_range_lock *br_lck;
407
408         if (!lp_locking(fsp->conn->params)) {
409                 return;
410         }
411
412         /* If we have no outstanding locks or pending
413          * locks then we don't need to look in the lock db.
414          */
415
416         if (fsp->current_lock_count == 0) {
417                 return;
418         }
419
420         br_lck = brl_get_locks(talloc_tos(),fsp);
421
422         if (br_lck) {
423                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
424                 brl_close_fnum(msg_ctx, br_lck);
425                 TALLOC_FREE(br_lck);
426         }
427 }
428
429 /*******************************************************************
430  Print out a share mode.
431 ********************************************************************/
432
433 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
434 {
435         return talloc_asprintf(ctx, "share_mode_entry[%d]: "
436                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
437                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
438                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
439                  num,
440                  procid_str_static(&e->pid),
441                  e->share_access, e->private_options,
442                  e->access_mask, (unsigned long long)e->op_mid,
443                  e->op_type, (unsigned long long)e->share_file_id,
444                  (unsigned int)e->uid, (unsigned int)e->flags,
445                  file_id_string_tos(&e->id),
446                  (unsigned int)e->name_hash);
447 }
448
449 /*******************************************************************
450  Fetch a share mode where we know one MUST exist. This call reference
451  counts it internally to allow for nested lock fetches.
452 ********************************************************************/
453
454 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
455                                                      const struct file_id id)
456 {
457         return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
458 }
459
460 /*******************************************************************
461  Sets the service name and filename for rename.
462  At this point we emit "file renamed" messages to all
463  process id's that have this file open.
464  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
465 ********************************************************************/
466
467 bool rename_share_filename(struct messaging_context *msg_ctx,
468                         struct share_mode_lock *lck,
469                         struct file_id id,
470                         const char *servicepath,
471                         uint32_t orig_name_hash,
472                         uint32_t new_name_hash,
473                         const struct smb_filename *smb_fname_dst)
474 {
475         struct share_mode_data *d = lck->data;
476         size_t sp_len;
477         size_t bn_len;
478         size_t sn_len;
479         size_t msg_len;
480         char *frm = NULL;
481         int i;
482         bool strip_two_chars = false;
483         bool has_stream = smb_fname_dst->stream_name != NULL;
484         struct server_id self_pid = messaging_server_id(msg_ctx);
485
486         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
487                    servicepath, smb_fname_dst->base_name));
488
489         /*
490          * rename_internal_fsp() and rename_internals() add './' to
491          * head of newname if newname does not contain a '/'.
492          */
493         if (smb_fname_dst->base_name[0] &&
494             smb_fname_dst->base_name[1] &&
495             smb_fname_dst->base_name[0] == '.' &&
496             smb_fname_dst->base_name[1] == '/') {
497                 strip_two_chars = true;
498         }
499
500         d->servicepath = talloc_strdup(d, servicepath);
501         d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
502                                        (strip_two_chars ? 2 : 0));
503         d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
504         if (d->base_name == NULL ||
505             (has_stream && d->stream_name == NULL) ||
506             d->servicepath == NULL) {
507                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
508                 return False;
509         }
510         d->modified = True;
511
512         sp_len = strlen(d->servicepath);
513         bn_len = strlen(d->base_name);
514         sn_len = has_stream ? strlen(d->stream_name) : 0;
515
516         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
517             sn_len + 1;
518
519         /* Set up the name changed message. */
520         frm = talloc_array(d, char, msg_len);
521         if (!frm) {
522                 return False;
523         }
524
525         push_file_id_24(frm, &id);
526
527         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
528
529         strlcpy(&frm[24],
530                 d->servicepath ? d->servicepath : "",
531                 sp_len+1);
532         strlcpy(&frm[24 + sp_len + 1],
533                 d->base_name ? d->base_name : "",
534                 bn_len+1);
535         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
536                 d->stream_name ? d->stream_name : "",
537                 sn_len+1);
538
539         /* Send the messages. */
540         for (i=0; i<d->num_share_modes; i++) {
541                 struct share_mode_entry *se = &d->share_modes[i];
542                 if (!is_valid_share_mode_entry(se)) {
543                         continue;
544                 }
545
546                 /* If this is a hardlink to the inode
547                    with a different name, skip this. */
548                 if (se->name_hash != orig_name_hash) {
549                         continue;
550                 }
551
552                 se->name_hash = new_name_hash;
553
554                 /* But not to ourselves... */
555                 if (serverid_equal(&se->pid, &self_pid)) {
556                         continue;
557                 }
558
559                 if (share_mode_stale_pid(d, i)) {
560                         continue;
561                 }
562
563                 DEBUG(10,("rename_share_filename: sending rename message to "
564                           "pid %s file_id %s sharepath %s base_name %s "
565                           "stream_name %s\n",
566                           procid_str_static(&se->pid),
567                           file_id_string_tos(&id),
568                           d->servicepath, d->base_name,
569                         has_stream ? d->stream_name : ""));
570
571                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
572                                    (uint8 *)frm, msg_len);
573         }
574
575         return True;
576 }
577
578 void get_file_infos(struct file_id id,
579                     uint32_t name_hash,
580                     bool *delete_on_close,
581                     struct timespec *write_time)
582 {
583         struct share_mode_lock *lck;
584
585         if (delete_on_close) {
586                 *delete_on_close = false;
587         }
588
589         if (write_time) {
590                 ZERO_STRUCTP(write_time);
591         }
592
593         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
594                 return;
595         }
596
597         if (delete_on_close) {
598                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
599         }
600
601         if (write_time) {
602                 *write_time = get_share_mode_write_time(lck);
603         }
604
605         TALLOC_FREE(lck);
606 }
607
608 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
609 {
610         int num_props = 0;
611
612         if (e->stale) {
613                 return false;
614         }
615
616         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
617         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
618         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
619
620         if ((num_props > 1) && serverid_exists(&e->pid)) {
621                 smb_panic("Invalid share mode entry");
622         }
623         return (num_props != 0);
624 }
625
626 /*
627  * In case d->share_modes[i] conflicts with something or otherwise is
628  * being used, we need to make sure the corresponding process still
629  * exists.
630  */
631 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
632 {
633         struct share_mode_entry *e;
634
635         if (idx > d->num_share_modes) {
636                 DEBUG(1, ("Asking for index %u, only %u around\n",
637                           idx, (unsigned)d->num_share_modes));
638                 return false;
639         }
640         e = &d->share_modes[idx];
641         if (e->stale) {
642                 /*
643                  * Checked before
644                  */
645                 return true;
646         }
647         if (serverid_exists(&e->pid)) {
648                 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
649                            procid_str_static(&e->pid), idx,
650                            (unsigned)d->num_share_modes));
651                 return false;
652         }
653         DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
654                    procid_str_static(&e->pid), idx,
655                    (unsigned)d->num_share_modes));
656
657         e->stale = true;
658
659         if (d->num_delete_tokens != 0) {
660                 uint32_t i, num_stale;
661
662                 /*
663                  * We cannot have any delete tokens
664                  * if there are no valid share modes.
665                  */
666
667                 num_stale = 0;
668
669                 for (i=0; i<d->num_share_modes; i++) {
670                         if (d->share_modes[i].stale) {
671                                 num_stale += 1;
672                         }
673                 }
674
675                 if (num_stale == d->num_share_modes) {
676                         /*
677                          * No non-stale share mode found
678                          */
679                         TALLOC_FREE(d->delete_tokens);
680                         d->num_delete_tokens = 0;
681                 }
682         }
683
684         d->modified = true;
685         return true;
686 }
687
688 void remove_stale_share_mode_entries(struct share_mode_data *d)
689 {
690         uint32_t i;
691
692         i = 0;
693         while (i < d->num_share_modes) {
694                 if (d->share_modes[i].stale) {
695                         struct share_mode_entry *m = d->share_modes;
696                         m[i] = m[d->num_share_modes-1];
697                         d->num_share_modes -= 1;
698                 } else {
699                         i += 1;
700                 }
701         }
702 }
703
704 bool set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
705                     uid_t uid, uint64_t mid, uint16 op_type)
706 {
707         struct share_mode_data *d = lck->data;
708         struct share_mode_entry *tmp, *e;
709
710         tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
711                              d->num_share_modes+1);
712         if (tmp == NULL) {
713                 return false;
714         }
715         d->share_modes = tmp;
716         e = &d->share_modes[d->num_share_modes];
717         d->num_share_modes += 1;
718         d->modified = true;
719
720         ZERO_STRUCTP(e);
721         e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
722         e->share_access = fsp->share_access;
723         e->private_options = fsp->fh->private_options;
724         e->access_mask = fsp->access_mask;
725         e->op_mid = mid;
726         e->op_type = op_type;
727         e->time.tv_sec = fsp->open_time.tv_sec;
728         e->time.tv_usec = fsp->open_time.tv_usec;
729         e->id = fsp->file_id;
730         e->share_file_id = fsp->fh->gen_id;
731         e->uid = (uint32)uid;
732         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
733         e->name_hash = fsp->name_hash;
734
735         return true;
736 }
737
738 static struct share_mode_entry *find_share_mode_entry(
739         struct share_mode_lock *lck, files_struct *fsp)
740 {
741         struct share_mode_data *d = lck->data;
742         struct server_id pid;
743         int i;
744
745         pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
746
747         for (i=0; i<d->num_share_modes; i++) {
748                 struct share_mode_entry *e = &d->share_modes[i];
749
750                 if (!is_valid_share_mode_entry(e)) {
751                         continue;
752                 }
753                 if (!serverid_equal(&pid, &e->pid)) {
754                         continue;
755                 }
756                 if (!file_id_equal(&fsp->file_id, &e->id)) {
757                         continue;
758                 }
759                 if (fsp->fh->gen_id != e->share_file_id) {
760                         continue;
761                 }
762                 return e;
763         }
764         return NULL;
765 }
766
767 /*******************************************************************
768  Del the share mode of a file for this process. Return the number of
769  entries left.
770 ********************************************************************/
771
772 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
773 {
774         struct share_mode_entry *e;
775
776         e = find_share_mode_entry(lck, fsp);
777         if (e == NULL) {
778                 return False;
779         }
780         *e = lck->data->share_modes[lck->data->num_share_modes-1];
781         lck->data->num_share_modes -= 1;
782         lck->data->modified = True;
783         return True;
784 }
785
786 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
787                                   struct files_struct *fsp)
788 {
789         struct share_mode_entry *e;
790
791         if (lck->data->num_share_modes != 1) {
792                 return false;
793         }
794
795         if (fsp->op == NULL) {
796                 return false;
797         }
798         if (!fsp->op->global->durable) {
799                 return false;
800         }
801
802         e = find_share_mode_entry(lck, fsp);
803         if (e == NULL) {
804                 return false;
805         }
806
807         DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
808
809         server_id_set_disconnected(&e->pid);
810
811         /*
812          * On reopen the caller needs to check that
813          * the client comes with the correct handle.
814          */
815         e->share_file_id = fsp->op->global->open_persistent_id;
816
817         lck->data->modified = true;
818         return true;
819 }
820
821 /*******************************************************************
822  Remove an oplock mid and mode entry from a share mode.
823 ********************************************************************/
824
825 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
826 {
827         struct share_mode_entry *e;
828
829         e = find_share_mode_entry(lck, fsp);
830         if (e == NULL) {
831                 return False;
832         }
833
834         e->op_type = NO_OPLOCK;
835         lck->data->modified = True;
836         return True;
837 }
838
839 /*******************************************************************
840  Downgrade a oplock type from exclusive to level II.
841 ********************************************************************/
842
843 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
844 {
845         struct share_mode_entry *e;
846
847         e = find_share_mode_entry(lck, fsp);
848         if (e == NULL) {
849                 return False;
850         }
851
852         e->op_type = LEVEL_II_OPLOCK;
853         lck->data->modified = True;
854         return True;
855 }
856
857 /****************************************************************************
858  Adds a delete on close token.
859 ****************************************************************************/
860
861 static bool add_delete_on_close_token(struct share_mode_data *d,
862                         uint32_t name_hash,
863                         const struct security_token *nt_tok,
864                         const struct security_unix_token *tok)
865 {
866         struct delete_token *tmp, *dtl;
867
868         tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
869                              d->num_delete_tokens+1);
870         if (tmp == NULL) {
871                 return false;
872         }
873         d->delete_tokens = tmp;
874         dtl = &d->delete_tokens[d->num_delete_tokens];
875
876         dtl->name_hash = name_hash;
877         dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
878         if (dtl->delete_nt_token == NULL) {
879                 return false;
880         }
881         dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
882         if (dtl->delete_token == NULL) {
883                 return false;
884         }
885         d->num_delete_tokens += 1;
886         d->modified = true;
887         return true;
888 }
889
890 /****************************************************************************
891  Sets the delete on close flag over all share modes on this file.
892  Modify the share mode entry for all files open
893  on this device and inode to tell other smbds we have
894  changed the delete on close flag. This will be noticed
895  in the close code, the last closer will delete the file
896  if flag is set.
897  This makes a copy of any struct security_unix_token into the
898  lck entry. This function is used when the lock is already granted.
899 ****************************************************************************/
900
901 void set_delete_on_close_lck(files_struct *fsp,
902                         struct share_mode_lock *lck,
903                         bool delete_on_close,
904                         const struct security_token *nt_tok,
905                         const struct security_unix_token *tok)
906 {
907         struct share_mode_data *d = lck->data;
908         int i;
909         bool ret;
910
911         if (delete_on_close) {
912                 SMB_ASSERT(nt_tok != NULL);
913                 SMB_ASSERT(tok != NULL);
914         } else {
915                 SMB_ASSERT(nt_tok == NULL);
916                 SMB_ASSERT(tok == NULL);
917         }
918
919         for (i=0; i<d->num_delete_tokens; i++) {
920                 struct delete_token *dt = &d->delete_tokens[i];
921                 if (dt->name_hash == fsp->name_hash) {
922                         d->modified = true;
923                         if (delete_on_close == false) {
924                                 /* Delete this entry. */
925                                 TALLOC_FREE(dt->delete_nt_token);
926                                 TALLOC_FREE(dt->delete_token);
927                                 *dt = d->delete_tokens[
928                                         d->num_delete_tokens-1];
929                                 d->num_delete_tokens -= 1;
930                         } else {
931                                 /* Replace this token with the
932                                    given tok. */
933                                 TALLOC_FREE(dt->delete_nt_token);
934                                 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
935                                 SMB_ASSERT(dt->delete_nt_token != NULL);
936                                 TALLOC_FREE(dt->delete_token);
937                                 dt->delete_token = copy_unix_token(dt, tok);
938                                 SMB_ASSERT(dt->delete_token != NULL);
939                         }
940                         return;
941                 }
942         }
943
944         if (!delete_on_close) {
945                 /* Nothing to delete - not found. */
946                 return;
947         }
948
949         ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
950         SMB_ASSERT(ret);
951 }
952
953 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
954                         const struct security_token *nt_tok,
955                         const struct security_unix_token *tok)
956 {
957         struct share_mode_lock *lck;
958
959         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
960                   "%s, file %s\n",
961                   delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
962                   fsp_str_dbg(fsp)));
963
964         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
965         if (lck == NULL) {
966                 return False;
967         }
968
969         if (delete_on_close) {
970                 set_delete_on_close_lck(fsp, lck, true,
971                         nt_tok,
972                         tok);
973         } else {
974                 set_delete_on_close_lck(fsp, lck, false,
975                         NULL,
976                         NULL);
977         }
978
979         if (fsp->is_directory) {
980                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
981                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
982                                                fsp->fsp_name->base_name);
983         }
984
985         TALLOC_FREE(lck);
986
987         fsp->delete_on_close = delete_on_close;
988
989         return True;
990 }
991
992 static struct delete_token *find_delete_on_close_token(
993         struct share_mode_data *d, uint32_t name_hash)
994 {
995         uint32_t i;
996
997         DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
998                    (unsigned int)name_hash));
999
1000         for (i=0; i<d->num_delete_tokens; i++) {
1001                 struct delete_token *dt = &d->delete_tokens[i];
1002
1003                 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1004                            (unsigned int)dt->name_hash ));
1005                 if (dt->name_hash == name_hash) {
1006                         return dt;
1007                 }
1008         }
1009         return NULL;
1010 }
1011
1012 /****************************************************************************
1013  Return the NT token and UNIX token if there's a match. Return true if
1014  found, false if not.
1015 ****************************************************************************/
1016
1017 bool get_delete_on_close_token(struct share_mode_lock *lck,
1018                                         uint32_t name_hash,
1019                                         const struct security_token **pp_nt_tok,
1020                                         const struct security_unix_token **pp_tok)
1021 {
1022         struct delete_token *dt;
1023
1024         dt = find_delete_on_close_token(lck->data, name_hash);
1025         if (dt == NULL) {
1026                 return false;
1027         }
1028         *pp_nt_tok = dt->delete_nt_token;
1029         *pp_tok =  dt->delete_token;
1030         return true;
1031 }
1032
1033 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1034 {
1035         return find_delete_on_close_token(lck->data, name_hash) != NULL;
1036 }
1037
1038 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1039 {
1040         struct share_mode_lock *lck;
1041
1042         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1043                  timestring(talloc_tos(),
1044                             convert_timespec_to_time_t(write_time)),
1045                  file_id_string_tos(&fileid)));
1046
1047         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1048         if (lck == NULL) {
1049                 return False;
1050         }
1051
1052         if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1053                 lck->data->modified = True;
1054                 lck->data->changed_write_time = write_time;
1055         }
1056
1057         TALLOC_FREE(lck);
1058         return True;
1059 }
1060
1061 bool set_write_time(struct file_id fileid, struct timespec write_time)
1062 {
1063         struct share_mode_lock *lck;
1064
1065         DEBUG(5,("set_write_time: %s id=%s\n",
1066                  timestring(talloc_tos(),
1067                             convert_timespec_to_time_t(write_time)),
1068                  file_id_string_tos(&fileid)));
1069
1070         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1071         if (lck == NULL) {
1072                 return False;
1073         }
1074
1075         if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1076                 lck->data->modified = True;
1077                 lck->data->old_write_time = write_time;
1078         }
1079
1080         TALLOC_FREE(lck);
1081         return True;
1082 }
1083
1084 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1085 {
1086         struct share_mode_data *d = lck->data;
1087
1088         if (!null_timespec(d->changed_write_time)) {
1089                 return d->changed_write_time;
1090         }
1091         return d->old_write_time;
1092 }