Changeset 988 for vendor/current/source3/locking/locking.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/locking/locking.c
r860 r988 5 5 Copyright (C) Jeremy Allison 1992-2006 6 6 Copyright (C) Volker Lendecke 2005 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 30 30 support. 31 31 32 rewr tten completely to use new tdb code. Tridge, Dec '9932 rewritten completely to use new tdb code. Tridge, Dec '99 33 33 34 34 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000. … … 40 40 #include "locking/proto.h" 41 41 #include "smbd/globals.h" 42 #include "dbwrap.h" 42 #include "dbwrap/dbwrap.h" 43 #include "dbwrap/dbwrap_open.h" 43 44 #include "../libcli/security/security.h" 44 45 #include "serverid.h" 45 46 #include "messages.h" 46 47 #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" 48 51 49 52 #undef DBGC_CLASS … … 51 54 52 55 #define NO_LOCKING_COUNT (-1) 53 54 /* the locking database handle */55 static struct db_context *lock_db;56 56 57 57 /**************************************************************************** … … 96 96 plock->context.smblctx = smblctx; 97 97 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); 99 99 plock->start = start; 100 100 plock->size = size; … … 106 106 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) 107 107 { 108 struct byte_range_lock *br_lck; 108 109 int strict_locking = lp_strict_locking(fsp->conn->params); 109 110 bool ret = False; … … 118 119 119 120 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))); 164 158 165 159 return ret; … … 198 192 return brl_lockquery(br_lck, 199 193 psmblctx, 200 sconn_server_id(fsp->conn->sconn),194 messaging_server_id(fsp->conn->sconn->msg_ctx), 201 195 poffset, 202 196 pcount, … … 246 240 bool blocking_lock, 247 241 NTSTATUS *perr, 248 uint64_t *psmblctx, 249 struct blocking_lock_record *blr) 242 uint64_t *psmblctx) 250 243 { 251 244 struct byte_range_lock *br_lck = NULL; … … 269 262 /* NOTE! 0 byte long ranges ARE allowed and should be stored */ 270 263 271 DEBUG(10,("do_lock: lock flavour %s lock type %s start=% .0f len=%.0f"272 "blocking_lock=%s requested for fnum %dfile %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", 273 266 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))); 276 269 277 270 br_lck = brl_get_locks(talloc_tos(), fsp); … … 284 277 br_lck, 285 278 smblctx, 286 sconn_server_id(fsp->conn->sconn),279 messaging_server_id(fsp->conn->sconn->msg_ctx), 287 280 offset, 288 281 count, … … 290 283 lock_flav, 291 284 blocking_lock, 292 psmblctx, 293 blr); 285 psmblctx); 294 286 295 287 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr))); … … 312 304 bool ok = False; 313 305 struct byte_range_lock *br_lck = NULL; 314 306 315 307 if (!fsp->can_lock) { 316 308 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; 317 309 } 318 310 319 311 if (!lp_locking(fsp->conn->params)) { 320 312 return NT_STATUS_OK; 321 313 } 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))); 326 318 327 319 br_lck = brl_get_locks(talloc_tos(), fsp); … … 333 325 br_lck, 334 326 smblctx, 335 sconn_server_id(fsp->conn->sconn),327 messaging_server_id(fsp->conn->sconn->msg_ctx), 336 328 offset, 337 329 count, 338 330 lock_flav); 339 331 340 332 TALLOC_FREE(br_lck); 341 333 … … 354 346 355 347 NTSTATUS do_lock_cancel(files_struct *fsp, 356 uint64 smblctx,348 uint64_t smblctx, 357 349 uint64_t count, 358 350 uint64_t offset, 359 enum brl_flavour lock_flav, 360 struct blocking_lock_record *blr) 351 enum brl_flavour lock_flav) 361 352 { 362 353 bool ok = False; … … 367 358 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; 368 359 } 369 360 370 361 if (!lp_locking(fsp->conn->params)) { 371 362 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); 372 363 } 373 364 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))); 377 368 378 369 br_lck = brl_get_locks(talloc_tos(), fsp); … … 383 374 ok = brl_lock_cancel(br_lck, 384 375 smblctx, 385 sconn_server_id(fsp->conn->sconn),376 messaging_server_id(fsp->conn->sconn->msg_ctx), 386 377 offset, 387 378 count, 388 lock_flav, 389 blr); 379 lock_flav); 390 380 391 381 TALLOC_FREE(br_lck); … … 414 404 } 415 405 416 /* If we have no toutstanding locks or pending406 /* If we have no outstanding locks or pending 417 407 * locks then we don't need to look in the lock db. 418 408 */ … … 431 421 } 432 422 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 491 423 /******************************************************************* 492 424 Print out a share mode. … … 495 427 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e) 496 428 { 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]: " 498 432 "pid = %s, share_access = 0x%x, private_options = 0x%x, " 499 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %l u, "433 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, " 500 434 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x", 501 435 num, 502 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", 503 procid_str_static(&e->pid), 436 server_id_str_buf(e->pid, &tmp), 504 437 e->share_access, e->private_options, 505 438 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, 507 440 (unsigned int)e->uid, (unsigned int)e->flags, 508 441 file_id_string_tos(&e->id), … … 511 444 512 445 /******************************************************************* 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. 514 448 ********************************************************************/ 515 449 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; 450 struct 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); 1032 454 } 1033 455 … … 1041 463 bool rename_share_filename(struct messaging_context *msg_ctx, 1042 464 struct share_mode_lock *lck, 465 struct file_id id, 1043 466 const char *servicepath, 1044 467 uint32_t orig_name_hash, … … 1046 469 const struct smb_filename *smb_fname_dst) 1047 470 { 471 struct share_mode_data *d = lck->data; 1048 472 size_t sp_len; 1049 473 size_t bn_len; … … 1051 475 size_t msg_len; 1052 476 char *frm = NULL; 1053 int i;477 uint32_t i; 1054 478 bool strip_two_chars = false; 1055 479 bool has_stream = smb_fname_dst->stream_name != NULL; 480 struct server_id self_pid = messaging_server_id(msg_ctx); 1056 481 1057 482 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", … … 1069 494 } 1070 495 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 + 1073 498 (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) { 1078 503 DEBUG(0, ("rename_share_filename: talloc failed\n")); 1079 504 return False; 1080 505 } 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; 1086 511 1087 512 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 + … … 1089 514 1090 515 /* Set up the name changed message. */ 1091 frm = TALLOC_ARRAY(lck, char, msg_len);516 frm = talloc_array(d, char, msg_len); 1092 517 if (!frm) { 1093 518 return False; 1094 519 } 1095 520 1096 push_file_id_24(frm, & lck->id);521 push_file_id_24(frm, &id); 1097 522 1098 523 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); 1099 524 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); 1104 534 1105 535 /* 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 1108 540 if (!is_valid_share_mode_entry(se)) { 1109 541 continue; … … 1119 551 1120 552 /* 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)) { 1122 558 continue; 1123 559 } … … 1126 562 "pid %s file_id %s sharepath %s base_name %s " 1127 563 "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 : "")); 1132 568 1133 569 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 } 1135 595 } 1136 596 … … 1162 622 1163 623 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); 1172 625 } 1173 626 … … 1179 632 int num_props = 0; 1180 633 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; 1187 636 } 1188 637 … … 1190 639 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); 1191 640 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 } 1194 646 return (num_props != 0); 1195 647 } 1196 648 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 654 static 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 */ 734 bool 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 794 void 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 810 bool 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 1215 836 ZERO_STRUCTP(e); 1216 e->pid = sconn_server_id(fsp->conn->sconn);837 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx); 1217 838 e->share_access = fsp->share_access; 1218 839 e->private_options = fsp->fh->private_options; … … 1220 841 e->op_mid = mid; 1221 842 e->op_type = op_type; 843 e->lease_idx = lease_idx; 844 e->lease = lease; 1222 845 e->time.tv_sec = fsp->open_time.tv_sec; 1223 846 e->time.tv_usec = fsp->open_time.tv_usec; 1224 847 e->id = fsp->file_id; 1225 848 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; 1228 852 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 857 static 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; 1251 862 int i; 1252 863 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; 1330 882 } 1331 883 return NULL; … … 1339 891 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp) 1340 892 { 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); 1347 896 if (e == NULL) { 1348 897 return False; 1349 898 } 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; 1353 903 return True; 1354 904 } 1355 905 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); 906 bool 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); 1365 923 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; 1371 939 } 1372 940 … … 1377 945 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) 1378 946 { 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); 1385 951 if (e == NULL) { 1386 952 return False; 1387 953 } 1388 954 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; 1404 958 } 1405 959 … … 1410 964 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) 1411 965 { 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); 1418 969 if (e == NULL) { 1419 970 return False; … … 1421 972 1422 973 e->op_type = LEVEL_II_OPLOCK; 1423 lck-> modified = True;974 lck->data->modified = True; 1424 975 return True; 1425 976 } 1426 977 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 { 978 NTSTATUS 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 1433 1011 /* 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 1435 1014 */ 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; 1481 1054 1482 1055 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;1511 1056 } 1512 1057 … … 1515 1060 ****************************************************************************/ 1516 1061 1517 static bool add_delete_on_close_token(struct share_mode_ lock *lck,1062 static bool add_delete_on_close_token(struct share_mode_data *d, 1518 1063 uint32_t name_hash, 1519 1064 const struct security_token *nt_tok, 1520 1065 const struct security_unix_token *tok) 1521 1066 { 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) { 1526 1072 return false; 1527 1073 } 1074 d->delete_tokens = tmp; 1075 dtl = &d->delete_tokens[d->num_delete_tokens]; 1528 1076 1529 1077 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); 1531 1083 if (dtl->delete_token == NULL) { 1532 TALLOC_FREE(dtl);1533 1084 return false; 1534 1085 } 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; 1542 1088 return true; 1089 } 1090 1091 void 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 } 1543 1110 } 1544 1111 … … 1556 1123 void set_delete_on_close_lck(files_struct *fsp, 1557 1124 struct share_mode_lock *lck, 1558 bool delete_on_close,1559 1125 const struct security_token *nt_tok, 1560 1126 const struct security_unix_token *tok) 1561 1127 { 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; 1563 1131 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 1590 1151 return; 1591 1152 } 1592 1153 } 1593 1154 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); 1600 1156 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); 1601 1182 } 1602 1183 … … 1606 1187 { 1607 1188 struct share_mode_lock *lck; 1608 1189 1609 1190 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), 1612 1193 fsp_str_dbg(fsp))); 1613 1194 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); 1616 1196 if (lck == NULL) { 1617 1197 return False; … … 1619 1199 1620 1200 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); 1624 1202 } else { 1625 set_delete_on_close_lck(fsp, lck, false, 1626 NULL, 1627 NULL); 1203 reset_delete_on_close_lck(fsp, lck); 1628 1204 } 1629 1205 … … 1641 1217 } 1642 1218 1219 static 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 1643 1239 /**************************************************************************** 1644 1240 Return the NT token and UNIX token if there's a match. Return true if … … 1647 1243 1648 1244 bool 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; 1672 1258 } 1673 1259 1674 1260 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash) 1675 1261 { 1676 return get_delete_on_close_token(lck, name_hash, NULL, NULL);1262 return find_delete_on_close_token(lck->data, name_hash) != NULL; 1677 1263 } 1678 1264 … … 1686 1272 file_id_string_tos(&fileid))); 1687 1273 1688 lck = get_ share_mode_lock(NULL, fileid, NULL, NULL, NULL);1274 lck = get_existing_share_mode_lock(talloc_tos(), fileid); 1689 1275 if (lck == NULL) { 1690 1276 return False; 1691 1277 } 1692 1278 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; 1696 1282 } 1697 1283 … … 1709 1295 file_id_string_tos(&fileid))); 1710 1296 1711 lck = get_ share_mode_lock(NULL, fileid, NULL, NULL, NULL);1297 lck = get_existing_share_mode_lock(talloc_tos(), fileid); 1712 1298 if (lck == NULL) { 1713 1299 return False; 1714 1300 } 1715 1301 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; 1719 1305 } 1720 1306 … … 1723 1309 } 1724 1310 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 } 1311 struct 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.