smbd: Simplify logic in remove_stale_share_mode_entries
[samba.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2006
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewritten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
36 */
37
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "lib/util/server_id.h"
41 #include "locking/proto.h"
42 #include "smbd/globals.h"
43 #include "dbwrap/dbwrap.h"
44 #include "dbwrap/dbwrap_open.h"
45 #include "../libcli/security/security.h"
46 #include "serverid.h"
47 #include "messages.h"
48 #include "util_tdb.h"
49 #include "../librpc/gen_ndr/ndr_open_files.h"
50 #include "librpc/gen_ndr/ndr_file_id.h"
51 #include "locking/leases_db.h"
52
53 #undef DBGC_CLASS
54 #define DBGC_CLASS DBGC_LOCKING
55
56 #define NO_LOCKING_COUNT (-1)
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 = messaging_server_id(fsp->conn->sconn->msg_ctx);
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_check_default(files_struct *fsp, struct lock_struct *plock)
108 {
109         struct byte_range_lock *br_lck;
110         int strict_locking = lp_strict_locking(fsp->conn->params);
111         bool ret = False;
112
113         if (plock->size == 0) {
114                 return True;
115         }
116
117         if (!lp_locking(fsp->conn->params) || !strict_locking) {
118                 return True;
119         }
120
121         if (strict_locking == Auto) {
122                 uint32_t lease_type = fsp_lease_type(fsp);
123
124                 if ((lease_type & SMB2_LEASE_READ) &&
125                      (plock->lock_type == READ_LOCK))
126                 {
127                         DBG_DEBUG("optimisation - read lease on file %s\n",
128                                   fsp_str_dbg(fsp));
129                         return true;
130                 }
131
132                 if ((lease_type & SMB2_LEASE_WRITE) &&
133                      (plock->lock_type == WRITE_LOCK))
134                 {
135                         DBG_DEBUG("optimisation - write lease on file %s\n",
136                                   fsp_str_dbg(fsp));
137                         return true;
138                 }
139         }
140
141         br_lck = brl_get_locks_readonly(fsp);
142         if (!br_lck) {
143                 return true;
144         }
145         ret = brl_locktest(br_lck, plock);
146
147         if (!ret) {
148                 /*
149                  * We got a lock conflict. Retry with rw locks to enable
150                  * autocleanup. This is the slow path anyway.
151                  */
152                 br_lck = brl_get_locks(talloc_tos(), fsp);
153                 ret = brl_locktest(br_lck, plock);
154                 TALLOC_FREE(br_lck);
155         }
156
157         DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
158                    "len=%ju %s for fnum %ju file %s\n",
159                    lock_flav_name(plock->lock_flav),
160                    (uintmax_t)plock->start, (uintmax_t)plock->size,
161                    ret ? "unlocked" : "locked",
162                    (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
163
164         return ret;
165 }
166
167 /****************************************************************************
168  Find out if a lock could be granted - return who is blocking us if we can't.
169 ****************************************************************************/
170
171 NTSTATUS query_lock(files_struct *fsp,
172                         uint64_t *psmblctx,
173                         uint64_t *pcount,
174                         uint64_t *poffset,
175                         enum brl_type *plock_type,
176                         enum brl_flavour lock_flav)
177 {
178         struct byte_range_lock *br_lck = NULL;
179
180         if (!fsp->can_lock) {
181                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
182         }
183
184         if (!lp_locking(fsp->conn->params)) {
185                 return NT_STATUS_OK;
186         }
187
188         br_lck = brl_get_locks_readonly(fsp);
189         if (!br_lck) {
190                 return NT_STATUS_NO_MEMORY;
191         }
192
193         return brl_lockquery(br_lck,
194                         psmblctx,
195                         messaging_server_id(fsp->conn->sconn->msg_ctx),
196                         poffset,
197                         pcount,
198                         plock_type,
199                         lock_flav);
200 }
201
202 static void increment_current_lock_count(files_struct *fsp,
203     enum brl_flavour lock_flav)
204 {
205         if (lock_flav == WINDOWS_LOCK &&
206             fsp->current_lock_count != NO_LOCKING_COUNT) {
207                 /* blocking ie. pending, locks also count here,
208                  * as this is an efficiency counter to avoid checking
209                  * the lock db. on close. JRA. */
210
211                 fsp->current_lock_count++;
212         } else {
213                 /* Notice that this has had a POSIX lock request.
214                  * We can't count locks after this so forget them.
215                  */
216                 fsp->current_lock_count = NO_LOCKING_COUNT;
217         }
218 }
219
220 static void decrement_current_lock_count(files_struct *fsp,
221     enum brl_flavour lock_flav)
222 {
223         if (lock_flav == WINDOWS_LOCK &&
224             fsp->current_lock_count != NO_LOCKING_COUNT) {
225                 SMB_ASSERT(fsp->current_lock_count > 0);
226                 fsp->current_lock_count--;
227         }
228 }
229
230 /****************************************************************************
231  Utility function called by locking requests.
232 ****************************************************************************/
233
234 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
235                         files_struct *fsp,
236                         uint64_t smblctx,
237                         uint64_t count,
238                         uint64_t offset,
239                         enum brl_type lock_type,
240                         enum brl_flavour lock_flav,
241                         bool blocking_lock,
242                         NTSTATUS *perr,
243                         uint64_t *psmblctx)
244 {
245         struct byte_range_lock *br_lck = NULL;
246
247         /* silently return ok on print files as we don't do locking there */
248         if (fsp->print_file) {
249                 *perr = NT_STATUS_OK;
250                 return NULL;
251         }
252
253         if (!fsp->can_lock) {
254                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
255                 return NULL;
256         }
257
258         if (!lp_locking(fsp->conn->params)) {
259                 *perr = NT_STATUS_OK;
260                 return NULL;
261         }
262
263         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
264
265         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
266                 "blocking_lock=%s requested for %s file %s\n",
267                 lock_flav_name(lock_flav), lock_type_name(lock_type),
268                 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
269                 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
270
271         br_lck = brl_get_locks(talloc_tos(), fsp);
272         if (!br_lck) {
273                 *perr = NT_STATUS_NO_MEMORY;
274                 return NULL;
275         }
276
277         *perr = brl_lock(msg_ctx,
278                         br_lck,
279                         smblctx,
280                         messaging_server_id(fsp->conn->sconn->msg_ctx),
281                         offset,
282                         count,
283                         lock_type,
284                         lock_flav,
285                         blocking_lock,
286                         psmblctx);
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=%ju len=%ju requested for %s file "
317                    "%s\n", (uintmax_t)offset, (uintmax_t)count,
318                    fsp_fnum_dbg(fsp), 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                         messaging_server_id(fsp->conn->sconn->msg_ctx),
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_t smblctx,
350                         uint64_t count,
351                         uint64_t offset,
352                         enum brl_flavour lock_flav)
353 {
354         bool ok = False;
355         struct byte_range_lock *br_lck = NULL;
356
357         if (!fsp->can_lock) {
358                 return fsp->is_directory ?
359                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
360         }
361
362         if (!lp_locking(fsp->conn->params)) {
363                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
364         }
365
366         DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
367                    "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
368                    fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
369
370         br_lck = brl_get_locks(talloc_tos(), fsp);
371         if (!br_lck) {
372                 return NT_STATUS_NO_MEMORY;
373         }
374
375         ok = brl_lock_cancel(br_lck,
376                         smblctx,
377                         messaging_server_id(fsp->conn->sconn->msg_ctx),
378                         offset,
379                         count,
380                         lock_flav);
381
382         TALLOC_FREE(br_lck);
383
384         if (!ok) {
385                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
386                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
387         }
388
389         decrement_current_lock_count(fsp, lock_flav);
390         return NT_STATUS_OK;
391 }
392
393 /****************************************************************************
394  Remove any locks on this fd. Called from file_close().
395 ****************************************************************************/
396
397 void locking_close_file(struct messaging_context *msg_ctx,
398                         files_struct *fsp,
399                         enum file_close_type close_type)
400 {
401         struct byte_range_lock *br_lck;
402
403         if (!lp_locking(fsp->conn->params)) {
404                 return;
405         }
406
407         /* If we have no outstanding locks or pending
408          * locks then we don't need to look in the lock db.
409          */
410
411         if (fsp->current_lock_count == 0) {
412                 return;
413         }
414
415         br_lck = brl_get_locks(talloc_tos(),fsp);
416
417         if (br_lck) {
418                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
419                 brl_close_fnum(msg_ctx, br_lck);
420                 TALLOC_FREE(br_lck);
421         }
422 }
423
424 /*******************************************************************
425  Print out a share mode.
426 ********************************************************************/
427
428 char *share_mode_str(TALLOC_CTX *ctx, int num,
429                      const struct file_id *id,
430                      const struct share_mode_entry *e)
431 {
432         struct server_id_buf tmp;
433
434         return talloc_asprintf(ctx, "share_mode_entry[%d]: "
435                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
436                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
437                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
438                  num,
439                  server_id_str_buf(e->pid, &tmp),
440                  e->share_access, e->private_options,
441                  e->access_mask, (unsigned long long)e->op_mid,
442                  e->op_type, (unsigned long long)e->share_file_id,
443                  (unsigned int)e->uid, (unsigned int)e->flags,
444                  file_id_string_tos(id),
445                  (unsigned int)e->name_hash);
446 }
447
448 /*******************************************************************
449  Fetch a share mode where we know one MUST exist. This call reference
450  counts it internally to allow for nested lock fetches.
451 ********************************************************************/
452
453 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
454                                                      const struct file_id id)
455 {
456         return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
457 }
458
459 /*******************************************************************
460  Sets the service name and filename for rename.
461  At this point we emit "file renamed" messages to all
462  process id's that have this file open.
463  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
464 ********************************************************************/
465
466 bool rename_share_filename(struct messaging_context *msg_ctx,
467                         struct share_mode_lock *lck,
468                         struct file_id id,
469                         const char *servicepath,
470                         uint32_t orig_name_hash,
471                         uint32_t new_name_hash,
472                         const struct smb_filename *smb_fname_dst)
473 {
474         struct share_mode_data *d = lck->data;
475         size_t sp_len;
476         size_t bn_len;
477         size_t sn_len;
478         size_t msg_len;
479         char *frm = NULL;
480         uint32_t i;
481         bool strip_two_chars = false;
482         bool has_stream = smb_fname_dst->stream_name != NULL;
483         struct server_id self_pid = messaging_server_id(msg_ctx);
484
485         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
486                    servicepath, smb_fname_dst->base_name));
487
488         /*
489          * rename_internal_fsp() and rename_internals() add './' to
490          * head of newname if newname does not contain a '/'.
491          */
492         if (smb_fname_dst->base_name[0] &&
493             smb_fname_dst->base_name[1] &&
494             smb_fname_dst->base_name[0] == '.' &&
495             smb_fname_dst->base_name[1] == '/') {
496                 strip_two_chars = true;
497         }
498
499         d->servicepath = talloc_strdup(d, servicepath);
500         d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
501                                        (strip_two_chars ? 2 : 0));
502         d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
503         if (d->base_name == NULL ||
504             (has_stream && d->stream_name == NULL) ||
505             d->servicepath == NULL) {
506                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
507                 return False;
508         }
509         d->modified = True;
510
511         sp_len = strlen(d->servicepath);
512         bn_len = strlen(d->base_name);
513         sn_len = has_stream ? strlen(d->stream_name) : 0;
514
515         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
516             sn_len + 1;
517
518         /* Set up the name changed message. */
519         frm = talloc_array(d, char, msg_len);
520         if (!frm) {
521                 return False;
522         }
523
524         push_file_id_24(frm, &id);
525
526         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
527
528         strlcpy(&frm[24],
529                 d->servicepath ? d->servicepath : "",
530                 sp_len+1);
531         strlcpy(&frm[24 + sp_len + 1],
532                 d->base_name ? d->base_name : "",
533                 bn_len+1);
534         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
535                 d->stream_name ? d->stream_name : "",
536                 sn_len+1);
537
538         /* Send the messages. */
539         for (i=0; i<d->num_share_modes; i++) {
540                 struct share_mode_entry *se = &d->share_modes[i];
541                 struct server_id_buf tmp;
542
543                 if (!is_valid_share_mode_entry(se)) {
544                         continue;
545                 }
546
547                 /* If this is a hardlink to the inode
548                    with a different name, skip this. */
549                 if (se->name_hash != orig_name_hash) {
550                         continue;
551                 }
552
553                 se->name_hash = new_name_hash;
554
555                 /* But not to ourselves... */
556                 if (serverid_equal(&se->pid, &self_pid)) {
557                         continue;
558                 }
559
560                 if (share_mode_stale_pid(d, i)) {
561                         continue;
562                 }
563
564                 DEBUG(10,("rename_share_filename: sending rename message to "
565                           "pid %s file_id %s sharepath %s base_name %s "
566                           "stream_name %s\n",
567                           server_id_str_buf(se->pid, &tmp),
568                           file_id_string_tos(&id),
569                           d->servicepath, d->base_name,
570                         has_stream ? d->stream_name : ""));
571
572                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
573                                    (uint8_t *)frm, msg_len);
574         }
575
576         for (i=0; i<d->num_leases; i++) {
577                 /* Update the filename in leases_db. */
578                 NTSTATUS status;
579                 struct share_mode_lease *l;
580
581                 l = &d->leases[i];
582
583                 status = leases_db_rename(&l->client_guid,
584                                         &l->lease_key,
585                                         &id,
586                                         d->servicepath,
587                                         d->base_name,
588                                         d->stream_name);
589                 if (!NT_STATUS_IS_OK(status)) {
590                         /* Any error recovery possible here ? */
591                         DEBUG(1,("Failed to rename lease key for "
592                                 "renamed file %s:%s. %s\n",
593                                 d->base_name,
594                                 d->stream_name,
595                                 nt_errstr(status)));
596                         continue;
597                 }
598         }
599
600         return True;
601 }
602
603 void get_file_infos(struct file_id id,
604                     uint32_t name_hash,
605                     bool *delete_on_close,
606                     struct timespec *write_time)
607 {
608         struct share_mode_lock *lck;
609
610         if (delete_on_close) {
611                 *delete_on_close = false;
612         }
613
614         if (write_time) {
615                 ZERO_STRUCTP(write_time);
616         }
617
618         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
619                 return;
620         }
621
622         if (delete_on_close) {
623                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
624         }
625
626         if (write_time) {
627                 *write_time = get_share_mode_write_time(lck);
628         }
629
630         TALLOC_FREE(lck);
631 }
632
633 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
634 {
635         int num_props = 0;
636
637         if (e->stale) {
638                 return false;
639         }
640
641         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
642         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
643         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
644         num_props += (e->op_type == LEASE_OPLOCK);
645
646         if ((num_props > 1) && serverid_exists(&e->pid)) {
647                 smb_panic("Invalid share mode entry");
648         }
649         return (num_props != 0);
650 }
651
652 /*
653  * See if we need to remove a lease being referred to by a
654  * share mode that is being marked stale or deleted.
655  */
656
657 static void remove_share_mode_lease(struct share_mode_data *d,
658                                     struct share_mode_entry *e)
659 {
660         struct GUID client_guid;
661         struct smb2_lease_key lease_key;
662         uint16_t op_type;
663         uint32_t lease_idx;
664         uint32_t i;
665
666         op_type = e->op_type;
667         e->op_type = NO_OPLOCK;
668
669         d->modified = true;
670
671         if (op_type != LEASE_OPLOCK) {
672                 return;
673         }
674
675         /*
676          * This used to reference a lease. If there's no other one referencing
677          * it, remove it.
678          */
679
680         lease_idx = e->lease_idx;
681         e->lease_idx = UINT32_MAX;
682
683         for (i=0; i<d->num_share_modes; i++) {
684                 if (d->share_modes[i].stale) {
685                         continue;
686                 }
687                 if (e == &d->share_modes[i]) {
688                         /* Not ourselves. */
689                         continue;
690                 }
691                 if (d->share_modes[i].lease_idx == lease_idx) {
692                         break;
693                 }
694         }
695         if (i < d->num_share_modes) {
696                 /*
697                  * Found another one
698                  */
699                 return;
700         }
701
702         memcpy(&client_guid,
703                 &d->leases[lease_idx].client_guid,
704                 sizeof(client_guid));
705         lease_key = d->leases[lease_idx].lease_key;
706
707         d->num_leases -= 1;
708         d->leases[lease_idx] = d->leases[d->num_leases];
709
710         /*
711          * We changed the lease array. Fix all references to it.
712          */
713         for (i=0; i<d->num_share_modes; i++) {
714                 if (d->share_modes[i].lease_idx == d->num_leases) {
715                         d->share_modes[i].lease_idx = lease_idx;
716                 }
717         }
718
719         {
720                 NTSTATUS status;
721
722                 status = leases_db_del(&client_guid,
723                                         &lease_key,
724                                         &d->id);
725
726                 DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
727                            nt_errstr(status)));
728         }
729 }
730
731 /*
732  * In case d->share_modes[i] conflicts with something or otherwise is
733  * being used, we need to make sure the corresponding process still
734  * exists.
735  */
736 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
737 {
738         struct server_id_buf tmp;
739         struct share_mode_entry *e;
740
741         if (idx > d->num_share_modes) {
742                 DBG_WARNING("Asking for index %"PRIu32", "
743                             "only %"PRIu32" around\n",
744                             idx,
745                             d->num_share_modes);
746                 return false;
747         }
748         e = &d->share_modes[idx];
749         if (e->stale) {
750                 /*
751                  * Checked before
752                  */
753                 return true;
754         }
755         if (serverid_exists(&e->pid)) {
756                 DBG_DEBUG("PID %s (index %"PRIu32" out of %"PRIu32") "
757                           "still exists\n",
758                           server_id_str_buf(e->pid, &tmp),
759                           idx,
760                           d->num_share_modes);
761                 return false;
762         }
763         DBG_DEBUG("PID %s (index %"PRIu32" out of %"PRIu32") "
764                   "does not exist anymore\n",
765                   server_id_str_buf(e->pid, &tmp),
766                   idx,
767                   d->num_share_modes);
768
769         e->stale = true;
770
771         if (d->num_delete_tokens != 0) {
772                 uint32_t i;
773
774                 for (i=0; i<d->num_share_modes; i++) {
775                         bool valid = !d->share_modes[i].stale;
776                         if (valid) {
777                                 break;
778                         }
779                 }
780
781                 if (i == d->num_share_modes) {
782                         /*
783                          * No valid (non-stale) share mode found, all
784                          * who might have set the delete token are
785                          * gone.
786                          */
787                         TALLOC_FREE(d->delete_tokens);
788                         d->num_delete_tokens = 0;
789                 }
790         }
791
792         remove_share_mode_lease(d, e);
793
794         d->modified = true;
795         return true;
796 }
797
798 void remove_stale_share_mode_entries(struct share_mode_data *d)
799 {
800         uint32_t i;
801
802         i = 0;
803         while (i < d->num_share_modes) {
804                 if (d->share_modes[i].stale) {
805                         struct share_mode_entry *m = d->share_modes;
806                         m[i] = m[d->num_share_modes-1];
807                         d->num_share_modes -= 1;
808                         continue;
809                 }
810                 i += 1;
811         }
812 }
813
814 bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
815                     uid_t uid, uint64_t mid, uint16_t op_type,
816                     uint32_t lease_idx)
817 {
818         struct share_mode_data *d = lck->data;
819         struct share_mode_entry *tmp, *e;
820
821         if ((lease_idx != UINT32_MAX) &&
822             (lease_idx >= d->num_leases)) {
823                 return false;
824         }
825
826         tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
827                              d->num_share_modes+1);
828         if (tmp == NULL) {
829                 return false;
830         }
831         d->share_modes = tmp;
832         e = &d->share_modes[d->num_share_modes];
833         d->num_share_modes += 1;
834         d->modified = true;
835
836         ZERO_STRUCTP(e);
837         e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
838         e->share_access = fsp->share_access;
839         e->private_options = fsp->fh->private_options;
840         e->access_mask = fsp->access_mask;
841         e->op_mid = mid;
842         e->op_type = op_type;
843         e->lease_idx = lease_idx;
844         e->time.tv_sec = fsp->open_time.tv_sec;
845         e->time.tv_usec = fsp->open_time.tv_usec;
846         e->share_file_id = fsp->fh->gen_id;
847         e->uid = (uint32_t)uid;
848         e->flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
849                 SHARE_MODE_FLAG_POSIX_OPEN : 0;
850         e->name_hash = fsp->name_hash;
851
852         return true;
853 }
854
855 struct share_mode_entry *find_share_mode_entry(
856         struct share_mode_lock *lck, files_struct *fsp)
857 {
858         struct share_mode_data *d = lck->data;
859         struct server_id pid;
860         uint32_t i;
861
862         pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
863
864         for (i=0; i<d->num_share_modes; i++) {
865                 struct share_mode_entry *e = &d->share_modes[i];
866
867                 if (!is_valid_share_mode_entry(e)) {
868                         continue;
869                 }
870                 if (!serverid_equal(&pid, &e->pid)) {
871                         continue;
872                 }
873                 if (fsp->fh->gen_id != e->share_file_id) {
874                         continue;
875                 }
876                 return e;
877         }
878         return NULL;
879 }
880
881 /*******************************************************************
882  Del the share mode of a file for this process. Return the number of
883  entries left.
884 ********************************************************************/
885
886 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
887 {
888         struct share_mode_entry *e;
889
890         e = find_share_mode_entry(lck, fsp);
891         if (e == NULL) {
892                 return False;
893         }
894         remove_share_mode_lease(lck->data, e);
895         *e = lck->data->share_modes[lck->data->num_share_modes-1];
896         lck->data->num_share_modes -= 1;
897         lck->data->modified = True;
898         return True;
899 }
900
901 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
902                                   struct files_struct *fsp)
903 {
904         struct share_mode_entry *e;
905
906         if (lck->data->num_share_modes != 1) {
907                 return false;
908         }
909
910         if (fsp->op == NULL) {
911                 return false;
912         }
913         if (!fsp->op->global->durable) {
914                 return false;
915         }
916
917         e = find_share_mode_entry(lck, fsp);
918         if (e == NULL) {
919                 return false;
920         }
921
922         DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
923
924         server_id_set_disconnected(&e->pid);
925
926         /*
927          * On reopen the caller needs to check that
928          * the client comes with the correct handle.
929          */
930         e->share_file_id = fsp->op->global->open_persistent_id;
931
932         lck->data->modified = true;
933         return true;
934 }
935
936 /*******************************************************************
937  Remove an oplock mid and mode entry from a share mode.
938 ********************************************************************/
939
940 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
941 {
942         struct share_mode_data *d = lck->data;
943         struct share_mode_entry *e;
944
945         e = find_share_mode_entry(lck, fsp);
946         if (e == NULL) {
947                 return False;
948         }
949
950         remove_share_mode_lease(d, e);
951         d->modified = True;
952         return true;
953 }
954
955 /*******************************************************************
956  Downgrade a oplock type from exclusive to level II.
957 ********************************************************************/
958
959 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
960 {
961         struct share_mode_entry *e;
962
963         e = find_share_mode_entry(lck, fsp);
964         if (e == NULL) {
965                 return False;
966         }
967
968         e->op_type = LEVEL_II_OPLOCK;
969         lck->data->modified = True;
970         return True;
971 }
972
973 NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
974                                struct share_mode_lock *lck,
975                                const struct smb2_lease_key *key,
976                                uint32_t new_lease_state,
977                                struct share_mode_lease **_l)
978 {
979         struct share_mode_data *d = lck->data;
980         struct share_mode_lease *l;
981         uint32_t i;
982
983         *_l = NULL;
984
985         for (i=0; i<d->num_leases; i++) {
986                 if (smb2_lease_equal(&sconn->client->connections->smb2.client.guid,
987                                      key,
988                                      &d->leases[i].client_guid,
989                                      &d->leases[i].lease_key)) {
990                         break;
991                 }
992         }
993         if (i == d->num_leases) {
994                 DEBUG(10, ("lease not found\n"));
995                 return NT_STATUS_INVALID_PARAMETER;
996         }
997
998         l = &d->leases[i];
999
1000         if (!l->breaking) {
1001                 DEBUG(1, ("Attempt to break from %d to %d - but we're not in breaking state\n",
1002                            (int)l->current_state, (int)new_lease_state));
1003                 return NT_STATUS_UNSUCCESSFUL;
1004         }
1005
1006         /*
1007          * Can't upgrade anything: l->breaking_to_requested (and l->current_state)
1008          * must be a strict bitwise superset of new_lease_state
1009          */
1010         if ((new_lease_state & l->breaking_to_requested) != new_lease_state) {
1011                 DEBUG(1, ("Attempt to upgrade from %d to %d - expected %d\n",
1012                            (int)l->current_state, (int)new_lease_state,
1013                            (int)l->breaking_to_requested));
1014                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
1015         }
1016
1017         if (l->current_state != new_lease_state) {
1018                 l->current_state = new_lease_state;
1019                 d->modified = true;
1020         }
1021
1022         if ((new_lease_state & ~l->breaking_to_required) != 0) {
1023                 DEBUG(5, ("lease state %d not fully broken from %d to %d\n",
1024                            (int)new_lease_state,
1025                            (int)l->current_state,
1026                            (int)l->breaking_to_required));
1027                 l->breaking_to_requested = l->breaking_to_required;
1028                 if (l->current_state & (~SMB2_LEASE_READ)) {
1029                         /*
1030                          * Here we break in steps, as windows does
1031                          * see the breaking3 and v2_breaking3 tests.
1032                          */
1033                         l->breaking_to_requested |= SMB2_LEASE_READ;
1034                 }
1035                 d->modified = true;
1036                 *_l = l;
1037                 return NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
1038         }
1039
1040         DEBUG(10, ("breaking from %d to %d - expected %d\n",
1041                    (int)l->current_state, (int)new_lease_state,
1042                    (int)l->breaking_to_requested));
1043
1044         l->breaking_to_requested = 0;
1045         l->breaking_to_required = 0;
1046         l->breaking = false;
1047
1048         d->modified = true;
1049
1050         return NT_STATUS_OK;
1051 }
1052
1053 /****************************************************************************
1054  Adds a delete on close token.
1055 ****************************************************************************/
1056
1057 static bool add_delete_on_close_token(struct share_mode_data *d,
1058                         uint32_t name_hash,
1059                         const struct security_token *nt_tok,
1060                         const struct security_unix_token *tok)
1061 {
1062         struct delete_token *tmp, *dtl;
1063
1064         tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
1065                              d->num_delete_tokens+1);
1066         if (tmp == NULL) {
1067                 return false;
1068         }
1069         d->delete_tokens = tmp;
1070         dtl = &d->delete_tokens[d->num_delete_tokens];
1071
1072         dtl->name_hash = name_hash;
1073         dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
1074         if (dtl->delete_nt_token == NULL) {
1075                 return false;
1076         }
1077         dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
1078         if (dtl->delete_token == NULL) {
1079                 return false;
1080         }
1081         d->num_delete_tokens += 1;
1082         d->modified = true;
1083         return true;
1084 }
1085
1086 void reset_delete_on_close_lck(files_struct *fsp,
1087                                struct share_mode_lock *lck)
1088 {
1089         struct share_mode_data *d = lck->data;
1090         uint32_t i;
1091
1092         for (i=0; i<d->num_delete_tokens; i++) {
1093                 struct delete_token *dt = &d->delete_tokens[i];
1094
1095                 if (dt->name_hash == fsp->name_hash) {
1096                         d->modified = true;
1097
1098                         /* Delete this entry. */
1099                         TALLOC_FREE(dt->delete_nt_token);
1100                         TALLOC_FREE(dt->delete_token);
1101                         *dt = d->delete_tokens[d->num_delete_tokens-1];
1102                         d->num_delete_tokens -= 1;
1103                 }
1104         }
1105 }
1106
1107 /****************************************************************************
1108  Sets the delete on close flag over all share modes on this file.
1109  Modify the share mode entry for all files open
1110  on this device and inode to tell other smbds we have
1111  changed the delete on close flag. This will be noticed
1112  in the close code, the last closer will delete the file
1113  if flag is set.
1114  This makes a copy of any struct security_unix_token into the
1115  lck entry. This function is used when the lock is already granted.
1116 ****************************************************************************/
1117
1118 void set_delete_on_close_lck(files_struct *fsp,
1119                         struct share_mode_lock *lck,
1120                         const struct security_token *nt_tok,
1121                         const struct security_unix_token *tok)
1122 {
1123         struct messaging_context *msg_ctx = fsp->conn->sconn->msg_ctx;
1124         struct share_mode_data *d = lck->data;
1125         uint32_t i;
1126         bool ret;
1127         DATA_BLOB fid_blob = {};
1128         enum ndr_err_code ndr_err;
1129
1130         SMB_ASSERT(nt_tok != NULL);
1131         SMB_ASSERT(tok != NULL);
1132
1133         for (i=0; i<d->num_delete_tokens; i++) {
1134                 struct delete_token *dt = &d->delete_tokens[i];
1135                 if (dt->name_hash == fsp->name_hash) {
1136                         d->modified = true;
1137
1138                         /* Replace this token with the given tok. */
1139                         TALLOC_FREE(dt->delete_nt_token);
1140                         dt->delete_nt_token = dup_nt_token(dt, nt_tok);
1141                         SMB_ASSERT(dt->delete_nt_token != NULL);
1142                         TALLOC_FREE(dt->delete_token);
1143                         dt->delete_token = copy_unix_token(dt, tok);
1144                         SMB_ASSERT(dt->delete_token != NULL);
1145
1146                         return;
1147                 }
1148         }
1149
1150         ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
1151         SMB_ASSERT(ret);
1152
1153         ndr_err = ndr_push_struct_blob(&fid_blob, talloc_tos(), &fsp->file_id,
1154                                        (ndr_push_flags_fn_t)ndr_push_file_id);
1155         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1156                 DEBUG(10, ("ndr_push_file_id failed: %s\n",
1157                            ndr_errstr(ndr_err)));
1158         }
1159
1160         for (i=0; i<d->num_share_modes; i++) {
1161                 struct share_mode_entry *e = &d->share_modes[i];
1162                 NTSTATUS status;
1163
1164                 status = messaging_send(
1165                         msg_ctx, e->pid, MSG_SMB_NOTIFY_CANCEL_DELETED,
1166                         &fid_blob);
1167
1168                 if (!NT_STATUS_IS_OK(status)) {
1169                         struct server_id_buf tmp;
1170                         DEBUG(10, ("%s: messaging_send to %s returned %s\n",
1171                                    __func__, server_id_str_buf(e->pid, &tmp),
1172                                    nt_errstr(status)));
1173                 }
1174         }
1175
1176         TALLOC_FREE(fid_blob.data);
1177 }
1178
1179 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
1180                         const struct security_token *nt_tok,
1181                         const struct security_unix_token *tok)
1182 {
1183         struct share_mode_lock *lck;
1184
1185         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1186                   "%s, file %s\n",
1187                   delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
1188                   fsp_str_dbg(fsp)));
1189
1190         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1191         if (lck == NULL) {
1192                 return False;
1193         }
1194
1195         if (delete_on_close) {
1196                 set_delete_on_close_lck(fsp, lck, nt_tok, tok);
1197         } else {
1198                 reset_delete_on_close_lck(fsp, lck);
1199         }
1200
1201         if (fsp->is_directory) {
1202                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1203                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1204                                                fsp->fsp_name->base_name);
1205         }
1206
1207         TALLOC_FREE(lck);
1208
1209         fsp->delete_on_close = delete_on_close;
1210
1211         return True;
1212 }
1213
1214 static struct delete_token *find_delete_on_close_token(
1215         struct share_mode_data *d, uint32_t name_hash)
1216 {
1217         uint32_t i;
1218
1219         DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
1220                    (unsigned int)name_hash));
1221
1222         for (i=0; i<d->num_delete_tokens; i++) {
1223                 struct delete_token *dt = &d->delete_tokens[i];
1224
1225                 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1226                            (unsigned int)dt->name_hash ));
1227                 if (dt->name_hash == name_hash) {
1228                         return dt;
1229                 }
1230         }
1231         return NULL;
1232 }
1233
1234 /****************************************************************************
1235  Return the NT token and UNIX token if there's a match. Return true if
1236  found, false if not.
1237 ****************************************************************************/
1238
1239 bool get_delete_on_close_token(struct share_mode_lock *lck,
1240                                         uint32_t name_hash,
1241                                         const struct security_token **pp_nt_tok,
1242                                         const struct security_unix_token **pp_tok)
1243 {
1244         struct delete_token *dt;
1245
1246         dt = find_delete_on_close_token(lck->data, name_hash);
1247         if (dt == NULL) {
1248                 return false;
1249         }
1250         *pp_nt_tok = dt->delete_nt_token;
1251         *pp_tok =  dt->delete_token;
1252         return true;
1253 }
1254
1255 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1256 {
1257         return find_delete_on_close_token(lck->data, name_hash) != NULL;
1258 }
1259
1260 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1261 {
1262         struct share_mode_lock *lck;
1263
1264         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1265                  timestring(talloc_tos(),
1266                             convert_timespec_to_time_t(write_time)),
1267                  file_id_string_tos(&fileid)));
1268
1269         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1270         if (lck == NULL) {
1271                 return False;
1272         }
1273
1274         if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1275                 lck->data->modified = True;
1276                 lck->data->changed_write_time = write_time;
1277         }
1278
1279         TALLOC_FREE(lck);
1280         return True;
1281 }
1282
1283 bool set_write_time(struct file_id fileid, struct timespec write_time)
1284 {
1285         struct share_mode_lock *lck;
1286
1287         DEBUG(5,("set_write_time: %s id=%s\n",
1288                  timestring(talloc_tos(),
1289                             convert_timespec_to_time_t(write_time)),
1290                  file_id_string_tos(&fileid)));
1291
1292         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1293         if (lck == NULL) {
1294                 return False;
1295         }
1296
1297         if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1298                 lck->data->modified = True;
1299                 lck->data->old_write_time = write_time;
1300         }
1301
1302         TALLOC_FREE(lck);
1303         return True;
1304 }
1305
1306 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1307 {
1308         struct share_mode_data *d = lck->data;
1309
1310         if (!null_timespec(d->changed_write_time)) {
1311                 return d->changed_write_time;
1312         }
1313         return d->old_write_time;
1314 }
1315
1316 bool file_has_open_streams(files_struct *fsp)
1317 {
1318         struct share_mode_lock *lock = NULL;
1319         struct share_mode_data *d = NULL;
1320         uint32_t i;
1321
1322         lock = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1323         if (lock == NULL) {
1324                 return false;
1325         }
1326         d = lock->data;
1327
1328         for (i = 0; i < d->num_share_modes; i++) {
1329                 struct share_mode_entry *e = &d->share_modes[i];
1330
1331                 if (share_mode_stale_pid(d, i)) {
1332                         continue;
1333                 }
1334
1335                 if (e->private_options &
1336                     NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN)
1337                 {
1338                         TALLOC_FREE(lock);
1339                         return true;
1340                 }
1341         }
1342
1343         TALLOC_FREE(lock);
1344         return false;
1345 }