root/source3/locking/locking.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lock_type_name
  2. lock_flav_name
  3. init_strict_lock_struct
  4. strict_lock_default
  5. strict_unlock_default
  6. query_lock
  7. increment_current_lock_count
  8. decrement_current_lock_count
  9. do_lock
  10. do_unlock
  11. do_lock_cancel
  12. locking_close_file
  13. locking_init_internal
  14. locking_init
  15. locking_init_readonly
  16. locking_end
  17. locking_key
  18. share_mode_str
  19. print_share_mode_table
  20. parse_share_modes
  21. unparse_share_modes
  22. share_mode_lock_destructor
  23. fill_share_mode_lock
  24. get_share_mode_lock
  25. fetch_share_mode_unlocked
  26. rename_share_filename
  27. get_file_infos
  28. is_valid_share_mode_entry
  29. is_deferred_open_entry
  30. is_unused_share_mode_entry
  31. fill_share_mode_entry
  32. fill_deferred_open_entry
  33. add_share_mode_entry
  34. set_share_mode
  35. add_deferred_open
  36. share_modes_identical
  37. deferred_open_identical
  38. find_share_mode_entry
  39. del_share_mode
  40. del_deferred_open_entry
  41. remove_share_oplock
  42. downgrade_share_oplock
  43. can_set_delete_on_close
  44. copy_unix_token
  45. set_delete_on_close_token
  46. set_delete_on_close_lck
  47. set_delete_on_close
  48. set_sticky_write_time
  49. set_write_time
  50. traverse_fn
  51. share_mode_forall

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

/* [<][>][^][v][top][bottom][index][help] */