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