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