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