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