s3: Use autogenerated open_files.idl
[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    rewrtten 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 /* the locking database handle */
56 static struct db_context *lock_db;
57
58 /****************************************************************************
59  Debugging aids :-).
60 ****************************************************************************/
61
62 const char *lock_type_name(enum brl_type lock_type)
63 {
64         switch (lock_type) {
65                 case READ_LOCK:
66                         return "READ";
67                 case WRITE_LOCK:
68                         return "WRITE";
69                 case PENDING_READ_LOCK:
70                         return "PENDING_READ";
71                 case PENDING_WRITE_LOCK:
72                         return "PENDING_WRITE";
73                 default:
74                         return "other";
75         }
76 }
77
78 const char *lock_flav_name(enum brl_flavour lock_flav)
79 {
80         return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
81 }
82
83 /****************************************************************************
84  Utility function called to see if a file region is locked.
85  Called in the read/write codepath.
86 ****************************************************************************/
87
88 void init_strict_lock_struct(files_struct *fsp,
89                                 uint64_t smblctx,
90                                 br_off start,
91                                 br_off size,
92                                 enum brl_type lock_type,
93                                 struct lock_struct *plock)
94 {
95         SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
96
97         plock->context.smblctx = smblctx;
98         plock->context.tid = fsp->conn->cnum;
99         plock->context.pid = sconn_server_id(fsp->conn->sconn);
100         plock->start = start;
101         plock->size = size;
102         plock->fnum = fsp->fnum;
103         plock->lock_type = lock_type;
104         plock->lock_flav = lp_posix_cifsu_locktype(fsp);
105 }
106
107 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
108 {
109         int strict_locking = lp_strict_locking(fsp->conn->params);
110         bool ret = False;
111
112         if (plock->size == 0) {
113                 return True;
114         }
115
116         if (!lp_locking(fsp->conn->params) || !strict_locking) {
117                 return True;
118         }
119
120         if (strict_locking == Auto) {
121                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
122                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
123                         ret = True;
124                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
125                            (plock->lock_type == READ_LOCK)) {
126                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
127                         ret = True;
128                 } else {
129                         struct byte_range_lock *br_lck;
130
131                         br_lck = brl_get_locks_readonly(fsp);
132                         if (!br_lck) {
133                                 return True;
134                         }
135                         ret = brl_locktest(br_lck,
136                                         plock->context.smblctx,
137                                         plock->context.pid,
138                                         plock->start,
139                                         plock->size,
140                                         plock->lock_type,
141                                         plock->lock_flav);
142                 }
143         } else {
144                 struct byte_range_lock *br_lck;
145
146                 br_lck = brl_get_locks_readonly(fsp);
147                 if (!br_lck) {
148                         return True;
149                 }
150                 ret = brl_locktest(br_lck,
151                                 plock->context.smblctx,
152                                 plock->context.pid,
153                                 plock->start,
154                                 plock->size,
155                                 plock->lock_type,
156                                 plock->lock_flav);
157         }
158
159         DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
160                         "len=%.0f %s for fnum %d file %s\n",
161                         lock_flav_name(plock->lock_flav),
162                         (double)plock->start, (double)plock->size,
163                         ret ? "unlocked" : "locked",
164                         plock->fnum, fsp_str_dbg(fsp)));
165
166         return ret;
167 }
168
169 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
170 {
171 }
172
173 /****************************************************************************
174  Find out if a lock could be granted - return who is blocking us if we can't.
175 ****************************************************************************/
176
177 NTSTATUS query_lock(files_struct *fsp,
178                         uint64_t *psmblctx,
179                         uint64_t *pcount,
180                         uint64_t *poffset,
181                         enum brl_type *plock_type,
182                         enum brl_flavour lock_flav)
183 {
184         struct byte_range_lock *br_lck = NULL;
185
186         if (!fsp->can_lock) {
187                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
188         }
189
190         if (!lp_locking(fsp->conn->params)) {
191                 return NT_STATUS_OK;
192         }
193
194         br_lck = brl_get_locks_readonly(fsp);
195         if (!br_lck) {
196                 return NT_STATUS_NO_MEMORY;
197         }
198
199         return brl_lockquery(br_lck,
200                         psmblctx,
201                         sconn_server_id(fsp->conn->sconn),
202                         poffset,
203                         pcount,
204                         plock_type,
205                         lock_flav);
206 }
207
208 static void increment_current_lock_count(files_struct *fsp,
209     enum brl_flavour lock_flav)
210 {
211         if (lock_flav == WINDOWS_LOCK &&
212             fsp->current_lock_count != NO_LOCKING_COUNT) {
213                 /* blocking ie. pending, locks also count here,
214                  * as this is an efficiency counter to avoid checking
215                  * the lock db. on close. JRA. */
216
217                 fsp->current_lock_count++;
218         } else {
219                 /* Notice that this has had a POSIX lock request.
220                  * We can't count locks after this so forget them.
221                  */
222                 fsp->current_lock_count = NO_LOCKING_COUNT;
223         }
224 }
225
226 static void decrement_current_lock_count(files_struct *fsp,
227     enum brl_flavour lock_flav)
228 {
229         if (lock_flav == WINDOWS_LOCK &&
230             fsp->current_lock_count != NO_LOCKING_COUNT) {
231                 SMB_ASSERT(fsp->current_lock_count > 0);
232                 fsp->current_lock_count--;
233         }
234 }
235
236 /****************************************************************************
237  Utility function called by locking requests.
238 ****************************************************************************/
239
240 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
241                         files_struct *fsp,
242                         uint64_t smblctx,
243                         uint64_t count,
244                         uint64_t offset,
245                         enum brl_type lock_type,
246                         enum brl_flavour lock_flav,
247                         bool blocking_lock,
248                         NTSTATUS *perr,
249                         uint64_t *psmblctx,
250                         struct blocking_lock_record *blr)
251 {
252         struct byte_range_lock *br_lck = NULL;
253
254         /* silently return ok on print files as we don't do locking there */
255         if (fsp->print_file) {
256                 *perr = NT_STATUS_OK;
257                 return NULL;
258         }
259
260         if (!fsp->can_lock) {
261                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
262                 return NULL;
263         }
264
265         if (!lp_locking(fsp->conn->params)) {
266                 *perr = NT_STATUS_OK;
267                 return NULL;
268         }
269
270         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
271
272         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
273                 "blocking_lock=%s requested for fnum %d file %s\n",
274                 lock_flav_name(lock_flav), lock_type_name(lock_type),
275                 (double)offset, (double)count, blocking_lock ? "true" :
276                 "false", fsp->fnum, fsp_str_dbg(fsp)));
277
278         br_lck = brl_get_locks(talloc_tos(), fsp);
279         if (!br_lck) {
280                 *perr = NT_STATUS_NO_MEMORY;
281                 return NULL;
282         }
283
284         *perr = brl_lock(msg_ctx,
285                         br_lck,
286                         smblctx,
287                         sconn_server_id(fsp->conn->sconn),
288                         offset,
289                         count,
290                         lock_type,
291                         lock_flav,
292                         blocking_lock,
293                         psmblctx,
294                         blr);
295
296         DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
297
298         increment_current_lock_count(fsp, lock_flav);
299         return br_lck;
300 }
301
302 /****************************************************************************
303  Utility function called by unlocking requests.
304 ****************************************************************************/
305
306 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
307                         files_struct *fsp,
308                         uint64_t smblctx,
309                         uint64_t count,
310                         uint64_t offset,
311                         enum brl_flavour lock_flav)
312 {
313         bool ok = False;
314         struct byte_range_lock *br_lck = NULL;
315
316         if (!fsp->can_lock) {
317                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
318         }
319
320         if (!lp_locking(fsp->conn->params)) {
321                 return NT_STATUS_OK;
322         }
323
324         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
325                   (double)offset, (double)count, fsp->fnum,
326                   fsp_str_dbg(fsp)));
327
328         br_lck = brl_get_locks(talloc_tos(), fsp);
329         if (!br_lck) {
330                 return NT_STATUS_NO_MEMORY;
331         }
332
333         ok = brl_unlock(msg_ctx,
334                         br_lck,
335                         smblctx,
336                         sconn_server_id(fsp->conn->sconn),
337                         offset,
338                         count,
339                         lock_flav);
340
341         TALLOC_FREE(br_lck);
342
343         if (!ok) {
344                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
345                 return NT_STATUS_RANGE_NOT_LOCKED;
346         }
347
348         decrement_current_lock_count(fsp, lock_flav);
349         return NT_STATUS_OK;
350 }
351
352 /****************************************************************************
353  Cancel any pending blocked locks.
354 ****************************************************************************/
355
356 NTSTATUS do_lock_cancel(files_struct *fsp,
357                         uint64 smblctx,
358                         uint64_t count,
359                         uint64_t offset,
360                         enum brl_flavour lock_flav,
361                         struct blocking_lock_record *blr)
362 {
363         bool ok = False;
364         struct byte_range_lock *br_lck = NULL;
365
366         if (!fsp->can_lock) {
367                 return fsp->is_directory ?
368                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
369         }
370
371         if (!lp_locking(fsp->conn->params)) {
372                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
373         }
374
375         DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
376                   (double)offset, (double)count, fsp->fnum,
377                   fsp_str_dbg(fsp)));
378
379         br_lck = brl_get_locks(talloc_tos(), fsp);
380         if (!br_lck) {
381                 return NT_STATUS_NO_MEMORY;
382         }
383
384         ok = brl_lock_cancel(br_lck,
385                         smblctx,
386                         sconn_server_id(fsp->conn->sconn),
387                         offset,
388                         count,
389                         lock_flav,
390                         blr);
391
392         TALLOC_FREE(br_lck);
393
394         if (!ok) {
395                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
396                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
397         }
398
399         decrement_current_lock_count(fsp, lock_flav);
400         return NT_STATUS_OK;
401 }
402
403 /****************************************************************************
404  Remove any locks on this fd. Called from file_close().
405 ****************************************************************************/
406
407 void locking_close_file(struct messaging_context *msg_ctx,
408                         files_struct *fsp,
409                         enum file_close_type close_type)
410 {
411         struct byte_range_lock *br_lck;
412
413         if (!lp_locking(fsp->conn->params)) {
414                 return;
415         }
416
417         /* If we have not outstanding locks or pending
418          * locks then we don't need to look in the lock db.
419          */
420
421         if (fsp->current_lock_count == 0) {
422                 return;
423         }
424
425         br_lck = brl_get_locks(talloc_tos(),fsp);
426
427         if (br_lck) {
428                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
429                 brl_close_fnum(msg_ctx, br_lck);
430                 TALLOC_FREE(br_lck);
431         }
432 }
433
434 /****************************************************************************
435  Initialise the locking functions.
436 ****************************************************************************/
437
438 static bool locking_init_internal(bool read_only)
439 {
440         brl_init(read_only);
441
442         if (lock_db)
443                 return True;
444
445         lock_db = db_open(NULL, lock_path("locking.tdb"),
446                           lp_open_files_db_hash_size(),
447                           TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
448                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
449
450         if (!lock_db) {
451                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
452                 return False;
453         }
454
455         if (!posix_locking_init(read_only))
456                 return False;
457
458         return True;
459 }
460
461 bool locking_init(void)
462 {
463         return locking_init_internal(false);
464 }
465
466 bool locking_init_readonly(void)
467 {
468         return locking_init_internal(true);
469 }
470
471 /*******************************************************************
472  Deinitialize the share_mode management.
473 ******************************************************************/
474
475 bool locking_end(void)
476 {
477         brl_shutdown();
478         TALLOC_FREE(lock_db);
479         return true;
480 }
481
482 /*******************************************************************
483  Form a static locking key for a dev/inode pair.
484 ******************************************************************/
485
486 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
487 {
488         *tmp = *id;
489         return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
490 }
491
492 /*******************************************************************
493  Print out a share mode.
494 ********************************************************************/
495
496 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
497 {
498         return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
499                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
500                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
501                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
502                  num,
503                  e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
504                  procid_str_static(&e->pid),
505                  e->share_access, e->private_options,
506                  e->access_mask, (unsigned long long)e->op_mid,
507                  e->op_type, e->share_file_id,
508                  (unsigned int)e->uid, (unsigned int)e->flags,
509                  file_id_string_tos(&e->id),
510                  (unsigned int)e->name_hash);
511 }
512
513 /*******************************************************************
514  Get all share mode entries for a dev/inode pair.
515 ********************************************************************/
516
517 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
518 {
519         int i;
520         struct server_id *pids;
521         bool *pid_exists;
522         enum ndr_err_code ndr_err;
523         DATA_BLOB blob;
524
525         blob.data = dbuf.dptr;
526         blob.length = dbuf.dsize;
527
528         ndr_err = ndr_pull_struct_blob(
529                 &blob, lck, lck,
530                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
531         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
532                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
533                 return false;
534         }
535
536         lck->modified = false;
537
538         if (DEBUGLEVEL >= 10) {
539                 DEBUG(10, ("parse_share_modes:\n"));
540                 NDR_PRINT_DEBUG(share_mode_lock, lck);
541         }
542
543         /*
544          * Ensure that each entry has a real process attached.
545          */
546
547         pids = talloc_array(talloc_tos(), struct server_id,
548                             lck->num_share_modes);
549         if (pids == NULL) {
550                 smb_panic("parse_share_modes: talloc_array failed");
551         }
552         pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
553         if (pid_exists == NULL) {
554                 smb_panic("parse_share_modes: talloc_array failed");
555         }
556
557         for (i=0; i<lck->num_share_modes; i++) {
558                 pids[i] = lck->share_modes[i].pid;
559         }
560
561         if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
562                 smb_panic("parse_share_modes: serverids_exist failed");
563         }
564
565         for (i = 0; i < lck->num_share_modes; i++) {
566                 struct share_mode_entry *entry_p = &lck->share_modes[i];
567                 if (!pid_exists[i]) {
568                         entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
569                         lck->modified = True;
570                 }
571         }
572         TALLOC_FREE(pid_exists);
573         TALLOC_FREE(pids);
574
575         return True;
576 }
577
578 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
579 {
580         DATA_BLOB blob;
581         enum ndr_err_code ndr_err;
582         uint32_t i;
583
584         if (DEBUGLEVEL >= 10) {
585                 DEBUG(10, ("unparse_share_modes:\n"));
586                 NDR_PRINT_DEBUG(share_mode_lock, lck);
587         }
588
589         for (i=0; i<lck->num_share_modes; i++) {
590                 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
591                         break;
592                 }
593         }
594         if (i == lck->num_share_modes) {
595                 DEBUG(10, ("No used share mode found\n"));
596                 return make_tdb_data(NULL, 0);
597         }
598
599         ndr_err = ndr_push_struct_blob(
600                 &blob, lck, lck,
601                 (ndr_push_flags_fn_t)ndr_push_share_mode_lock);
602         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
603                 smb_panic("ndr_push_share_mode_lock failed");
604         }
605
606         return make_tdb_data(blob.data, blob.length);
607 }
608
609 static int share_mode_lock_destructor(struct share_mode_lock *lck)
610 {
611         NTSTATUS status;
612         TDB_DATA data;
613
614         if (!lck->modified) {
615                 return 0;
616         }
617
618         data = unparse_share_modes(lck);
619
620         if (data.dptr == NULL) {
621                 if (!lck->fresh) {
622                         /* There has been an entry before, delete it */
623
624                         status = dbwrap_record_delete(lck->record);
625                         if (!NT_STATUS_IS_OK(status)) {
626                                 char *errmsg;
627
628                                 DEBUG(0, ("delete_rec returned %s\n",
629                                           nt_errstr(status)));
630
631                                 if (asprintf(&errmsg, "could not delete share "
632                                              "entry: %s\n",
633                                              nt_errstr(status)) == -1) {
634                                         smb_panic("could not delete share"
635                                                   "entry");
636                                 }
637                                 smb_panic(errmsg);
638                         }
639                 }
640                 goto done;
641         }
642
643         status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
644         if (!NT_STATUS_IS_OK(status)) {
645                 char *errmsg;
646
647                 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
648
649                 if (asprintf(&errmsg, "could not store share mode entry: %s",
650                              nt_errstr(status)) == -1) {
651                         smb_panic("could not store share mode entry");
652                 }
653                 smb_panic(errmsg);
654         }
655
656  done:
657
658         return 0;
659 }
660
661 static bool fill_share_mode_lock(struct share_mode_lock *lck,
662                                  struct file_id id,
663                                  const char *servicepath,
664                                  const struct smb_filename *smb_fname,
665                                  TDB_DATA share_mode_data,
666                                  const struct timespec *old_write_time)
667 {
668         bool fresh;
669
670         /* Ensure we set every field here as the destructor must be
671            valid even if parse_share_modes fails. */
672
673         lck->servicepath = NULL;
674         lck->base_name = NULL;
675         lck->stream_name = NULL;
676         lck->id = id;
677         lck->num_share_modes = 0;
678         lck->share_modes = NULL;
679         lck->num_delete_tokens = 0;
680         lck->delete_tokens = NULL;
681         ZERO_STRUCT(lck->old_write_time);
682         ZERO_STRUCT(lck->changed_write_time);
683
684         fresh = (share_mode_data.dptr == NULL);
685
686         if (fresh) {
687                 bool has_stream;
688                 if (smb_fname == NULL || servicepath == NULL
689                     || old_write_time == NULL) {
690                         return False;
691                 }
692
693                 has_stream = smb_fname->stream_name != NULL;
694
695                 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
696                 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
697                 lck->servicepath = talloc_strdup(lck, servicepath);
698                 if (lck->base_name == NULL ||
699                     (has_stream && lck->stream_name == NULL) ||
700                     lck->servicepath == NULL) {
701                         DEBUG(0, ("talloc failed\n"));
702                         return False;
703                 }
704                 lck->old_write_time = *old_write_time;
705                 lck->modified = false;
706         } else {
707                 if (!parse_share_modes(share_mode_data, lck)) {
708                         DEBUG(0, ("Could not parse share modes\n"));
709                         return False;
710                 }
711         }
712         lck->fresh = fresh;
713
714         return True;
715 }
716
717 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
718                                             const struct file_id id,
719                                             const char *servicepath,
720                                             const struct smb_filename *smb_fname,
721                                             const struct timespec *old_write_time)
722 {
723         struct share_mode_lock *lck;
724         struct file_id tmp;
725         struct db_record *rec;
726         TDB_DATA key = locking_key(&id, &tmp);
727         TDB_DATA value;
728
729         if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
730                 DEBUG(0, ("talloc failed\n"));
731                 return NULL;
732         }
733
734         rec = dbwrap_fetch_locked(lock_db, lck, key);
735         if (rec == NULL) {
736                 DEBUG(3, ("Could not lock share entry\n"));
737                 TALLOC_FREE(lck);
738                 return NULL;
739         }
740
741         value = dbwrap_record_get_value(rec);
742
743         if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
744                                   value, old_write_time)) {
745                 DEBUG(3, ("fill_share_mode_lock failed\n"));
746                 TALLOC_FREE(lck);
747                 return NULL;
748         }
749
750         lck->record = rec;
751         talloc_set_destructor(lck, share_mode_lock_destructor);
752
753         return lck;
754 }
755
756 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
757                                                   const struct file_id id)
758 {
759         struct share_mode_lock *lck;
760         struct file_id tmp;
761         TDB_DATA key = locking_key(&id, &tmp);
762         TDB_DATA data;
763         NTSTATUS status;
764
765         if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
766                 DEBUG(0, ("talloc failed\n"));
767                 return NULL;
768         }
769
770         status = dbwrap_fetch(lock_db, lck, key, &data);
771         if (!NT_STATUS_IS_OK(status)) {
772                 DEBUG(3, ("Could not fetch share entry\n"));
773                 TALLOC_FREE(lck);
774                 return NULL;
775         }
776
777         if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
778                 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
779                            "around (file not open)\n"));
780                 TALLOC_FREE(lck);
781                 return NULL;
782         }
783
784         return lck;
785 }
786
787 /*******************************************************************
788  Sets the service name and filename for rename.
789  At this point we emit "file renamed" messages to all
790  process id's that have this file open.
791  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
792 ********************************************************************/
793
794 bool rename_share_filename(struct messaging_context *msg_ctx,
795                         struct share_mode_lock *lck,
796                         const char *servicepath,
797                         uint32_t orig_name_hash,
798                         uint32_t new_name_hash,
799                         const struct smb_filename *smb_fname_dst)
800 {
801         size_t sp_len;
802         size_t bn_len;
803         size_t sn_len;
804         size_t msg_len;
805         char *frm = NULL;
806         int i;
807         bool strip_two_chars = false;
808         bool has_stream = smb_fname_dst->stream_name != NULL;
809
810         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
811                    servicepath, smb_fname_dst->base_name));
812
813         /*
814          * rename_internal_fsp() and rename_internals() add './' to
815          * head of newname if newname does not contain a '/'.
816          */
817         if (smb_fname_dst->base_name[0] &&
818             smb_fname_dst->base_name[1] &&
819             smb_fname_dst->base_name[0] == '.' &&
820             smb_fname_dst->base_name[1] == '/') {
821                 strip_two_chars = true;
822         }
823
824         lck->servicepath = talloc_strdup(lck, servicepath);
825         lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
826                                        (strip_two_chars ? 2 : 0));
827         lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
828         if (lck->base_name == NULL ||
829             (has_stream && lck->stream_name == NULL) ||
830             lck->servicepath == NULL) {
831                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
832                 return False;
833         }
834         lck->modified = True;
835
836         sp_len = strlen(lck->servicepath);
837         bn_len = strlen(lck->base_name);
838         sn_len = has_stream ? strlen(lck->stream_name) : 0;
839
840         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
841             sn_len + 1;
842
843         /* Set up the name changed message. */
844         frm = talloc_array(lck, char, msg_len);
845         if (!frm) {
846                 return False;
847         }
848
849         push_file_id_24(frm, &lck->id);
850
851         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
852
853         strlcpy(&frm[24],
854                 lck->servicepath ? lck->servicepath : "",
855                 sp_len+1);
856         strlcpy(&frm[24 + sp_len + 1],
857                 lck->base_name ? lck->base_name : "",
858                 bn_len+1);
859         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
860                 lck->stream_name ? lck->stream_name : "",
861                 sn_len+1);
862
863         /* Send the messages. */
864         for (i=0; i<lck->num_share_modes; i++) {
865                 struct share_mode_entry *se = &lck->share_modes[i];
866                 if (!is_valid_share_mode_entry(se)) {
867                         continue;
868                 }
869
870                 /* If this is a hardlink to the inode
871                    with a different name, skip this. */
872                 if (se->name_hash != orig_name_hash) {
873                         continue;
874                 }
875
876                 se->name_hash = new_name_hash;
877
878                 /* But not to ourselves... */
879                 if (procid_is_me(&se->pid)) {
880                         continue;
881                 }
882
883                 DEBUG(10,("rename_share_filename: sending rename message to "
884                           "pid %s file_id %s sharepath %s base_name %s "
885                           "stream_name %s\n",
886                           procid_str_static(&se->pid),
887                           file_id_string_tos(&lck->id),
888                           lck->servicepath, lck->base_name,
889                         has_stream ? lck->stream_name : ""));
890
891                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
892                                    (uint8 *)frm, msg_len);
893         }
894
895         return True;
896 }
897
898 void get_file_infos(struct file_id id,
899                     uint32_t name_hash,
900                     bool *delete_on_close,
901                     struct timespec *write_time)
902 {
903         struct share_mode_lock *lck;
904
905         if (delete_on_close) {
906                 *delete_on_close = false;
907         }
908
909         if (write_time) {
910                 ZERO_STRUCTP(write_time);
911         }
912
913         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
914                 return;
915         }
916
917         if (delete_on_close) {
918                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
919         }
920
921         if (write_time) {
922                 struct timespec wt;
923
924                 wt = lck->changed_write_time;
925                 if (null_timespec(wt)) {
926                         wt = lck->old_write_time;
927                 }
928
929                 *write_time = wt;
930         }
931
932         TALLOC_FREE(lck);
933 }
934
935 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
936 {
937         int num_props = 0;
938
939         if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
940                 /* cope with dead entries from the process not
941                    existing. These should not be considered valid,
942                    otherwise we end up doing zero timeout sharing
943                    violation */
944                 return False;
945         }
946
947         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
948         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
949         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
950
951         SMB_ASSERT(num_props <= 1);
952         return (num_props != 0);
953 }
954
955 bool is_deferred_open_entry(const struct share_mode_entry *e)
956 {
957         return (e->op_type == DEFERRED_OPEN_ENTRY);
958 }
959
960 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
961 {
962         return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
963 }
964
965 /*******************************************************************
966  Fill a share mode entry.
967 ********************************************************************/
968
969 static void fill_share_mode_entry(struct share_mode_entry *e,
970                                   files_struct *fsp,
971                                   uid_t uid, uint64_t mid, uint16 op_type)
972 {
973         ZERO_STRUCTP(e);
974         e->pid = sconn_server_id(fsp->conn->sconn);
975         e->share_access = fsp->share_access;
976         e->private_options = fsp->fh->private_options;
977         e->access_mask = fsp->access_mask;
978         e->op_mid = mid;
979         e->op_type = op_type;
980         e->time.tv_sec = fsp->open_time.tv_sec;
981         e->time.tv_usec = fsp->open_time.tv_usec;
982         e->id = fsp->file_id;
983         e->share_file_id = fsp->fh->gen_id;
984         e->uid = (uint32)uid;
985         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
986         e->name_hash = fsp->name_hash;
987 }
988
989 static void fill_deferred_open_entry(struct share_mode_entry *e,
990                                      const struct timeval request_time,
991                                      struct file_id id,
992                                      struct server_id pid,
993                                      uint64_t mid)
994 {
995         ZERO_STRUCTP(e);
996         e->pid = pid;
997         e->op_mid = mid;
998         e->op_type = DEFERRED_OPEN_ENTRY;
999         e->time.tv_sec = request_time.tv_sec;
1000         e->time.tv_usec = request_time.tv_usec;
1001         e->id = id;
1002         e->uid = (uint32)-1;
1003         e->flags = 0;
1004 }
1005
1006 static void add_share_mode_entry(struct share_mode_lock *lck,
1007                                  const struct share_mode_entry *entry)
1008 {
1009         int i;
1010
1011         for (i=0; i<lck->num_share_modes; i++) {
1012                 struct share_mode_entry *e = &lck->share_modes[i];
1013                 if (is_unused_share_mode_entry(e)) {
1014                         *e = *entry;
1015                         break;
1016                 }
1017         }
1018
1019         if (i == lck->num_share_modes) {
1020                 /* No unused entry found */
1021                 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1022                              &lck->share_modes, &lck->num_share_modes);
1023         }
1024         lck->modified = True;
1025 }
1026
1027 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1028                     uid_t uid, uint64_t mid, uint16 op_type)
1029 {
1030         struct share_mode_entry entry;
1031         fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1032         add_share_mode_entry(lck, &entry);
1033 }
1034
1035 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1036                        struct timeval request_time,
1037                        struct server_id pid, struct file_id id)
1038 {
1039         struct share_mode_entry entry;
1040         fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1041         add_share_mode_entry(lck, &entry);
1042 }
1043
1044 /*******************************************************************
1045  Check if two share mode entries are identical, ignoring oplock 
1046  and mid info and desired_access. (Removed paranoia test - it's
1047  not automatically a logic error if they are identical. JRA.)
1048 ********************************************************************/
1049
1050 static bool share_modes_identical(struct share_mode_entry *e1,
1051                                   struct share_mode_entry *e2)
1052 {
1053         /* We used to check for e1->share_access == e2->share_access here
1054            as well as the other fields but 2 different DOS or FCB opens
1055            sharing the same share mode entry may validly differ in
1056            fsp->share_access field. */
1057
1058         return (procid_equal(&e1->pid, &e2->pid) &&
1059                 file_id_equal(&e1->id, &e2->id) &&
1060                 e1->share_file_id == e2->share_file_id );
1061 }
1062
1063 static bool deferred_open_identical(struct share_mode_entry *e1,
1064                                     struct share_mode_entry *e2)
1065 {
1066         return (procid_equal(&e1->pid, &e2->pid) &&
1067                 (e1->op_mid == e2->op_mid) &&
1068                 file_id_equal(&e1->id, &e2->id));
1069 }
1070
1071 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1072                                                       struct share_mode_entry *entry)
1073 {
1074         int i;
1075
1076         for (i=0; i<lck->num_share_modes; i++) {
1077                 struct share_mode_entry *e = &lck->share_modes[i];
1078                 if (is_valid_share_mode_entry(entry) &&
1079                     is_valid_share_mode_entry(e) &&
1080                     share_modes_identical(e, entry)) {
1081                         return e;
1082                 }
1083                 if (is_deferred_open_entry(entry) &&
1084                     is_deferred_open_entry(e) &&
1085                     deferred_open_identical(e, entry)) {
1086                         return e;
1087                 }
1088         }
1089         return NULL;
1090 }
1091
1092 /*******************************************************************
1093  Del the share mode of a file for this process. Return the number of
1094  entries left.
1095 ********************************************************************/
1096
1097 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1098 {
1099         struct share_mode_entry entry, *e;
1100
1101         /* Don't care about the pid owner being correct here - just a search. */
1102         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1103
1104         e = find_share_mode_entry(lck, &entry);
1105         if (e == NULL) {
1106                 return False;
1107         }
1108
1109         e->op_type = UNUSED_SHARE_MODE_ENTRY;
1110         lck->modified = True;
1111         return True;
1112 }
1113
1114 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1115                              struct server_id pid)
1116 {
1117         struct share_mode_entry entry, *e;
1118
1119         fill_deferred_open_entry(&entry, timeval_zero(),
1120                                  lck->id, pid, mid);
1121
1122         e = find_share_mode_entry(lck, &entry);
1123         if (e == NULL) {
1124                 return;
1125         }
1126
1127         e->op_type = UNUSED_SHARE_MODE_ENTRY;
1128         lck->modified = True;
1129 }
1130
1131 /*******************************************************************
1132  Remove an oplock mid and mode entry from a share mode.
1133 ********************************************************************/
1134
1135 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1136 {
1137         struct share_mode_entry entry, *e;
1138
1139         /* Don't care about the pid owner being correct here - just a search. */
1140         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1141
1142         e = find_share_mode_entry(lck, &entry);
1143         if (e == NULL) {
1144                 return False;
1145         }
1146
1147         if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1148                 /*
1149                  * Going from exclusive or batch,
1150                  * we always go through FAKE_LEVEL_II
1151                  * first.
1152                  */
1153                 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1154                         smb_panic("remove_share_oplock: logic error");
1155                 }
1156                 e->op_type = FAKE_LEVEL_II_OPLOCK;
1157         } else {
1158                 e->op_type = NO_OPLOCK;
1159         }
1160         lck->modified = True;
1161         return True;
1162 }
1163
1164 /*******************************************************************
1165  Downgrade a oplock type from exclusive to level II.
1166 ********************************************************************/
1167
1168 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1169 {
1170         struct share_mode_entry entry, *e;
1171
1172         /* Don't care about the pid owner being correct here - just a search. */
1173         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1174
1175         e = find_share_mode_entry(lck, &entry);
1176         if (e == NULL) {
1177                 return False;
1178         }
1179
1180         e->op_type = LEVEL_II_OPLOCK;
1181         lck->modified = True;
1182         return True;
1183 }
1184
1185 /****************************************************************************
1186  Check if setting delete on close is allowed on this fsp.
1187 ****************************************************************************/
1188
1189 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1190 {
1191         /*
1192          * Only allow delete on close for writable files.
1193          */
1194
1195         if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
1196             !lp_delete_readonly(SNUM(fsp->conn))) {
1197                 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1198                           "flag set but file attribute is readonly.\n",
1199                           fsp_str_dbg(fsp)));
1200                 return NT_STATUS_CANNOT_DELETE;
1201         }
1202
1203         /*
1204          * Only allow delete on close for writable shares.
1205          */
1206
1207         if (!CAN_WRITE(fsp->conn)) {
1208                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1209                           "close flag set but write access denied on share.\n",
1210                           fsp_str_dbg(fsp)));
1211                 return NT_STATUS_ACCESS_DENIED;
1212         }
1213
1214         /*
1215          * Only allow delete on close for files/directories opened with delete
1216          * intent.
1217          */
1218
1219         if (!(fsp->access_mask & DELETE_ACCESS)) {
1220                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1221                           "close flag set but delete access denied.\n",
1222                           fsp_str_dbg(fsp)));
1223                 return NT_STATUS_ACCESS_DENIED;
1224         }
1225
1226         /* Don't allow delete on close for non-empty directories. */
1227         if (fsp->is_directory) {
1228                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1229
1230                 /* Or the root of a share. */
1231                 if (ISDOT(fsp->fsp_name->base_name)) {
1232                         DEBUG(10,("can_set_delete_on_close: can't set delete on "
1233                                   "close for the root of a share.\n"));
1234                         return NT_STATUS_ACCESS_DENIED;
1235                 }
1236
1237                 return can_delete_directory(fsp->conn,
1238                                             fsp->fsp_name->base_name);
1239         }
1240
1241         return NT_STATUS_OK;
1242 }
1243
1244 /*************************************************************************
1245  Return a talloced copy of a struct security_unix_token. NULL on fail.
1246  (Should this be in locking.c.... ?).
1247 *************************************************************************/
1248
1249 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1250 {
1251         struct security_unix_token *cpy;
1252
1253         cpy = talloc(ctx, struct security_unix_token);
1254         if (!cpy) {
1255                 return NULL;
1256         }
1257
1258         cpy->uid = tok->uid;
1259         cpy->gid = tok->gid;
1260         cpy->ngroups = tok->ngroups;
1261         if (tok->ngroups) {
1262                 /* Make this a talloc child of cpy. */
1263                 cpy->groups = (gid_t *)talloc_memdup(
1264                         cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1265                 if (!cpy->groups) {
1266                         TALLOC_FREE(cpy);
1267                         return NULL;
1268                 }
1269         }
1270         return cpy;
1271 }
1272
1273 /****************************************************************************
1274  Adds a delete on close token.
1275 ****************************************************************************/
1276
1277 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1278                         uint32_t name_hash,
1279                         const struct security_unix_token *tok)
1280 {
1281         struct delete_token *tmp, *dtl;
1282
1283         tmp = talloc_realloc(lck, lck->delete_tokens, struct delete_token,
1284                              lck->num_delete_tokens+1);
1285         if (tmp == NULL) {
1286                 return false;
1287         }
1288         lck->delete_tokens = tmp;
1289         dtl = &lck->delete_tokens[lck->num_delete_tokens];
1290
1291         dtl->name_hash = name_hash;
1292         dtl->delete_token = copy_unix_token(lck->delete_tokens, tok);
1293         if (dtl->delete_token == NULL) {
1294                 return false;
1295         }
1296         lck->num_delete_tokens += 1;
1297         lck->modified = true;
1298         return true;
1299 }
1300
1301 /****************************************************************************
1302  Sets the delete on close flag over all share modes on this file.
1303  Modify the share mode entry for all files open
1304  on this device and inode to tell other smbds we have
1305  changed the delete on close flag. This will be noticed
1306  in the close code, the last closer will delete the file
1307  if flag is set.
1308  This makes a copy of any struct security_unix_token into the
1309  lck entry. This function is used when the lock is already granted.
1310 ****************************************************************************/
1311
1312 void set_delete_on_close_lck(files_struct *fsp,
1313                         struct share_mode_lock *lck,
1314                         bool delete_on_close,
1315                         const struct security_unix_token *tok)
1316 {
1317         int i;
1318         bool ret;
1319
1320         if (delete_on_close) {
1321                 SMB_ASSERT(tok != NULL);
1322         } else {
1323                 SMB_ASSERT(tok == NULL);
1324         }
1325
1326         for (i=0; i<lck->num_delete_tokens; i++) {
1327                 struct delete_token *dt = &lck->delete_tokens[i];
1328                 if (dt->name_hash == fsp->name_hash) {
1329                         lck->modified = true;
1330                         if (delete_on_close == false) {
1331                                 /* Delete this entry. */
1332                                 TALLOC_FREE(dt->delete_token);
1333                                 *dt = lck->delete_tokens[
1334                                         lck->num_delete_tokens-1];
1335                                 lck->num_delete_tokens -= 1;
1336                                 return;
1337                         }
1338                         /* Replace this token with the
1339                            given tok. */
1340                         TALLOC_FREE(dt->delete_token);
1341                         dt->delete_token = copy_unix_token(dt, tok);
1342                         SMB_ASSERT(dt->delete_token != NULL);
1343                 }
1344         }
1345
1346         if (!delete_on_close) {
1347                 /* Nothing to delete - not found. */
1348                 return;
1349         }
1350
1351         ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1352         SMB_ASSERT(ret);
1353 }
1354
1355 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1356 {
1357         struct share_mode_lock *lck;
1358
1359         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1360                   "fnum = %d, file %s\n",
1361                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
1362                   fsp_str_dbg(fsp)));
1363
1364         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1365                                   NULL);
1366         if (lck == NULL) {
1367                 return False;
1368         }
1369
1370         set_delete_on_close_lck(fsp, lck, delete_on_close,
1371                         delete_on_close ? tok : NULL);
1372
1373         if (fsp->is_directory) {
1374                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1375                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1376                                                fsp->fsp_name->base_name);
1377         }
1378
1379         TALLOC_FREE(lck);
1380
1381         fsp->delete_on_close = delete_on_close;
1382
1383         return True;
1384 }
1385
1386 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1387 {
1388         int i;
1389
1390         DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1391                         (unsigned int)name_hash ));
1392
1393         for (i=0; i<lck->num_delete_tokens; i++) {
1394                 struct delete_token *dt = &lck->delete_tokens[i];
1395                 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1396                                 (unsigned int)dt->name_hash ));
1397                 if (dt->name_hash == name_hash) {
1398                         return dt->delete_token;
1399                 }
1400         }
1401         return NULL;
1402 }
1403
1404 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1405 {
1406         return (get_delete_on_close_token(lck, name_hash) != NULL);
1407 }
1408
1409 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1410 {
1411         struct share_mode_lock *lck;
1412
1413         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1414                  timestring(talloc_tos(),
1415                             convert_timespec_to_time_t(write_time)),
1416                  file_id_string_tos(&fileid)));
1417
1418         lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1419         if (lck == NULL) {
1420                 return False;
1421         }
1422
1423         if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1424                 lck->modified = True;
1425                 lck->changed_write_time = write_time;
1426         }
1427
1428         TALLOC_FREE(lck);
1429         return True;
1430 }
1431
1432 bool set_write_time(struct file_id fileid, struct timespec write_time)
1433 {
1434         struct share_mode_lock *lck;
1435
1436         DEBUG(5,("set_write_time: %s id=%s\n",
1437                  timestring(talloc_tos(),
1438                             convert_timespec_to_time_t(write_time)),
1439                  file_id_string_tos(&fileid)));
1440
1441         lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1442         if (lck == NULL) {
1443                 return False;
1444         }
1445
1446         if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1447                 lck->modified = True;
1448                 lck->old_write_time = write_time;
1449         }
1450
1451         TALLOC_FREE(lck);
1452         return True;
1453 }
1454
1455
1456 struct forall_state {
1457         void (*fn)(const struct share_mode_entry *entry,
1458                    const char *sharepath,
1459                    const char *fname,
1460                    void *private_data);
1461         void *private_data;
1462 };
1463
1464 static int traverse_fn(struct db_record *rec, void *_state)
1465 {
1466         struct forall_state *state = (struct forall_state *)_state;
1467         uint32_t i;
1468         TDB_DATA key;
1469         TDB_DATA value;
1470         DATA_BLOB blob;
1471         enum ndr_err_code ndr_err;
1472         struct share_mode_lock *lck;
1473
1474         key = dbwrap_record_get_key(rec);
1475         value = dbwrap_record_get_value(rec);
1476
1477         /* Ensure this is a locking_key record. */
1478         if (key.dsize != sizeof(struct file_id))
1479                 return 0;
1480
1481         lck = talloc(talloc_tos(), struct share_mode_lock);
1482         if (lck == NULL) {
1483                 return 0;
1484         }
1485
1486         blob.data = value.dptr;
1487         blob.length = value.dsize;
1488
1489         ndr_err = ndr_pull_struct_blob(
1490                 &blob, lck, lck,
1491                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
1492         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1493                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1494                 return 0;
1495         }
1496         for (i=0; i<lck->num_share_modes; i++) {
1497                 state->fn(&lck->share_modes[i],
1498                           lck->servicepath, lck->base_name,
1499                           state->private_data);
1500         }
1501         TALLOC_FREE(lck);
1502
1503         return 0;
1504 }
1505
1506 /*******************************************************************
1507  Call the specified function on each entry under management by the
1508  share mode system.
1509 ********************************************************************/
1510
1511 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1512                                  const char *, void *),
1513                       void *private_data)
1514 {
1515         struct forall_state state;
1516         NTSTATUS status;
1517         int count;
1518
1519         if (lock_db == NULL)
1520                 return 0;
1521
1522         state.fn = fn;
1523         state.private_data = private_data;
1524
1525         status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1526                                       &count);
1527
1528         if (!NT_STATUS_IS_OK(status)) {
1529                 return -1;
1530         } else {
1531                 return count;
1532         }
1533 }