Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/locking/locking.c

    r860 r988  
    55   Copyright (C) Jeremy Allison 1992-2006
    66   Copyright (C) Volker Lendecke 2005
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    3030   support.
    3131
    32    rewrtten completely to use new tdb code. Tridge, Dec '99
     32   rewritten completely to use new tdb code. Tridge, Dec '99
    3333
    3434   Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
     
    4040#include "locking/proto.h"
    4141#include "smbd/globals.h"
    42 #include "dbwrap.h"
     42#include "dbwrap/dbwrap.h"
     43#include "dbwrap/dbwrap_open.h"
    4344#include "../libcli/security/security.h"
    4445#include "serverid.h"
    4546#include "messages.h"
    4647#include "util_tdb.h"
    47 #include "../librpc/gen_ndr/ndr_security.h"
     48#include "../librpc/gen_ndr/ndr_open_files.h"
     49#include "librpc/gen_ndr/ndr_file_id.h"
     50#include "locking/leases_db.h"
    4851
    4952#undef DBGC_CLASS
     
    5154
    5255#define NO_LOCKING_COUNT (-1)
    53 
    54 /* the locking database handle */
    55 static struct db_context *lock_db;
    5656
    5757/****************************************************************************
     
    9696        plock->context.smblctx = smblctx;
    9797        plock->context.tid = fsp->conn->cnum;
    98         plock->context.pid = sconn_server_id(fsp->conn->sconn);
     98        plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
    9999        plock->start = start;
    100100        plock->size = size;
     
    106106bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
    107107{
     108        struct byte_range_lock *br_lck;
    108109        int strict_locking = lp_strict_locking(fsp->conn->params);
    109110        bool ret = False;
     
    118119
    119120        if (strict_locking == Auto) {
    120                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
    121                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
    122                         ret = True;
    123                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
    124                            (plock->lock_type == READ_LOCK)) {
    125                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
    126                         ret = True;
    127                 } else {
    128                         struct byte_range_lock *br_lck;
    129 
    130                         br_lck = brl_get_locks_readonly(fsp);
    131                         if (!br_lck) {
    132                                 return True;
    133                         }
    134                         ret = brl_locktest(br_lck,
    135                                         plock->context.smblctx,
    136                                         plock->context.pid,
    137                                         plock->start,
    138                                         plock->size,
    139                                         plock->lock_type,
    140                                         plock->lock_flav);
    141                 }
    142         } else {
    143                 struct byte_range_lock *br_lck;
    144 
    145                 br_lck = brl_get_locks_readonly(fsp);
    146                 if (!br_lck) {
    147                         return True;
    148                 }
    149                 ret = brl_locktest(br_lck,
    150                                 plock->context.smblctx,
    151                                 plock->context.pid,
    152                                 plock->start,
    153                                 plock->size,
    154                                 plock->lock_type,
    155                                 plock->lock_flav);
    156         }
    157 
    158         DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
    159                         "len=%.0f %s for fnum %d file %s\n",
    160                         lock_flav_name(plock->lock_flav),
    161                         (double)plock->start, (double)plock->size,
    162                         ret ? "unlocked" : "locked",
    163                         plock->fnum, fsp_str_dbg(fsp)));
     121                if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
     122                     (plock->lock_type == READ_LOCK ||
     123                      plock->lock_type == WRITE_LOCK)) {
     124                        DEBUG(10, ("is_locked: optimisation - exclusive oplock "
     125                                   "on file %s\n", fsp_str_dbg(fsp)));
     126                        return true;
     127                }
     128                if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
     129                    (plock->lock_type == READ_LOCK)) {
     130                        DEBUG(10, ("is_locked: optimisation - level II oplock "
     131                                   "on file %s\n", fsp_str_dbg(fsp)));
     132                        return true;
     133                }
     134        }
     135
     136        br_lck = brl_get_locks_readonly(fsp);
     137        if (!br_lck) {
     138                return true;
     139        }
     140        ret = brl_locktest(br_lck, plock);
     141
     142        if (!ret) {
     143                /*
     144                 * We got a lock conflict. Retry with rw locks to enable
     145                 * autocleanup. This is the slow path anyway.
     146                 */
     147                br_lck = brl_get_locks(talloc_tos(), fsp);
     148                ret = brl_locktest(br_lck, plock);
     149                TALLOC_FREE(br_lck);
     150        }
     151
     152        DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
     153                   "len=%ju %s for fnum %ju file %s\n",
     154                   lock_flav_name(plock->lock_flav),
     155                   (uintmax_t)plock->start, (uintmax_t)plock->size,
     156                   ret ? "unlocked" : "locked",
     157                   (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
    164158
    165159        return ret;
     
    198192        return brl_lockquery(br_lck,
    199193                        psmblctx,
    200                         sconn_server_id(fsp->conn->sconn),
     194                        messaging_server_id(fsp->conn->sconn->msg_ctx),
    201195                        poffset,
    202196                        pcount,
     
    246240                        bool blocking_lock,
    247241                        NTSTATUS *perr,
    248                         uint64_t *psmblctx,
    249                         struct blocking_lock_record *blr)
     242                        uint64_t *psmblctx)
    250243{
    251244        struct byte_range_lock *br_lck = NULL;
     
    269262        /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
    270263
    271         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
    272                 "blocking_lock=%s requested for fnum %d file %s\n",
     264        DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
     265                "blocking_lock=%s requested for %s file %s\n",
    273266                lock_flav_name(lock_flav), lock_type_name(lock_type),
    274                 (double)offset, (double)count, blocking_lock ? "true" :
    275                 "false", fsp->fnum, fsp_str_dbg(fsp)));
     267                (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
     268                "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
    276269
    277270        br_lck = brl_get_locks(talloc_tos(), fsp);
     
    284277                        br_lck,
    285278                        smblctx,
    286                         sconn_server_id(fsp->conn->sconn),
     279                        messaging_server_id(fsp->conn->sconn->msg_ctx),
    287280                        offset,
    288281                        count,
     
    290283                        lock_flav,
    291284                        blocking_lock,
    292                         psmblctx,
    293                         blr);
     285                        psmblctx);
    294286
    295287        DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
     
    312304        bool ok = False;
    313305        struct byte_range_lock *br_lck = NULL;
    314        
     306
    315307        if (!fsp->can_lock) {
    316308                return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
    317309        }
    318        
     310
    319311        if (!lp_locking(fsp->conn->params)) {
    320312                return NT_STATUS_OK;
    321313        }
    322        
    323         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
    324                   (double)offset, (double)count, fsp->fnum,
    325                   fsp_str_dbg(fsp)));
     314
     315        DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
     316                   "%s\n", (uintmax_t)offset, (uintmax_t)count,
     317                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
    326318
    327319        br_lck = brl_get_locks(talloc_tos(), fsp);
     
    333325                        br_lck,
    334326                        smblctx,
    335                         sconn_server_id(fsp->conn->sconn),
     327                        messaging_server_id(fsp->conn->sconn->msg_ctx),
    336328                        offset,
    337329                        count,
    338330                        lock_flav);
    339    
     331
    340332        TALLOC_FREE(br_lck);
    341333
     
    354346
    355347NTSTATUS do_lock_cancel(files_struct *fsp,
    356                         uint64 smblctx,
     348                        uint64_t smblctx,
    357349                        uint64_t count,
    358350                        uint64_t offset,
    359                         enum brl_flavour lock_flav,
    360                         struct blocking_lock_record *blr)
     351                        enum brl_flavour lock_flav)
    361352{
    362353        bool ok = False;
     
    367358                        NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
    368359        }
    369        
     360
    370361        if (!lp_locking(fsp->conn->params)) {
    371362                return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
    372363        }
    373364
    374         DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
    375                   (double)offset, (double)count, fsp->fnum,
    376                   fsp_str_dbg(fsp)));
     365        DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
     366                   "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
     367                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
    377368
    378369        br_lck = brl_get_locks(talloc_tos(), fsp);
     
    383374        ok = brl_lock_cancel(br_lck,
    384375                        smblctx,
    385                         sconn_server_id(fsp->conn->sconn),
     376                        messaging_server_id(fsp->conn->sconn->msg_ctx),
    386377                        offset,
    387378                        count,
    388                         lock_flav,
    389                         blr);
     379                        lock_flav);
    390380
    391381        TALLOC_FREE(br_lck);
     
    414404        }
    415405
    416         /* If we have not outstanding locks or pending
     406        /* If we have no outstanding locks or pending
    417407         * locks then we don't need to look in the lock db.
    418408         */
     
    431421}
    432422
    433 /****************************************************************************
    434  Initialise the locking functions.
    435 ****************************************************************************/
    436 
    437 static bool locking_init_internal(bool read_only)
    438 {
    439         brl_init(read_only);
    440 
    441         if (lock_db)
    442                 return True;
    443 
    444         lock_db = db_open(NULL, lock_path("locking.tdb"),
    445                           lp_open_files_db_hash_size(),
    446                           TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
    447                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
    448 
    449         if (!lock_db) {
    450                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
    451                 return False;
    452         }
    453 
    454         if (!posix_locking_init(read_only))
    455                 return False;
    456 
    457         return True;
    458 }
    459 
    460 bool locking_init(void)
    461 {
    462         return locking_init_internal(false);
    463 }
    464 
    465 bool locking_init_readonly(void)
    466 {
    467         return locking_init_internal(true);
    468 }
    469 
    470 /*******************************************************************
    471  Deinitialize the share_mode management.
    472 ******************************************************************/
    473 
    474 bool locking_end(void)
    475 {
    476         brl_shutdown();
    477         TALLOC_FREE(lock_db);
    478         return true;
    479 }
    480 
    481 /*******************************************************************
    482  Form a static locking key for a dev/inode pair.
    483 ******************************************************************/
    484 
    485 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
    486 {
    487         *tmp = *id;
    488         return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
    489 }
    490 
    491423/*******************************************************************
    492424 Print out a share mode.
     
    495427char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
    496428{
    497         return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
     429        struct server_id_buf tmp;
     430
     431        return talloc_asprintf(ctx, "share_mode_entry[%d]: "
    498432                 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
    499                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
     433                 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
    500434                 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
    501435                 num,
    502                  e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
    503                  procid_str_static(&e->pid),
     436                 server_id_str_buf(e->pid, &tmp),
    504437                 e->share_access, e->private_options,
    505438                 e->access_mask, (unsigned long long)e->op_mid,
    506                  e->op_type, e->share_file_id,
     439                 e->op_type, (unsigned long long)e->share_file_id,
    507440                 (unsigned int)e->uid, (unsigned int)e->flags,
    508441                 file_id_string_tos(&e->id),
     
    511444
    512445/*******************************************************************
    513  Print out a share mode table.
     446 Fetch a share mode where we know one MUST exist. This call reference
     447 counts it internally to allow for nested lock fetches.
    514448********************************************************************/
    515449
    516 static void print_share_mode_table(struct locking_data *data)
    517 {
    518         int num_share_modes = data->u.s.num_share_mode_entries;
    519         struct share_mode_entry *shares =
    520                 (struct share_mode_entry *)(data + 1);
    521         int i;
    522 
    523         for (i = 0; i < num_share_modes; i++) {
    524                 struct share_mode_entry entry;
    525                 char *str;
    526 
    527                 /*
    528                  * We need to memcpy the entry here due to alignment
    529                  * restrictions that are not met when directly accessing
    530                  * shares[i]
    531                  */
    532 
    533                 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
    534                 str = share_mode_str(talloc_tos(), i, &entry);
    535 
    536                 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
    537                 TALLOC_FREE(str);
    538         }
    539 }
    540 
    541 static int parse_delete_tokens_list(struct share_mode_lock *lck,
    542                 struct locking_data *pdata,
    543                 const TDB_DATA dbuf)
    544 {
    545         uint8_t *p = dbuf.dptr + sizeof(struct locking_data) +
    546                         (lck->num_share_modes *
    547                         sizeof(struct share_mode_entry));
    548         uint8_t *end_ptr = dbuf.dptr + (dbuf.dsize - 2);
    549         int delete_tokens_size = 0;
    550         int i;
    551 
    552         lck->delete_tokens = NULL;
    553 
    554         for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) {
    555                 DATA_BLOB blob;
    556                 enum ndr_err_code ndr_err;
    557                 struct delete_token_list *pdtl;
    558                 size_t token_len = 0;
    559 
    560                 pdtl = TALLOC_ZERO_P(lck, struct delete_token_list);
    561                 if (pdtl == NULL) {
    562                         DEBUG(0,("parse_delete_tokens_list: talloc failed"));
    563                         return -1;
    564                 }
    565                 /* Copy out the name_hash. */
    566                 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash));
    567                 p += sizeof(pdtl->name_hash);
    568                 delete_tokens_size += sizeof(pdtl->name_hash);
    569 
    570                 pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token);
    571                 if (pdtl->delete_token == NULL) {
    572                         DEBUG(0,("parse_delete_tokens_list: talloc failed"));
    573                         return -1;
    574                 }
    575 
    576                 if (p >= end_ptr) {
    577                         DEBUG(0,("parse_delete_tokens_list: corrupt data"));
    578                         return -1;
    579                 }
    580 
    581                 blob.data = p;
    582                 blob.length = end_ptr - p;
    583 
    584                 ndr_err = ndr_pull_struct_blob(&blob,
    585                                 pdtl,
    586                                 pdtl->delete_token,
    587                                 (ndr_pull_flags_fn_t)ndr_pull_security_unix_token);
    588                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    589                         DEBUG(1, ("parse_delete_tokens_list: "
    590                                 "ndr_pull_security_unix_token failed\n"));
    591                         return -1;
    592                 }
    593 
    594                 token_len = ndr_size_security_unix_token(pdtl->delete_token, 0);
    595 
    596                 p += token_len;
    597                 delete_tokens_size += token_len;
    598 
    599                 if (p >= end_ptr) {
    600                         DEBUG(0,("parse_delete_tokens_list: corrupt data"));
    601                         return -1;
    602                 }
    603 
    604                 pdtl->delete_nt_token = TALLOC_ZERO_P(pdtl, struct security_token);
    605                 if (pdtl->delete_nt_token == NULL) {
    606                         DEBUG(0,("parse_delete_tokens_list: talloc failed"));
    607                         return -1;
    608                 }
    609 
    610                 blob.data = p;
    611                 blob.length = end_ptr - p;
    612 
    613                 ndr_err = ndr_pull_struct_blob(&blob,
    614                                 pdtl,
    615                                 pdtl->delete_nt_token,
    616                                 (ndr_pull_flags_fn_t)ndr_pull_security_token);
    617                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    618                         DEBUG(1, ("parse_delete_tokens_list: "
    619                                 "ndr_pull_security_token failed\n"));
    620                         return -1;
    621                 }
    622 
    623                 token_len = ndr_size_security_token(pdtl->delete_nt_token, 0);
    624 
    625                 p += token_len;
    626                 delete_tokens_size += token_len;
    627 
    628                 /* Add to the list. */
    629                 DLIST_ADD(lck->delete_tokens, pdtl);
    630         }
    631 
    632         return delete_tokens_size;
    633 }
    634 
    635 /*******************************************************************
    636  Get all share mode entries for a dev/inode pair.
    637 ********************************************************************/
    638 
    639 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
    640 {
    641         struct locking_data data;
    642         int delete_tokens_size;
    643         int i;
    644 
    645         if (dbuf.dsize < sizeof(struct locking_data)) {
    646                 smb_panic("parse_share_modes: buffer too short");
    647         }
    648 
    649         memcpy(&data, dbuf.dptr, sizeof(data));
    650 
    651         lck->old_write_time = data.u.s.old_write_time;
    652         lck->changed_write_time = data.u.s.changed_write_time;
    653         lck->num_share_modes = data.u.s.num_share_mode_entries;
    654 
    655         DEBUG(10, ("parse_share_modes: owrt: %s, "
    656                    "cwrt: %s, ntok: %u, num_share_modes: %d\n",
    657                    timestring(talloc_tos(),
    658                               convert_timespec_to_time_t(lck->old_write_time)),
    659                    timestring(talloc_tos(),
    660                               convert_timespec_to_time_t(
    661                                       lck->changed_write_time)),
    662                    (unsigned int)data.u.s.num_delete_token_entries,
    663                    lck->num_share_modes));
    664 
    665         if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
    666                 DEBUG(0, ("invalid number of share modes: %d\n",
    667                           lck->num_share_modes));
    668                 smb_panic("parse_share_modes: invalid number of share modes");
    669         }
    670 
    671         lck->share_modes = NULL;
    672        
    673         if (lck->num_share_modes != 0) {
    674 
    675                 if (dbuf.dsize < (sizeof(struct locking_data) +
    676                                   (lck->num_share_modes *
    677                                    sizeof(struct share_mode_entry)))) {
    678                         smb_panic("parse_share_modes: buffer too short");
    679                 }
    680                                  
    681                 lck->share_modes = (struct share_mode_entry *)
    682                         TALLOC_MEMDUP(lck,
    683                                       dbuf.dptr+sizeof(struct locking_data),
    684                                       lck->num_share_modes *
    685                                       sizeof(struct share_mode_entry));
    686 
    687                 if (lck->share_modes == NULL) {
    688                         smb_panic("parse_share_modes: talloc failed");
    689                 }
    690         }
    691 
    692         /* Get any delete tokens. */
    693         delete_tokens_size = parse_delete_tokens_list(lck, &data, dbuf);
    694         if (delete_tokens_size < 0) {
    695                 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
    696         }
    697 
    698         /* Save off the associated service path and filename. */
    699         lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
    700                 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
    701                 delete_tokens_size;
    702 
    703         lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
    704                 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
    705                 delete_tokens_size +
    706                 strlen(lck->servicepath) + 1;
    707 
    708         lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
    709                 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
    710                 delete_tokens_size +
    711                 strlen(lck->servicepath) + 1 +
    712                 strlen(lck->base_name) + 1;
    713 
    714         /*
    715          * Ensure that each entry has a real process attached.
    716          */
    717 
    718         for (i = 0; i < lck->num_share_modes; i++) {
    719                 struct share_mode_entry *entry_p = &lck->share_modes[i];
    720                 char *str = NULL;
    721                 if (DEBUGLEVEL >= 10) {
    722                         str = share_mode_str(NULL, i, entry_p);
    723                 }
    724                 DEBUG(10,("parse_share_modes: %s\n",
    725                         str ? str : ""));
    726                 if (!serverid_exists(&entry_p->pid)) {
    727                         DEBUG(10,("parse_share_modes: deleted %s\n",
    728                                 str ? str : ""));
    729                         entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
    730                         lck->modified = True;
    731                 }
    732                 TALLOC_FREE(str);
    733         }
    734 
    735         return True;
    736 }
    737 
    738 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
    739 {
    740         TDB_DATA result;
    741         int num_valid = 0;
    742         int i;
    743         struct locking_data *data;
    744         ssize_t offset;
    745         ssize_t sp_len, bn_len, sn_len;
    746         uint32_t delete_tokens_size = 0;
    747         struct delete_token_list *pdtl = NULL;
    748         uint32_t num_delete_token_entries = 0;
    749 
    750         result.dptr = NULL;
    751         result.dsize = 0;
    752 
    753         for (i=0; i<lck->num_share_modes; i++) {
    754                 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
    755                         num_valid += 1;
    756                 }
    757         }
    758 
    759         if (num_valid == 0) {
    760                 return result;
    761         }
    762 
    763         sp_len = strlen(lck->servicepath);
    764         bn_len = strlen(lck->base_name);
    765         sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
    766 
    767         for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
    768                 num_delete_token_entries++;
    769                 delete_tokens_size += sizeof(uint32_t) +
    770                                 ndr_size_security_unix_token(pdtl->delete_token, 0) +
    771                                 ndr_size_security_token(pdtl->delete_nt_token, 0);
    772         }
    773 
    774         result.dsize = sizeof(*data) +
    775                 lck->num_share_modes * sizeof(struct share_mode_entry) +
    776                 delete_tokens_size +
    777                 sp_len + 1 +
    778                 bn_len + 1 +
    779                 sn_len + 1;
    780         result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
    781 
    782         if (result.dptr == NULL) {
    783                 smb_panic("talloc failed");
    784         }
    785 
    786         data = (struct locking_data *)result.dptr;
    787         ZERO_STRUCTP(data);
    788         data->u.s.num_share_mode_entries = lck->num_share_modes;
    789         data->u.s.old_write_time = lck->old_write_time;
    790         data->u.s.changed_write_time = lck->changed_write_time;
    791         data->u.s.num_delete_token_entries = num_delete_token_entries;
    792 
    793         DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
    794                   "num: %d\n",
    795                   timestring(talloc_tos(),
    796                              convert_timespec_to_time_t(lck->old_write_time)),
    797                   timestring(talloc_tos(),
    798                              convert_timespec_to_time_t(
    799                                      lck->changed_write_time)),
    800                   (unsigned int)data->u.s.num_delete_token_entries,
    801                   data->u.s.num_share_mode_entries));
    802 
    803         memcpy(result.dptr + sizeof(*data), lck->share_modes,
    804                sizeof(struct share_mode_entry)*lck->num_share_modes);
    805         offset = sizeof(*data) +
    806                 sizeof(struct share_mode_entry)*lck->num_share_modes;
    807 
    808         /* Store any delete on close tokens. */
    809         for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
    810                 struct security_unix_token *pdt = pdtl->delete_token;
    811                 struct security_token *pdt_nt = pdtl->delete_nt_token;
    812                 uint8_t *p = result.dptr + offset;
    813                 DATA_BLOB blob;
    814                 enum ndr_err_code ndr_err;
    815 
    816                 memcpy(p, &pdtl->name_hash, sizeof(uint32_t));
    817                 p += sizeof(uint32_t);
    818                 offset += sizeof(uint32_t);
    819 
    820                 ndr_err = ndr_push_struct_blob(&blob,
    821                                 talloc_tos(),
    822                                 pdt,
    823                                 (ndr_push_flags_fn_t)ndr_push_security_unix_token);
    824 
    825                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    826                         smb_panic("ndr_push_security_unix_token failed");
    827                 }
    828 
    829                 /* We know we have space here as we counted above. */
    830                 memcpy(p, blob.data, blob.length);
    831                 p += blob.length;
    832                 offset += blob.length;
    833                 TALLOC_FREE(blob.data);
    834 
    835                 ndr_err = ndr_push_struct_blob(&blob,
    836                                 talloc_tos(),
    837                                 pdt_nt,
    838                                 (ndr_push_flags_fn_t)ndr_push_security_token);
    839 
    840                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    841                         smb_panic("ndr_push_security_token failed");
    842                 }
    843 
    844                 /* We know we have space here as we counted above. */
    845                 memcpy(p, blob.data, blob.length);
    846                 p += blob.length;
    847                 offset += blob.length;
    848                 TALLOC_FREE(blob.data);
    849         }
    850 
    851         safe_strcpy((char *)result.dptr + offset, lck->servicepath,
    852                     result.dsize - offset - 1);
    853         offset += sp_len + 1;
    854         safe_strcpy((char *)result.dptr + offset, lck->base_name,
    855                     result.dsize - offset - 1);
    856         offset += bn_len + 1;
    857         safe_strcpy((char *)result.dptr + offset, lck->stream_name,
    858                     result.dsize - offset - 1);
    859 
    860         if (DEBUGLEVEL >= 10) {
    861                 print_share_mode_table(data);
    862         }
    863 
    864         return result;
    865 }
    866 
    867 static int share_mode_lock_destructor(struct share_mode_lock *lck)
    868 {
    869         NTSTATUS status;
    870         TDB_DATA data;
    871 
    872         if (!lck->modified) {
    873                 return 0;
    874         }
    875 
    876         data = unparse_share_modes(lck);
    877 
    878         if (data.dptr == NULL) {
    879                 if (!lck->fresh) {
    880                         /* There has been an entry before, delete it */
    881 
    882                         status = lck->record->delete_rec(lck->record);
    883                         if (!NT_STATUS_IS_OK(status)) {
    884                                 char *errmsg;
    885 
    886                                 DEBUG(0, ("delete_rec returned %s\n",
    887                                           nt_errstr(status)));
    888 
    889                                 if (asprintf(&errmsg, "could not delete share "
    890                                              "entry: %s\n",
    891                                              nt_errstr(status)) == -1) {
    892                                         smb_panic("could not delete share"
    893                                                   "entry");
    894                                 }
    895                                 smb_panic(errmsg);
    896                         }
    897                 }
    898                 goto done;
    899         }
    900 
    901         status = lck->record->store(lck->record, data, TDB_REPLACE);
    902         if (!NT_STATUS_IS_OK(status)) {
    903                 char *errmsg;
    904 
    905                 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
    906 
    907                 if (asprintf(&errmsg, "could not store share mode entry: %s",
    908                              nt_errstr(status)) == -1) {
    909                         smb_panic("could not store share mode entry");
    910                 }
    911                 smb_panic(errmsg);
    912         }
    913 
    914  done:
    915 
    916         return 0;
    917 }
    918 
    919 static bool fill_share_mode_lock(struct share_mode_lock *lck,
    920                                  struct file_id id,
    921                                  const char *servicepath,
    922                                  const struct smb_filename *smb_fname,
    923                                  TDB_DATA share_mode_data,
    924                                  const struct timespec *old_write_time)
    925 {
    926         /* Ensure we set every field here as the destructor must be
    927            valid even if parse_share_modes fails. */
    928 
    929         lck->servicepath = NULL;
    930         lck->base_name = NULL;
    931         lck->stream_name = NULL;
    932         lck->id = id;
    933         lck->num_share_modes = 0;
    934         lck->share_modes = NULL;
    935         lck->delete_tokens = NULL;
    936         ZERO_STRUCT(lck->old_write_time);
    937         ZERO_STRUCT(lck->changed_write_time);
    938         lck->fresh = False;
    939         lck->modified = False;
    940 
    941         lck->fresh = (share_mode_data.dptr == NULL);
    942 
    943         if (lck->fresh) {
    944                 bool has_stream;
    945                 if (smb_fname == NULL || servicepath == NULL
    946                     || old_write_time == NULL) {
    947                         return False;
    948                 }
    949 
    950                 has_stream = smb_fname->stream_name != NULL;
    951 
    952                 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
    953                 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
    954                 lck->servicepath = talloc_strdup(lck, servicepath);
    955                 if (lck->base_name == NULL ||
    956                     (has_stream && lck->stream_name == NULL) ||
    957                     lck->servicepath == NULL) {
    958                         DEBUG(0, ("talloc failed\n"));
    959                         return False;
    960                 }
    961                 lck->old_write_time = *old_write_time;
    962         } else {
    963                 if (!parse_share_modes(share_mode_data, lck)) {
    964                         DEBUG(0, ("Could not parse share modes\n"));
    965                         return False;
    966                 }
    967         }
    968 
    969         return True;
    970 }
    971 
    972 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
    973                                             const struct file_id id,
    974                                             const char *servicepath,
    975                                             const struct smb_filename *smb_fname,
    976                                             const struct timespec *old_write_time)
    977 {
    978         struct share_mode_lock *lck;
    979         struct file_id tmp;
    980         TDB_DATA key = locking_key(&id, &tmp);
    981 
    982         if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
    983                 DEBUG(0, ("talloc failed\n"));
    984                 return NULL;
    985         }
    986 
    987         if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
    988                 DEBUG(3, ("Could not lock share entry\n"));
    989                 TALLOC_FREE(lck);
    990                 return NULL;
    991         }
    992 
    993         if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
    994                                   lck->record->value, old_write_time)) {
    995                 DEBUG(3, ("fill_share_mode_lock failed\n"));
    996                 TALLOC_FREE(lck);
    997                 return NULL;
    998         }
    999 
    1000         talloc_set_destructor(lck, share_mode_lock_destructor);
    1001 
    1002         return lck;
    1003 }
    1004 
    1005 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
    1006                                                   const struct file_id id)
    1007 {
    1008         struct share_mode_lock *lck;
    1009         struct file_id tmp;
    1010         TDB_DATA key = locking_key(&id, &tmp);
    1011         TDB_DATA data;
    1012 
    1013         if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
    1014                 DEBUG(0, ("talloc failed\n"));
    1015                 return NULL;
    1016         }
    1017 
    1018         if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
    1019                 DEBUG(3, ("Could not fetch share entry\n"));
    1020                 TALLOC_FREE(lck);
    1021                 return NULL;
    1022         }
    1023 
    1024         if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
    1025                 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
    1026                            "around (file not open)\n"));
    1027                 TALLOC_FREE(lck);
    1028                 return NULL;
    1029         }
    1030 
    1031         return lck;
     450struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
     451                                                     const struct file_id id)
     452{
     453        return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
    1032454}
    1033455
     
    1041463bool rename_share_filename(struct messaging_context *msg_ctx,
    1042464                        struct share_mode_lock *lck,
     465                        struct file_id id,
    1043466                        const char *servicepath,
    1044467                        uint32_t orig_name_hash,
     
    1046469                        const struct smb_filename *smb_fname_dst)
    1047470{
     471        struct share_mode_data *d = lck->data;
    1048472        size_t sp_len;
    1049473        size_t bn_len;
     
    1051475        size_t msg_len;
    1052476        char *frm = NULL;
    1053         int i;
     477        uint32_t i;
    1054478        bool strip_two_chars = false;
    1055479        bool has_stream = smb_fname_dst->stream_name != NULL;
     480        struct server_id self_pid = messaging_server_id(msg_ctx);
    1056481
    1057482        DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
     
    1069494        }
    1070495
    1071         lck->servicepath = talloc_strdup(lck, servicepath);
    1072         lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
     496        d->servicepath = talloc_strdup(d, servicepath);
     497        d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
    1073498                                       (strip_two_chars ? 2 : 0));
    1074         lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
    1075         if (lck->base_name == NULL ||
    1076             (has_stream && lck->stream_name == NULL) ||
    1077             lck->servicepath == NULL) {
     499        d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
     500        if (d->base_name == NULL ||
     501            (has_stream && d->stream_name == NULL) ||
     502            d->servicepath == NULL) {
    1078503                DEBUG(0, ("rename_share_filename: talloc failed\n"));
    1079504                return False;
    1080505        }
    1081         lck->modified = True;
    1082 
    1083         sp_len = strlen(lck->servicepath);
    1084         bn_len = strlen(lck->base_name);
    1085         sn_len = has_stream ? strlen(lck->stream_name) : 0;
     506        d->modified = True;
     507
     508        sp_len = strlen(d->servicepath);
     509        bn_len = strlen(d->base_name);
     510        sn_len = has_stream ? strlen(d->stream_name) : 0;
    1086511
    1087512        msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
     
    1089514
    1090515        /* Set up the name changed message. */
    1091         frm = TALLOC_ARRAY(lck, char, msg_len);
     516        frm = talloc_array(d, char, msg_len);
    1092517        if (!frm) {
    1093518                return False;
    1094519        }
    1095520
    1096         push_file_id_24(frm, &lck->id);
     521        push_file_id_24(frm, &id);
    1097522
    1098523        DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
    1099524
    1100         safe_strcpy(&frm[24], lck->servicepath, sp_len);
    1101         safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
    1102         safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
    1103                     sn_len);
     525        strlcpy(&frm[24],
     526                d->servicepath ? d->servicepath : "",
     527                sp_len+1);
     528        strlcpy(&frm[24 + sp_len + 1],
     529                d->base_name ? d->base_name : "",
     530                bn_len+1);
     531        strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
     532                d->stream_name ? d->stream_name : "",
     533                sn_len+1);
    1104534
    1105535        /* Send the messages. */
    1106         for (i=0; i<lck->num_share_modes; i++) {
    1107                 struct share_mode_entry *se = &lck->share_modes[i];
     536        for (i=0; i<d->num_share_modes; i++) {
     537                struct share_mode_entry *se = &d->share_modes[i];
     538                struct server_id_buf tmp;
     539
    1108540                if (!is_valid_share_mode_entry(se)) {
    1109541                        continue;
     
    1119551
    1120552                /* But not to ourselves... */
    1121                 if (procid_is_me(&se->pid)) {
     553                if (serverid_equal(&se->pid, &self_pid)) {
     554                        continue;
     555                }
     556
     557                if (share_mode_stale_pid(d, i)) {
    1122558                        continue;
    1123559                }
     
    1126562                          "pid %s file_id %s sharepath %s base_name %s "
    1127563                          "stream_name %s\n",
    1128                           procid_str_static(&se->pid),
    1129                           file_id_string_tos(&lck->id),
    1130                           lck->servicepath, lck->base_name,
    1131                         has_stream ? lck->stream_name : ""));
     564                          server_id_str_buf(se->pid, &tmp),
     565                          file_id_string_tos(&id),
     566                          d->servicepath, d->base_name,
     567                        has_stream ? d->stream_name : ""));
    1132568
    1133569                messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
    1134                                    (uint8 *)frm, msg_len);
     570                                   (uint8_t *)frm, msg_len);
     571        }
     572
     573        for (i=0; i<d->num_leases; i++) {
     574                /* Update the filename in leases_db. */
     575                NTSTATUS status;
     576                struct share_mode_lease *l;
     577
     578                l = &d->leases[i];
     579
     580                status = leases_db_rename(&l->client_guid,
     581                                        &l->lease_key,
     582                                        &id,
     583                                        d->servicepath,
     584                                        d->base_name,
     585                                        d->stream_name);
     586                if (!NT_STATUS_IS_OK(status)) {
     587                        /* Any error recovery possible here ? */
     588                        DEBUG(1,("Failed to rename lease key for "
     589                                "renamed file %s:%s. %s\n",
     590                                d->base_name,
     591                                d->stream_name,
     592                                nt_errstr(status)));
     593                        continue;
     594                }
    1135595        }
    1136596
     
    1162622
    1163623        if (write_time) {
    1164                 struct timespec wt;
    1165 
    1166                 wt = lck->changed_write_time;
    1167                 if (null_timespec(wt)) {
    1168                         wt = lck->old_write_time;
    1169                 }
    1170 
    1171                 *write_time = wt;
     624                *write_time = get_share_mode_write_time(lck);
    1172625        }
    1173626
     
    1179632        int num_props = 0;
    1180633
    1181         if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
    1182                 /* cope with dead entries from the process not
    1183                    existing. These should not be considered valid,
    1184                    otherwise we end up doing zero timeout sharing
    1185                    violation */
    1186                 return False;
     634        if (e->stale) {
     635                return false;
    1187636        }
    1188637
     
    1190639        num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
    1191640        num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
    1192 
    1193         SMB_ASSERT(num_props <= 1);
     641        num_props += (e->op_type == LEASE_OPLOCK);
     642
     643        if ((num_props > 1) && serverid_exists(&e->pid)) {
     644                smb_panic("Invalid share mode entry");
     645        }
    1194646        return (num_props != 0);
    1195647}
    1196648
    1197 bool is_deferred_open_entry(const struct share_mode_entry *e)
    1198 {
    1199         return (e->op_type == DEFERRED_OPEN_ENTRY);
    1200 }
    1201 
    1202 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
    1203 {
    1204         return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
    1205 }
    1206 
    1207 /*******************************************************************
    1208  Fill a share mode entry.
    1209 ********************************************************************/
    1210 
    1211 static void fill_share_mode_entry(struct share_mode_entry *e,
    1212                                   files_struct *fsp,
    1213                                   uid_t uid, uint64_t mid, uint16 op_type)
    1214 {
     649/*
     650 * See if we need to remove a lease being referred to by a
     651 * share mode that is being marked stale or deleted.
     652 */
     653
     654static void remove_share_mode_lease(struct share_mode_data *d,
     655                                    struct share_mode_entry *e)
     656{
     657        struct GUID client_guid;
     658        struct smb2_lease_key lease_key;
     659        uint16_t op_type;
     660        uint32_t lease_idx;
     661        uint32_t i;
     662
     663        op_type = e->op_type;
     664        e->op_type = NO_OPLOCK;
     665
     666        d->modified = true;
     667
     668        if (op_type != LEASE_OPLOCK) {
     669                return;
     670        }
     671
     672        /*
     673         * This used to reference a lease. If there's no other one referencing
     674         * it, remove it.
     675         */
     676
     677        lease_idx = e->lease_idx;
     678        e->lease_idx = UINT32_MAX;
     679
     680        for (i=0; i<d->num_share_modes; i++) {
     681                if (d->share_modes[i].stale) {
     682                        continue;
     683                }
     684                if (e == &d->share_modes[i]) {
     685                        /* Not ourselves. */
     686                        continue;
     687                }
     688                if (d->share_modes[i].lease_idx == lease_idx) {
     689                        break;
     690                }
     691        }
     692        if (i < d->num_share_modes) {
     693                /*
     694                 * Found another one
     695                 */
     696                return;
     697        }
     698
     699        memcpy(&client_guid,
     700                &d->leases[lease_idx].client_guid,
     701                sizeof(client_guid));
     702        lease_key = d->leases[lease_idx].lease_key;
     703
     704        d->num_leases -= 1;
     705        d->leases[lease_idx] = d->leases[d->num_leases];
     706
     707        /*
     708         * We changed the lease array. Fix all references to it.
     709         */
     710        for (i=0; i<d->num_share_modes; i++) {
     711                if (d->share_modes[i].lease_idx == d->num_leases) {
     712                        d->share_modes[i].lease_idx = lease_idx;
     713                        d->share_modes[i].lease = &d->leases[lease_idx];
     714                }
     715        }
     716
     717        {
     718                NTSTATUS status;
     719
     720                status = leases_db_del(&client_guid,
     721                                        &lease_key,
     722                                        &e->id);
     723
     724                DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
     725                           nt_errstr(status)));
     726        }
     727}
     728
     729/*
     730 * In case d->share_modes[i] conflicts with something or otherwise is
     731 * being used, we need to make sure the corresponding process still
     732 * exists.
     733 */
     734bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
     735{
     736        struct server_id_buf tmp;
     737        struct share_mode_entry *e;
     738
     739        if (idx > d->num_share_modes) {
     740                DEBUG(1, ("Asking for index %u, only %u around\n",
     741                          idx, (unsigned)d->num_share_modes));
     742                return false;
     743        }
     744        e = &d->share_modes[idx];
     745        if (e->stale) {
     746                /*
     747                 * Checked before
     748                 */
     749                return true;
     750        }
     751        if (serverid_exists(&e->pid)) {
     752                DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
     753                           server_id_str_buf(e->pid, &tmp), idx,
     754                           (unsigned)d->num_share_modes));
     755                return false;
     756        }
     757        DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
     758                   server_id_str_buf(e->pid, &tmp), idx,
     759                   (unsigned)d->num_share_modes));
     760
     761        e->stale = true;
     762
     763        if (d->num_delete_tokens != 0) {
     764                uint32_t i, num_stale;
     765
     766                /*
     767                 * We cannot have any delete tokens
     768                 * if there are no valid share modes.
     769                 */
     770
     771                num_stale = 0;
     772
     773                for (i=0; i<d->num_share_modes; i++) {
     774                        if (d->share_modes[i].stale) {
     775                                num_stale += 1;
     776                        }
     777                }
     778
     779                if (num_stale == d->num_share_modes) {
     780                        /*
     781                         * No non-stale share mode found
     782                         */
     783                        TALLOC_FREE(d->delete_tokens);
     784                        d->num_delete_tokens = 0;
     785                }
     786        }
     787
     788        remove_share_mode_lease(d, e);
     789
     790        d->modified = true;
     791        return true;
     792}
     793
     794void remove_stale_share_mode_entries(struct share_mode_data *d)
     795{
     796        uint32_t i;
     797
     798        i = 0;
     799        while (i < d->num_share_modes) {
     800                if (d->share_modes[i].stale) {
     801                        struct share_mode_entry *m = d->share_modes;
     802                        m[i] = m[d->num_share_modes-1];
     803                        d->num_share_modes -= 1;
     804                } else {
     805                        i += 1;
     806                }
     807        }
     808}
     809
     810bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
     811                    uid_t uid, uint64_t mid, uint16_t op_type,
     812                    uint32_t lease_idx)
     813{
     814        struct share_mode_data *d = lck->data;
     815        struct share_mode_entry *tmp, *e;
     816        struct share_mode_lease *lease = NULL;
     817
     818        if (lease_idx == UINT32_MAX) {
     819                lease = NULL;
     820        } else if (lease_idx >= d->num_leases) {
     821                return false;
     822        } else {
     823                lease = &d->leases[lease_idx];
     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
    1215836        ZERO_STRUCTP(e);
    1216         e->pid = sconn_server_id(fsp->conn->sconn);
     837        e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
    1217838        e->share_access = fsp->share_access;
    1218839        e->private_options = fsp->fh->private_options;
     
    1220841        e->op_mid = mid;
    1221842        e->op_type = op_type;
     843        e->lease_idx = lease_idx;
     844        e->lease = lease;
    1222845        e->time.tv_sec = fsp->open_time.tv_sec;
    1223846        e->time.tv_usec = fsp->open_time.tv_usec;
    1224847        e->id = fsp->file_id;
    1225848        e->share_file_id = fsp->fh->gen_id;
    1226         e->uid = (uint32)uid;
    1227         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
     849        e->uid = (uint32_t)uid;
     850        e->flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
     851                SHARE_MODE_FLAG_POSIX_OPEN : 0;
    1228852        e->name_hash = fsp->name_hash;
    1229 }
    1230 
    1231 static void fill_deferred_open_entry(struct share_mode_entry *e,
    1232                                      const struct timeval request_time,
    1233                                      struct file_id id,
    1234                                      struct server_id pid,
    1235                                      uint64_t mid)
    1236 {
    1237         ZERO_STRUCTP(e);
    1238         e->pid = pid;
    1239         e->op_mid = mid;
    1240         e->op_type = DEFERRED_OPEN_ENTRY;
    1241         e->time.tv_sec = request_time.tv_sec;
    1242         e->time.tv_usec = request_time.tv_usec;
    1243         e->id = id;
    1244         e->uid = (uint32)-1;
    1245         e->flags = 0;
    1246 }
    1247 
    1248 static void add_share_mode_entry(struct share_mode_lock *lck,
    1249                                  const struct share_mode_entry *entry)
    1250 {
     853
     854        return true;
     855}
     856
     857static struct share_mode_entry *find_share_mode_entry(
     858        struct share_mode_lock *lck, files_struct *fsp)
     859{
     860        struct share_mode_data *d = lck->data;
     861        struct server_id pid;
    1251862        int i;
    1252863
    1253         for (i=0; i<lck->num_share_modes; i++) {
    1254                 struct share_mode_entry *e = &lck->share_modes[i];
    1255                 if (is_unused_share_mode_entry(e)) {
    1256                         *e = *entry;
    1257                         break;
    1258                 }
    1259         }
    1260 
    1261         if (i == lck->num_share_modes) {
    1262                 /* No unused entry found */
    1263                 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
    1264                              &lck->share_modes, &lck->num_share_modes);
    1265         }
    1266         lck->modified = True;
    1267 }
    1268 
    1269 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
    1270                     uid_t uid, uint64_t mid, uint16 op_type)
    1271 {
    1272         struct share_mode_entry entry;
    1273         fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
    1274         add_share_mode_entry(lck, &entry);
    1275 }
    1276 
    1277 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
    1278                        struct timeval request_time,
    1279                        struct server_id pid, struct file_id id)
    1280 {
    1281         struct share_mode_entry entry;
    1282         fill_deferred_open_entry(&entry, request_time, id, pid, mid);
    1283         add_share_mode_entry(lck, &entry);
    1284 }
    1285 
    1286 /*******************************************************************
    1287  Check if two share mode entries are identical, ignoring oplock
    1288  and mid info and desired_access. (Removed paranoia test - it's
    1289  not automatically a logic error if they are identical. JRA.)
    1290 ********************************************************************/
    1291 
    1292 static bool share_modes_identical(struct share_mode_entry *e1,
    1293                                   struct share_mode_entry *e2)
    1294 {
    1295         /* We used to check for e1->share_access == e2->share_access here
    1296            as well as the other fields but 2 different DOS or FCB opens
    1297            sharing the same share mode entry may validly differ in
    1298            fsp->share_access field. */
    1299 
    1300         return (procid_equal(&e1->pid, &e2->pid) &&
    1301                 file_id_equal(&e1->id, &e2->id) &&
    1302                 e1->share_file_id == e2->share_file_id );
    1303 }
    1304 
    1305 static bool deferred_open_identical(struct share_mode_entry *e1,
    1306                                     struct share_mode_entry *e2)
    1307 {
    1308         return (procid_equal(&e1->pid, &e2->pid) &&
    1309                 (e1->op_mid == e2->op_mid) &&
    1310                 file_id_equal(&e1->id, &e2->id));
    1311 }
    1312 
    1313 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
    1314                                                       struct share_mode_entry *entry)
    1315 {
    1316         int i;
    1317 
    1318         for (i=0; i<lck->num_share_modes; i++) {
    1319                 struct share_mode_entry *e = &lck->share_modes[i];
    1320                 if (is_valid_share_mode_entry(entry) &&
    1321                     is_valid_share_mode_entry(e) &&
    1322                     share_modes_identical(e, entry)) {
    1323                         return e;
    1324                 }
    1325                 if (is_deferred_open_entry(entry) &&
    1326                     is_deferred_open_entry(e) &&
    1327                     deferred_open_identical(e, entry)) {
    1328                         return e;
    1329                 }
     864        pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
     865
     866        for (i=0; i<d->num_share_modes; i++) {
     867                struct share_mode_entry *e = &d->share_modes[i];
     868
     869                if (!is_valid_share_mode_entry(e)) {
     870                        continue;
     871                }
     872                if (!serverid_equal(&pid, &e->pid)) {
     873                        continue;
     874                }
     875                if (!file_id_equal(&fsp->file_id, &e->id)) {
     876                        continue;
     877                }
     878                if (fsp->fh->gen_id != e->share_file_id) {
     879                        continue;
     880                }
     881                return e;
    1330882        }
    1331883        return NULL;
     
    1339891bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
    1340892{
    1341         struct share_mode_entry entry, *e;
    1342 
    1343         /* Don't care about the pid owner being correct here - just a search. */
    1344         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
    1345 
    1346         e = find_share_mode_entry(lck, &entry);
     893        struct share_mode_entry *e;
     894
     895        e = find_share_mode_entry(lck, fsp);
    1347896        if (e == NULL) {
    1348897                return False;
    1349898        }
    1350 
    1351         e->op_type = UNUSED_SHARE_MODE_ENTRY;
    1352         lck->modified = True;
     899        remove_share_mode_lease(lck->data, e);
     900        *e = lck->data->share_modes[lck->data->num_share_modes-1];
     901        lck->data->num_share_modes -= 1;
     902        lck->data->modified = True;
    1353903        return True;
    1354904}
    1355905
    1356 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
    1357                              struct server_id pid)
    1358 {
    1359         struct share_mode_entry entry, *e;
    1360 
    1361         fill_deferred_open_entry(&entry, timeval_zero(),
    1362                                  lck->id, pid, mid);
    1363 
    1364         e = find_share_mode_entry(lck, &entry);
     906bool mark_share_mode_disconnected(struct share_mode_lock *lck,
     907                                  struct files_struct *fsp)
     908{
     909        struct share_mode_entry *e;
     910
     911        if (lck->data->num_share_modes != 1) {
     912                return false;
     913        }
     914
     915        if (fsp->op == NULL) {
     916                return false;
     917        }
     918        if (!fsp->op->global->durable) {
     919                return false;
     920        }
     921
     922        e = find_share_mode_entry(lck, fsp);
    1365923        if (e == NULL) {
    1366                 return;
    1367         }
    1368 
    1369         e->op_type = UNUSED_SHARE_MODE_ENTRY;
    1370         lck->modified = True;
     924                return false;
     925        }
     926
     927        DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
     928
     929        server_id_set_disconnected(&e->pid);
     930
     931        /*
     932         * On reopen the caller needs to check that
     933         * the client comes with the correct handle.
     934         */
     935        e->share_file_id = fsp->op->global->open_persistent_id;
     936
     937        lck->data->modified = true;
     938        return true;
    1371939}
    1372940
     
    1377945bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
    1378946{
    1379         struct share_mode_entry entry, *e;
    1380 
    1381         /* Don't care about the pid owner being correct here - just a search. */
    1382         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
    1383 
    1384         e = find_share_mode_entry(lck, &entry);
     947        struct share_mode_data *d = lck->data;
     948        struct share_mode_entry *e;
     949
     950        e = find_share_mode_entry(lck, fsp);
    1385951        if (e == NULL) {
    1386952                return False;
    1387953        }
    1388954
    1389         if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
    1390                 /*
    1391                  * Going from exclusive or batch,
    1392                  * we always go through FAKE_LEVEL_II
    1393                  * first.
    1394                  */
    1395                 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    1396                         smb_panic("remove_share_oplock: logic error");
    1397                 }
    1398                 e->op_type = FAKE_LEVEL_II_OPLOCK;
    1399         } else {
    1400                 e->op_type = NO_OPLOCK;
    1401         }
    1402         lck->modified = True;
    1403         return True;
     955        remove_share_mode_lease(d, e);
     956        d->modified = True;
     957        return true;
    1404958}
    1405959
     
    1410964bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
    1411965{
    1412         struct share_mode_entry entry, *e;
    1413 
    1414         /* Don't care about the pid owner being correct here - just a search. */
    1415         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
    1416 
    1417         e = find_share_mode_entry(lck, &entry);
     966        struct share_mode_entry *e;
     967
     968        e = find_share_mode_entry(lck, fsp);
    1418969        if (e == NULL) {
    1419970                return False;
     
    1421972
    1422973        e->op_type = LEVEL_II_OPLOCK;
    1423         lck->modified = True;
     974        lck->data->modified = True;
    1424975        return True;
    1425976}
    1426977
    1427 /****************************************************************************
    1428  Check if setting delete on close is allowed on this fsp.
    1429 ****************************************************************************/
    1430 
    1431 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
    1432 {
     978NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
     979                               struct share_mode_lock *lck,
     980                               const struct smb2_lease_key *key,
     981                               uint32_t new_lease_state,
     982                               struct share_mode_lease **_l)
     983{
     984        struct share_mode_data *d = lck->data;
     985        struct share_mode_lease *l;
     986        uint32_t i;
     987
     988        *_l = NULL;
     989
     990        for (i=0; i<d->num_leases; i++) {
     991                if (smb2_lease_equal(&sconn->client->connections->smb2.client.guid,
     992                                     key,
     993                                     &d->leases[i].client_guid,
     994                                     &d->leases[i].lease_key)) {
     995                        break;
     996                }
     997        }
     998        if (i == d->num_leases) {
     999                DEBUG(10, ("lease not found\n"));
     1000                return NT_STATUS_INVALID_PARAMETER;
     1001        }
     1002
     1003        l = &d->leases[i];
     1004
     1005        if (!l->breaking) {
     1006                DEBUG(1, ("Attempt to break from %d to %d - but we're not in breaking state\n",
     1007                           (int)l->current_state, (int)new_lease_state));
     1008                return NT_STATUS_UNSUCCESSFUL;
     1009        }
     1010
    14331011        /*
    1434          * Only allow delete on close for writable files.
     1012         * Can't upgrade anything: l->breaking_to_requested (and l->current_state)
     1013         * must be a strict bitwise superset of new_lease_state
    14351014         */
    1436 
    1437         if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
    1438             !lp_delete_readonly(SNUM(fsp->conn))) {
    1439                 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
    1440                           "flag set but file attribute is readonly.\n",
    1441                           fsp_str_dbg(fsp)));
    1442                 return NT_STATUS_CANNOT_DELETE;
    1443         }
    1444 
    1445         /*
    1446          * Only allow delete on close for writable shares.
    1447          */
    1448 
    1449         if (!CAN_WRITE(fsp->conn)) {
    1450                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
    1451                           "close flag set but write access denied on share.\n",
    1452                           fsp_str_dbg(fsp)));
    1453                 return NT_STATUS_ACCESS_DENIED;
    1454         }
    1455 
    1456         /*
    1457          * Only allow delete on close for files/directories opened with delete
    1458          * intent.
    1459          */
    1460 
    1461         if (!(fsp->access_mask & DELETE_ACCESS)) {
    1462                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
    1463                           "close flag set but delete access denied.\n",
    1464                           fsp_str_dbg(fsp)));
    1465                 return NT_STATUS_ACCESS_DENIED;
    1466         }
    1467 
    1468         /* Don't allow delete on close for non-empty directories. */
    1469         if (fsp->is_directory) {
    1470                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
    1471 
    1472                 /* Or the root of a share. */
    1473                 if (ISDOT(fsp->fsp_name->base_name)) {
    1474                         DEBUG(10,("can_set_delete_on_close: can't set delete on "
    1475                                   "close for the root of a share.\n"));
    1476                         return NT_STATUS_ACCESS_DENIED;
    1477                 }
    1478 
    1479                 return can_delete_directory_fsp(fsp);
    1480         }
     1015        if ((new_lease_state & l->breaking_to_requested) != new_lease_state) {
     1016                DEBUG(1, ("Attempt to upgrade from %d to %d - expected %d\n",
     1017                           (int)l->current_state, (int)new_lease_state,
     1018                           (int)l->breaking_to_requested));
     1019                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     1020        }
     1021
     1022        if (l->current_state != new_lease_state) {
     1023                l->current_state = new_lease_state;
     1024                d->modified = true;
     1025        }
     1026
     1027        if ((new_lease_state & ~l->breaking_to_required) != 0) {
     1028                DEBUG(5, ("lease state %d not fully broken from %d to %d\n",
     1029                           (int)new_lease_state,
     1030                           (int)l->current_state,
     1031                           (int)l->breaking_to_required));
     1032                l->breaking_to_requested = l->breaking_to_required;
     1033                if (l->current_state & (~SMB2_LEASE_READ)) {
     1034                        /*
     1035                         * Here we break in steps, as windows does
     1036                         * see the breaking3 and v2_breaking3 tests.
     1037                         */
     1038                        l->breaking_to_requested |= SMB2_LEASE_READ;
     1039                }
     1040                d->modified = true;
     1041                *_l = l;
     1042                return NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
     1043        }
     1044
     1045        DEBUG(10, ("breaking from %d to %d - expected %d\n",
     1046                   (int)l->current_state, (int)new_lease_state,
     1047                   (int)l->breaking_to_requested));
     1048
     1049        l->breaking_to_requested = 0;
     1050        l->breaking_to_required = 0;
     1051        l->breaking = false;
     1052
     1053        d->modified = true;
    14811054
    14821055        return NT_STATUS_OK;
    1483 }
    1484 
    1485 /*************************************************************************
    1486  Return a talloced copy of a struct security_unix_token. NULL on fail.
    1487  (Should this be in locking.c.... ?).
    1488 *************************************************************************/
    1489 
    1490 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
    1491 {
    1492         struct security_unix_token *cpy;
    1493 
    1494         cpy = TALLOC_P(ctx, struct security_unix_token);
    1495         if (!cpy) {
    1496                 return NULL;
    1497         }
    1498 
    1499         cpy->uid = tok->uid;
    1500         cpy->gid = tok->gid;
    1501         cpy->ngroups = tok->ngroups;
    1502         if (tok->ngroups) {
    1503                 /* Make this a talloc child of cpy. */
    1504                 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
    1505                 if (!cpy->groups) {
    1506                         return NULL;
    1507                 }
    1508                 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
    1509         }
    1510         return cpy;
    15111056}
    15121057
     
    15151060****************************************************************************/
    15161061
    1517 static bool add_delete_on_close_token(struct share_mode_lock *lck,
     1062static bool add_delete_on_close_token(struct share_mode_data *d,
    15181063                        uint32_t name_hash,
    15191064                        const struct security_token *nt_tok,
    15201065                        const struct security_unix_token *tok)
    15211066{
    1522         struct delete_token_list *dtl;
    1523 
    1524         dtl = TALLOC_ZERO_P(lck, struct delete_token_list);
    1525         if (dtl == NULL) {
     1067        struct delete_token *tmp, *dtl;
     1068
     1069        tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
     1070                             d->num_delete_tokens+1);
     1071        if (tmp == NULL) {
    15261072                return false;
    15271073        }
     1074        d->delete_tokens = tmp;
     1075        dtl = &d->delete_tokens[d->num_delete_tokens];
    15281076
    15291077        dtl->name_hash = name_hash;
    1530         dtl->delete_token = copy_unix_token(dtl, tok);
     1078        dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
     1079        if (dtl->delete_nt_token == NULL) {
     1080                return false;
     1081        }
     1082        dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
    15311083        if (dtl->delete_token == NULL) {
    1532                 TALLOC_FREE(dtl);
    15331084                return false;
    15341085        }
    1535         dtl->delete_nt_token = dup_nt_token(dtl, nt_tok);
    1536         if (dtl->delete_nt_token == NULL) {
    1537                 TALLOC_FREE(dtl);
    1538                 return false;
    1539         }
    1540         DLIST_ADD(lck->delete_tokens, dtl);
    1541         lck->modified = true;
     1086        d->num_delete_tokens += 1;
     1087        d->modified = true;
    15421088        return true;
     1089}
     1090
     1091void reset_delete_on_close_lck(files_struct *fsp,
     1092                               struct share_mode_lock *lck)
     1093{
     1094        struct share_mode_data *d = lck->data;
     1095        uint32_t i;
     1096
     1097        for (i=0; i<d->num_delete_tokens; i++) {
     1098                struct delete_token *dt = &d->delete_tokens[i];
     1099
     1100                if (dt->name_hash == fsp->name_hash) {
     1101                        d->modified = true;
     1102
     1103                        /* Delete this entry. */
     1104                        TALLOC_FREE(dt->delete_nt_token);
     1105                        TALLOC_FREE(dt->delete_token);
     1106                        *dt = d->delete_tokens[d->num_delete_tokens-1];
     1107                        d->num_delete_tokens -= 1;
     1108                }
     1109        }
    15431110}
    15441111
     
    15561123void set_delete_on_close_lck(files_struct *fsp,
    15571124                        struct share_mode_lock *lck,
    1558                         bool delete_on_close,
    15591125                        const struct security_token *nt_tok,
    15601126                        const struct security_unix_token *tok)
    15611127{
    1562         struct delete_token_list *dtl;
     1128        struct messaging_context *msg_ctx = fsp->conn->sconn->msg_ctx;
     1129        struct share_mode_data *d = lck->data;
     1130        uint32_t i;
    15631131        bool ret;
    1564 
    1565         if (delete_on_close) {
    1566                 SMB_ASSERT(nt_tok != NULL);
    1567                 SMB_ASSERT(tok != NULL);
    1568         } else {
    1569                 SMB_ASSERT(nt_tok == NULL);
    1570                 SMB_ASSERT(tok == NULL);
    1571         }
    1572 
    1573         for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
    1574                 if (dtl->name_hash == fsp->name_hash) {
    1575                         lck->modified = true;
    1576                         if (delete_on_close == false) {
    1577                                 /* Delete this entry. */
    1578                                 DLIST_REMOVE(lck->delete_tokens, dtl);
    1579                                 TALLOC_FREE(dtl);
    1580                         } else {
    1581                                 /* Replace this token with the
    1582                                    given tok. */
    1583                                 TALLOC_FREE(dtl->delete_token);
    1584                                 dtl->delete_token = copy_unix_token(dtl, tok);
    1585                                 SMB_ASSERT(dtl->delete_token != NULL);
    1586                                 TALLOC_FREE(dtl->delete_nt_token);
    1587                                 dtl->delete_nt_token = dup_nt_token(dtl, nt_tok);
    1588                                 SMB_ASSERT(dtl->delete_nt_token != NULL);
    1589                         }
     1132        DATA_BLOB fid_blob = {};
     1133        enum ndr_err_code ndr_err;
     1134
     1135        SMB_ASSERT(nt_tok != NULL);
     1136        SMB_ASSERT(tok != NULL);
     1137
     1138        for (i=0; i<d->num_delete_tokens; i++) {
     1139                struct delete_token *dt = &d->delete_tokens[i];
     1140                if (dt->name_hash == fsp->name_hash) {
     1141                        d->modified = true;
     1142
     1143                        /* Replace this token with the given tok. */
     1144                        TALLOC_FREE(dt->delete_nt_token);
     1145                        dt->delete_nt_token = dup_nt_token(dt, nt_tok);
     1146                        SMB_ASSERT(dt->delete_nt_token != NULL);
     1147                        TALLOC_FREE(dt->delete_token);
     1148                        dt->delete_token = copy_unix_token(dt, tok);
     1149                        SMB_ASSERT(dt->delete_token != NULL);
     1150
    15901151                        return;
    15911152                }
    15921153        }
    15931154
    1594         if (!delete_on_close) {
    1595                 /* Nothing to delete - not found. */
    1596                 return;
    1597         }
    1598 
    1599         ret = add_delete_on_close_token(lck, fsp->name_hash, nt_tok, tok);
     1155        ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
    16001156        SMB_ASSERT(ret);
     1157
     1158        ndr_err = ndr_push_struct_blob(&fid_blob, talloc_tos(), &fsp->file_id,
     1159                                       (ndr_push_flags_fn_t)ndr_push_file_id);
     1160        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1161                DEBUG(10, ("ndr_push_file_id failed: %s\n",
     1162                           ndr_errstr(ndr_err)));
     1163        }
     1164
     1165        for (i=0; i<d->num_share_modes; i++) {
     1166                struct share_mode_entry *e = &d->share_modes[i];
     1167                NTSTATUS status;
     1168
     1169                status = messaging_send(
     1170                        msg_ctx, e->pid, MSG_SMB_NOTIFY_CANCEL_DELETED,
     1171                        &fid_blob);
     1172
     1173                if (!NT_STATUS_IS_OK(status)) {
     1174                        struct server_id_buf tmp;
     1175                        DEBUG(10, ("%s: messaging_send to %s returned %s\n",
     1176                                   __func__, server_id_str_buf(e->pid, &tmp),
     1177                                   nt_errstr(status)));
     1178                }
     1179        }
     1180
     1181        TALLOC_FREE(fid_blob.data);
    16011182}
    16021183
     
    16061187{
    16071188        struct share_mode_lock *lck;
    1608        
     1189
    16091190        DEBUG(10,("set_delete_on_close: %s delete on close flag for "
    1610                   "fnum = %d, file %s\n",
    1611                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
     1191                  "%s, file %s\n",
     1192                  delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
    16121193                  fsp_str_dbg(fsp)));
    16131194
    1614         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
    1615                                   NULL);
     1195        lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
    16161196        if (lck == NULL) {
    16171197                return False;
     
    16191199
    16201200        if (delete_on_close) {
    1621                 set_delete_on_close_lck(fsp, lck, true,
    1622                         nt_tok,
    1623                         tok);
     1201                set_delete_on_close_lck(fsp, lck, nt_tok, tok);
    16241202        } else {
    1625                 set_delete_on_close_lck(fsp, lck, false,
    1626                         NULL,
    1627                         NULL);
     1203                reset_delete_on_close_lck(fsp, lck);
    16281204        }
    16291205
     
    16411217}
    16421218
     1219static struct delete_token *find_delete_on_close_token(
     1220        struct share_mode_data *d, uint32_t name_hash)
     1221{
     1222        uint32_t i;
     1223
     1224        DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
     1225                   (unsigned int)name_hash));
     1226
     1227        for (i=0; i<d->num_delete_tokens; i++) {
     1228                struct delete_token *dt = &d->delete_tokens[i];
     1229
     1230                DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
     1231                           (unsigned int)dt->name_hash ));
     1232                if (dt->name_hash == name_hash) {
     1233                        return dt;
     1234                }
     1235        }
     1236        return NULL;
     1237}
     1238
    16431239/****************************************************************************
    16441240 Return the NT token and UNIX token if there's a match. Return true if
     
    16471243
    16481244bool get_delete_on_close_token(struct share_mode_lock *lck,
    1649                                 uint32_t name_hash,
    1650                                 const struct security_token **pp_nt_tok,
    1651                                 const struct security_unix_token **pp_tok)
    1652 {
    1653         struct delete_token_list *dtl;
    1654 
    1655         DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
    1656                         (unsigned int)name_hash ));
    1657 
    1658         for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
    1659                 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
    1660                                 (unsigned int)dtl->name_hash ));
    1661                 if (dtl->name_hash == name_hash) {
    1662                         if (pp_nt_tok) {
    1663                                 *pp_nt_tok = dtl->delete_nt_token;
    1664                         }
    1665                         if (pp_tok) {
    1666                                 *pp_tok =  dtl->delete_token;
    1667                         }
    1668                         return true;
    1669                 }
    1670         }
    1671         return false;
     1245                                        uint32_t name_hash,
     1246                                        const struct security_token **pp_nt_tok,
     1247                                        const struct security_unix_token **pp_tok)
     1248{
     1249        struct delete_token *dt;
     1250
     1251        dt = find_delete_on_close_token(lck->data, name_hash);
     1252        if (dt == NULL) {
     1253                return false;
     1254        }
     1255        *pp_nt_tok = dt->delete_nt_token;
     1256        *pp_tok =  dt->delete_token;
     1257        return true;
    16721258}
    16731259
    16741260bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
    16751261{
    1676         return get_delete_on_close_token(lck, name_hash, NULL, NULL);
     1262        return find_delete_on_close_token(lck->data, name_hash) != NULL;
    16771263}
    16781264
     
    16861272                 file_id_string_tos(&fileid)));
    16871273
    1688         lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
     1274        lck = get_existing_share_mode_lock(talloc_tos(), fileid);
    16891275        if (lck == NULL) {
    16901276                return False;
    16911277        }
    16921278
    1693         if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
    1694                 lck->modified = True;
    1695                 lck->changed_write_time = write_time;
     1279        if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
     1280                lck->data->modified = True;
     1281                lck->data->changed_write_time = write_time;
    16961282        }
    16971283
     
    17091295                 file_id_string_tos(&fileid)));
    17101296
    1711         lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
     1297        lck = get_existing_share_mode_lock(talloc_tos(), fileid);
    17121298        if (lck == NULL) {
    17131299                return False;
    17141300        }
    17151301
    1716         if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
    1717                 lck->modified = True;
    1718                 lck->old_write_time = write_time;
     1302        if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
     1303                lck->data->modified = True;
     1304                lck->data->old_write_time = write_time;
    17191305        }
    17201306
     
    17231309}
    17241310
    1725 
    1726 struct forall_state {
    1727         void (*fn)(const struct share_mode_entry *entry,
    1728                    const char *sharepath,
    1729                    const char *fname,
    1730                    void *private_data);
    1731         void *private_data;
    1732 };
    1733 
    1734 static int traverse_fn(struct db_record *rec, void *_state)
    1735 {
    1736         struct forall_state *state = (struct forall_state *)_state;
    1737         int i;
    1738         struct share_mode_lock *lck;
    1739 
    1740         /* Ensure this is a locking_key record. */
    1741         if (rec->key.dsize != sizeof(struct file_id))
    1742                 return 0;
    1743 
    1744         lck = TALLOC_ZERO_P(talloc_tos(), struct share_mode_lock);
    1745         if (lck == NULL) {
    1746                 return 0;
    1747         }
    1748 
    1749         if (!parse_share_modes(rec->value, lck)) {
    1750                 TALLOC_FREE(lck);
    1751                 DEBUG(1, ("parse_share_modes failed\n"));
    1752                 return 0;
    1753         }
    1754 
    1755         for (i=0; i<lck->num_share_modes; i++) {
    1756                 struct share_mode_entry *se = &lck->share_modes[i];
    1757                 state->fn(se,
    1758                         lck->servicepath,
    1759                         lck->base_name,
    1760                         state->private_data);
    1761         }
    1762         TALLOC_FREE(lck);
    1763         return 0;
    1764 }
    1765 
    1766 /*******************************************************************
    1767  Call the specified function on each entry under management by the
    1768  share mode system.
    1769 ********************************************************************/
    1770 
    1771 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
    1772                                  const char *, void *),
    1773                       void *private_data)
    1774 {
    1775         struct forall_state state;
    1776 
    1777         if (lock_db == NULL)
    1778                 return 0;
    1779 
    1780         state.fn = fn;
    1781         state.private_data = private_data;
    1782 
    1783         return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);
    1784 }
     1311struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
     1312{
     1313        struct share_mode_data *d = lck->data;
     1314
     1315        if (!null_timespec(d->changed_write_time)) {
     1316                return d->changed_write_time;
     1317        }
     1318        return d->old_write_time;
     1319}
Note: See TracChangeset for help on using the changeset viewer.