00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "includes.h"
00040
00041 #undef DBGC_CLASS
00042 #define DBGC_CLASS DBGC_LOCKING
00043
00044 #define NO_LOCKING_COUNT (-1)
00045
00046
00047 static TDB_CONTEXT *tdb;
00048
00049
00050
00051
00052
00053 const char *lock_type_name(enum brl_type lock_type)
00054 {
00055 switch (lock_type) {
00056 case READ_LOCK:
00057 return "READ";
00058 case WRITE_LOCK:
00059 return "WRITE";
00060 case PENDING_READ_LOCK:
00061 return "PENDING_READ";
00062 case PENDING_WRITE_LOCK:
00063 return "PENDING_WRITE";
00064 default:
00065 return "other";
00066 }
00067 }
00068
00069 const char *lock_flav_name(enum brl_flavour lock_flav)
00070 {
00071 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
00072 }
00073
00074
00075
00076
00077
00078
00079 BOOL is_locked(files_struct *fsp,
00080 uint32 smbpid,
00081 SMB_BIG_UINT count,
00082 SMB_BIG_UINT offset,
00083 enum brl_type lock_type)
00084 {
00085 int strict_locking = lp_strict_locking(fsp->conn->params);
00086 enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
00087 BOOL ret = True;
00088
00089 if (count == 0) {
00090 return False;
00091 }
00092
00093 if (!lp_locking(fsp->conn->params) || !strict_locking) {
00094 return False;
00095 }
00096
00097 if (strict_locking == Auto) {
00098 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
00099 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
00100 ret = False;
00101 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
00102 (lock_type == READ_LOCK)) {
00103 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
00104 ret = False;
00105 } else {
00106 struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
00107 if (!br_lck) {
00108 return False;
00109 }
00110 ret = !brl_locktest(br_lck,
00111 smbpid,
00112 procid_self(),
00113 offset,
00114 count,
00115 lock_type,
00116 lock_flav);
00117 TALLOC_FREE(br_lck);
00118 }
00119 } else {
00120 struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
00121 if (!br_lck) {
00122 return False;
00123 }
00124 ret = !brl_locktest(br_lck,
00125 smbpid,
00126 procid_self(),
00127 offset,
00128 count,
00129 lock_type,
00130 lock_flav);
00131 TALLOC_FREE(br_lck);
00132 }
00133
00134 DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
00135 lock_flav_name(lock_flav),
00136 (double)offset, (double)count, ret ? "locked" : "unlocked",
00137 fsp->fnum, fsp->fsp_name ));
00138
00139 return ret;
00140 }
00141
00142
00143
00144
00145
00146 NTSTATUS query_lock(files_struct *fsp,
00147 uint32 *psmbpid,
00148 SMB_BIG_UINT *pcount,
00149 SMB_BIG_UINT *poffset,
00150 enum brl_type *plock_type,
00151 enum brl_flavour lock_flav)
00152 {
00153 struct byte_range_lock *br_lck = NULL;
00154 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
00155
00156 if (!fsp->can_lock) {
00157 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00158 }
00159
00160 if (!lp_locking(fsp->conn->params)) {
00161 return NT_STATUS_OK;
00162 }
00163
00164 br_lck = brl_get_locks_readonly(NULL, fsp);
00165 if (!br_lck) {
00166 return NT_STATUS_NO_MEMORY;
00167 }
00168
00169 status = brl_lockquery(br_lck,
00170 psmbpid,
00171 procid_self(),
00172 poffset,
00173 pcount,
00174 plock_type,
00175 lock_flav);
00176
00177 TALLOC_FREE(br_lck);
00178 return status;
00179 }
00180
00181
00182
00183
00184
00185 struct byte_range_lock *do_lock(files_struct *fsp,
00186 uint32 lock_pid,
00187 SMB_BIG_UINT count,
00188 SMB_BIG_UINT offset,
00189 enum brl_type lock_type,
00190 enum brl_flavour lock_flav,
00191 BOOL blocking_lock,
00192 NTSTATUS *perr,
00193 uint32 *plock_pid)
00194 {
00195 struct byte_range_lock *br_lck = NULL;
00196
00197 if (!fsp->can_lock) {
00198 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00199 return NULL;
00200 }
00201
00202 if (!lp_locking(fsp->conn->params)) {
00203 *perr = NT_STATUS_OK;
00204 return NULL;
00205 }
00206
00207
00208
00209 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
00210 lock_flav_name(lock_flav), lock_type_name(lock_type),
00211 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00212
00213 br_lck = brl_get_locks(NULL, fsp);
00214 if (!br_lck) {
00215 *perr = NT_STATUS_NO_MEMORY;
00216 return NULL;
00217 }
00218
00219 *perr = brl_lock(br_lck,
00220 lock_pid,
00221 procid_self(),
00222 offset,
00223 count,
00224 lock_type,
00225 lock_flav,
00226 blocking_lock,
00227 plock_pid);
00228
00229 if (lock_flav == WINDOWS_LOCK &&
00230 fsp->current_lock_count != NO_LOCKING_COUNT) {
00231
00232
00233
00234
00235 fsp->current_lock_count++;
00236 } else {
00237
00238
00239
00240 fsp->current_lock_count = NO_LOCKING_COUNT;
00241 }
00242
00243 return br_lck;
00244 }
00245
00246
00247
00248
00249
00250 NTSTATUS do_unlock(files_struct *fsp,
00251 uint32 lock_pid,
00252 SMB_BIG_UINT count,
00253 SMB_BIG_UINT offset,
00254 enum brl_flavour lock_flav)
00255 {
00256 BOOL ok = False;
00257 struct byte_range_lock *br_lck = NULL;
00258
00259 if (!fsp->can_lock) {
00260 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00261 }
00262
00263 if (!lp_locking(fsp->conn->params)) {
00264 return NT_STATUS_OK;
00265 }
00266
00267 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
00268 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00269
00270 br_lck = brl_get_locks(NULL, fsp);
00271 if (!br_lck) {
00272 return NT_STATUS_NO_MEMORY;
00273 }
00274
00275 ok = brl_unlock(br_lck,
00276 lock_pid,
00277 procid_self(),
00278 offset,
00279 count,
00280 lock_flav);
00281
00282 TALLOC_FREE(br_lck);
00283
00284 if (!ok) {
00285 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
00286 return NT_STATUS_RANGE_NOT_LOCKED;
00287 }
00288
00289 if (lock_flav == WINDOWS_LOCK &&
00290 fsp->current_lock_count != NO_LOCKING_COUNT) {
00291 SMB_ASSERT(fsp->current_lock_count > 0);
00292 fsp->current_lock_count--;
00293 }
00294
00295 return NT_STATUS_OK;
00296 }
00297
00298
00299
00300
00301
00302 NTSTATUS do_lock_cancel(files_struct *fsp,
00303 uint32 lock_pid,
00304 SMB_BIG_UINT count,
00305 SMB_BIG_UINT offset,
00306 enum brl_flavour lock_flav)
00307 {
00308 BOOL ok = False;
00309 struct byte_range_lock *br_lck = NULL;
00310
00311 if (!fsp->can_lock) {
00312 return fsp->is_directory ?
00313 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00314 }
00315
00316 if (!lp_locking(fsp->conn->params)) {
00317 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
00318 }
00319
00320 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
00321 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00322
00323 br_lck = brl_get_locks(NULL, fsp);
00324 if (!br_lck) {
00325 return NT_STATUS_NO_MEMORY;
00326 }
00327
00328 ok = brl_lock_cancel(br_lck,
00329 lock_pid,
00330 procid_self(),
00331 offset,
00332 count,
00333 lock_flav);
00334
00335 TALLOC_FREE(br_lck);
00336
00337 if (!ok) {
00338 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
00339 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
00340 }
00341
00342 if (lock_flav == WINDOWS_LOCK &&
00343 fsp->current_lock_count != NO_LOCKING_COUNT) {
00344 SMB_ASSERT(fsp->current_lock_count > 0);
00345 fsp->current_lock_count--;
00346 }
00347
00348 return NT_STATUS_OK;
00349 }
00350
00351
00352
00353
00354
00355 void locking_close_file(files_struct *fsp)
00356 {
00357 struct byte_range_lock *br_lck;
00358
00359 if (!lp_locking(fsp->conn->params)) {
00360 return;
00361 }
00362
00363
00364
00365
00366
00367 if (fsp->current_lock_count == 0) {
00368 return;
00369 }
00370
00371 br_lck = brl_get_locks(NULL,fsp);
00372
00373 if (br_lck) {
00374 cancel_pending_lock_requests_by_fid(fsp, br_lck);
00375 brl_close_fnum(br_lck);
00376 TALLOC_FREE(br_lck);
00377 }
00378 }
00379
00380
00381
00382
00383
00384 static int open_read_only;
00385
00386 BOOL locking_init(int read_only)
00387 {
00388 brl_init(read_only);
00389
00390 if (tdb)
00391 return True;
00392
00393 tdb = tdb_open_log(lock_path("locking.tdb"),
00394 lp_open_files_db_hash_size(),
00395 TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
00396 read_only?O_RDONLY:O_RDWR|O_CREAT,
00397 0644);
00398
00399 if (!tdb) {
00400 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
00401 return False;
00402 }
00403
00404
00405 tdb_set_max_dead(tdb, 5);
00406
00407 if (!posix_locking_init(read_only))
00408 return False;
00409
00410 open_read_only = read_only;
00411
00412 return True;
00413 }
00414
00415
00416
00417
00418
00419 BOOL locking_end(void)
00420 {
00421 BOOL ret = True;
00422
00423 brl_shutdown(open_read_only);
00424 if (tdb) {
00425 if (tdb_close(tdb) != 0)
00426 ret = False;
00427 }
00428
00429 return ret;
00430 }
00431
00432
00433
00434
00435
00436
00437 struct locking_key {
00438 SMB_DEV_T dev;
00439 SMB_INO_T ino;
00440 };
00441
00442
00443
00444
00445
00446 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
00447 {
00448 static struct locking_key key;
00449 TDB_DATA kbuf;
00450
00451 memset(&key, '\0', sizeof(key));
00452 key.dev = dev;
00453 key.ino = inode;
00454 kbuf.dptr = (char *)&key;
00455 kbuf.dsize = sizeof(key);
00456 return kbuf;
00457 }
00458
00459
00460
00461
00462
00463 char *share_mode_str(int num, struct share_mode_entry *e)
00464 {
00465 static pstring share_str;
00466
00467 slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s "
00468 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
00469 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
00470 "uid = %u, flags = %u, dev = 0x%x, inode = %.0f",
00471 num,
00472 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
00473 procid_str_static(&e->pid),
00474 e->share_access, e->private_options,
00475 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
00476 (unsigned int)e->uid, (unsigned int)e->flags,
00477 (unsigned int)e->dev, (double)e->inode );
00478
00479 return share_str;
00480 }
00481
00482
00483
00484
00485
00486 static void print_share_mode_table(struct locking_data *data)
00487 {
00488 int num_share_modes = data->u.s.num_share_mode_entries;
00489 struct share_mode_entry *shares =
00490 (struct share_mode_entry *)(data + 1);
00491 int i;
00492
00493 for (i = 0; i < num_share_modes; i++) {
00494 struct share_mode_entry entry;
00495
00496 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
00497 DEBUG(10,("print_share_mode_table: %s\n",
00498 share_mode_str(i, &entry)));
00499 }
00500 }
00501
00502
00503
00504
00505
00506 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
00507 {
00508 struct locking_data *data;
00509 int i;
00510
00511 if (dbuf.dsize < sizeof(struct locking_data)) {
00512 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00513 }
00514
00515 data = (struct locking_data *)dbuf.dptr;
00516
00517 lck->delete_on_close = data->u.s.delete_on_close;
00518 lck->num_share_modes = data->u.s.num_share_mode_entries;
00519
00520 DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
00521 "num_share_modes: %d\n",
00522 lck->delete_on_close,
00523 lck->num_share_modes));
00524
00525 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
00526 DEBUG(0, ("invalid number of share modes: %d\n",
00527 lck->num_share_modes));
00528 smb_panic("PANIC: invalid number of share modes");
00529 }
00530
00531 lck->share_modes = NULL;
00532
00533 if (lck->num_share_modes != 0) {
00534
00535 if (dbuf.dsize < (sizeof(struct locking_data) +
00536 (lck->num_share_modes *
00537 sizeof(struct share_mode_entry)))) {
00538 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00539 }
00540
00541 lck->share_modes = (struct share_mode_entry *)
00542 TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data),
00543 lck->num_share_modes *
00544 sizeof(struct share_mode_entry));
00545
00546 if (lck->share_modes == NULL) {
00547 smb_panic("talloc failed\n");
00548 }
00549 }
00550
00551
00552 if (data->u.s.delete_token_size) {
00553 char *p = dbuf.dptr + sizeof(*data) +
00554 (lck->num_share_modes *
00555 sizeof(struct share_mode_entry));
00556
00557 if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
00558 ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
00559 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
00560 data->u.s.delete_token_size));
00561 smb_panic("parse_share_modes: invalid token size\n");
00562 }
00563
00564 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
00565 if (!lck->delete_token) {
00566 smb_panic("talloc failed\n");
00567 }
00568
00569
00570 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
00571 p += sizeof(uid_t);
00572 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
00573 p += sizeof(gid_t);
00574
00575
00576 lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
00577 ((data->u.s.delete_token_size -
00578 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
00579
00580 if (lck->delete_token->ngroups) {
00581
00582 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
00583 lck->delete_token->ngroups);
00584 if (!lck->delete_token) {
00585 smb_panic("talloc failed\n");
00586 }
00587
00588 for (i = 0; i < lck->delete_token->ngroups; i++) {
00589 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
00590 p += sizeof(gid_t);
00591 }
00592 }
00593
00594 } else {
00595 lck->delete_token = NULL;
00596 }
00597
00598
00599 lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
00600 (lck->num_share_modes *
00601 sizeof(struct share_mode_entry)) +
00602 data->u.s.delete_token_size );
00603 if (lck->servicepath == NULL) {
00604 smb_panic("talloc_strdup failed\n");
00605 }
00606
00607 lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
00608 (lck->num_share_modes *
00609 sizeof(struct share_mode_entry)) +
00610 data->u.s.delete_token_size +
00611 strlen(lck->servicepath) + 1 );
00612 if (lck->filename == NULL) {
00613 smb_panic("talloc_strdup failed\n");
00614 }
00615
00616
00617
00618
00619
00620 for (i = 0; i < lck->num_share_modes; i++) {
00621 struct share_mode_entry *entry_p = &lck->share_modes[i];
00622 DEBUG(10,("parse_share_modes: %s\n",
00623 share_mode_str(i, entry_p) ));
00624 if (!process_exists(entry_p->pid)) {
00625 DEBUG(10,("parse_share_modes: deleted %s\n",
00626 share_mode_str(i, entry_p) ));
00627 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
00628 lck->modified = True;
00629 }
00630 }
00631
00632 return True;
00633 }
00634
00635 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
00636 {
00637 TDB_DATA result;
00638 int num_valid = 0;
00639 int i;
00640 struct locking_data *data;
00641 ssize_t offset;
00642 ssize_t sp_len;
00643 uint32 delete_token_size;
00644
00645 result.dptr = NULL;
00646 result.dsize = 0;
00647
00648 for (i=0; i<lck->num_share_modes; i++) {
00649 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
00650 num_valid += 1;
00651 }
00652 }
00653
00654 if (num_valid == 0) {
00655 return result;
00656 }
00657
00658 sp_len = strlen(lck->servicepath);
00659 delete_token_size = (lck->delete_token ?
00660 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
00661
00662 result.dsize = sizeof(*data) +
00663 lck->num_share_modes * sizeof(struct share_mode_entry) +
00664 delete_token_size +
00665 sp_len + 1 +
00666 strlen(lck->filename) + 1;
00667 result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
00668
00669 if (result.dptr == NULL) {
00670 smb_panic("talloc failed\n");
00671 }
00672
00673 data = (struct locking_data *)result.dptr;
00674 ZERO_STRUCTP(data);
00675 data->u.s.num_share_mode_entries = lck->num_share_modes;
00676 data->u.s.delete_on_close = lck->delete_on_close;
00677 data->u.s.delete_token_size = delete_token_size;
00678 DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
00679 data->u.s.delete_on_close,
00680 (unsigned int)data->u.s.delete_token_size,
00681 data->u.s.num_share_mode_entries));
00682 memcpy(result.dptr + sizeof(*data), lck->share_modes,
00683 sizeof(struct share_mode_entry)*lck->num_share_modes);
00684 offset = sizeof(*data) +
00685 sizeof(struct share_mode_entry)*lck->num_share_modes;
00686
00687
00688 if (lck->delete_token) {
00689 char *p = result.dptr + offset;
00690
00691 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
00692 p += sizeof(uid_t);
00693
00694 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
00695 p += sizeof(gid_t);
00696
00697 for (i = 0; i < lck->delete_token->ngroups; i++) {
00698 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
00699 p += sizeof(gid_t);
00700 }
00701 offset = p - result.dptr;
00702 }
00703
00704 safe_strcpy(result.dptr + offset, lck->servicepath,
00705 result.dsize - offset - 1);
00706 offset += sp_len + 1;
00707 safe_strcpy(result.dptr + offset, lck->filename,
00708 result.dsize - offset - 1);
00709
00710 if (DEBUGLEVEL >= 10) {
00711 print_share_mode_table(data);
00712 }
00713
00714 return result;
00715 }
00716
00717 static int share_mode_lock_destructor(struct share_mode_lock *lck)
00718 {
00719 TDB_DATA key = locking_key(lck->dev, lck->ino);
00720 TDB_DATA data;
00721
00722 if (!lck->modified) {
00723 goto done;
00724 }
00725
00726 data = unparse_share_modes(lck);
00727
00728 if (data.dptr == NULL) {
00729 if (!lck->fresh) {
00730
00731 if (tdb_delete(tdb, key) == -1) {
00732 smb_panic("Could not delete share entry\n");
00733 }
00734 }
00735 goto done;
00736 }
00737
00738 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
00739 smb_panic("Could not store share mode entry\n");
00740 }
00741
00742 done:
00743 tdb_chainunlock(tdb, key);
00744
00745 return 0;
00746 }
00747
00748 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
00749 SMB_DEV_T dev, SMB_INO_T ino,
00750 const char *servicepath,
00751 const char *fname)
00752 {
00753 struct share_mode_lock *lck;
00754 TDB_DATA key = locking_key(dev, ino);
00755 TDB_DATA data;
00756
00757 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
00758 if (lck == NULL) {
00759 DEBUG(0, ("talloc failed\n"));
00760 return NULL;
00761 }
00762
00763
00764
00765
00766 lck->servicepath = NULL;
00767 lck->filename = NULL;
00768 lck->dev = dev;
00769 lck->ino = ino;
00770 lck->num_share_modes = 0;
00771 lck->share_modes = NULL;
00772 lck->delete_token = NULL;
00773 lck->delete_on_close = False;
00774 lck->fresh = False;
00775 lck->modified = False;
00776
00777 if (tdb_chainlock(tdb, key) != 0) {
00778 DEBUG(3, ("Could not lock share entry\n"));
00779 TALLOC_FREE(lck);
00780 return NULL;
00781 }
00782
00783
00784
00785
00786
00787 talloc_set_destructor(lck, share_mode_lock_destructor);
00788
00789 data = tdb_fetch(tdb, key);
00790 lck->fresh = (data.dptr == NULL);
00791
00792 if (lck->fresh) {
00793
00794 if (fname == NULL || servicepath == NULL) {
00795 TALLOC_FREE(lck);
00796 return NULL;
00797 }
00798 lck->filename = talloc_strdup(lck, fname);
00799 lck->servicepath = talloc_strdup(lck, servicepath);
00800 if (lck->filename == NULL || lck->servicepath == NULL) {
00801 DEBUG(0, ("talloc failed\n"));
00802 TALLOC_FREE(lck);
00803 return NULL;
00804 }
00805 } else {
00806 if (!parse_share_modes(data, lck)) {
00807 DEBUG(0, ("Could not parse share modes\n"));
00808 TALLOC_FREE(lck);
00809 SAFE_FREE(data.dptr);
00810 return NULL;
00811 }
00812 }
00813
00814 SAFE_FREE(data.dptr);
00815
00816 return lck;
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826 BOOL rename_share_filename(struct share_mode_lock *lck,
00827 const char *servicepath,
00828 const char *newname)
00829 {
00830 size_t sp_len;
00831 size_t fn_len;
00832 size_t msg_len;
00833 char *frm = NULL;
00834 int i;
00835
00836 if (!lck) {
00837 return False;
00838 }
00839
00840 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
00841 servicepath, newname));
00842
00843
00844
00845
00846
00847 while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
00848 newname += 2;
00849 }
00850
00851 lck->servicepath = talloc_strdup(lck, servicepath);
00852 lck->filename = talloc_strdup(lck, newname);
00853 if (lck->filename == NULL || lck->servicepath == NULL) {
00854 DEBUG(0, ("rename_share_filename: talloc failed\n"));
00855 return False;
00856 }
00857 lck->modified = True;
00858
00859 sp_len = strlen(lck->servicepath);
00860 fn_len = strlen(lck->filename);
00861
00862 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
00863
00864
00865 frm = TALLOC_ARRAY(lck, char, msg_len);
00866 if (!frm) {
00867 return False;
00868 }
00869
00870 SDEV_T_VAL(frm,0,lck->dev);
00871 SINO_T_VAL(frm,8,lck->ino);
00872
00873 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
00874
00875 safe_strcpy(&frm[16], lck->servicepath, sp_len);
00876 safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
00877
00878
00879 for (i=0; i<lck->num_share_modes; i++) {
00880 struct share_mode_entry *se = &lck->share_modes[i];
00881 if (!is_valid_share_mode_entry(se)) {
00882 continue;
00883 }
00884
00885 if (procid_is_me(&se->pid)) {
00886 continue;
00887 }
00888
00889 DEBUG(10,("rename_share_filename: sending rename message to pid %s "
00890 "dev %x, inode %.0f sharepath %s newname %s\n",
00891 procid_str_static(&se->pid),
00892 (unsigned int)lck->dev, (double)lck->ino,
00893 lck->servicepath, lck->filename ));
00894
00895 message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
00896 frm, msg_len, True);
00897 }
00898
00899 return True;
00900 }
00901
00902 static int pull_delete_on_close_flag(TDB_DATA key, TDB_DATA dbuf,
00903 void *private_data)
00904 {
00905 BOOL *result = (BOOL *)private_data;
00906 struct locking_data *data;
00907
00908 if (dbuf.dsize < sizeof(struct locking_data)) {
00909 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00910 }
00911
00912 data = (struct locking_data *)dbuf.dptr;
00913
00914 *result = data->u.s.delete_on_close;
00915 return 0;
00916 }
00917
00918 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
00919 {
00920 TDB_DATA key = locking_key(dev, inode);
00921 BOOL result = False;
00922
00923 tdb_parse_record(tdb, key, pull_delete_on_close_flag,
00924 (void *)&result);
00925 return result;
00926 }
00927
00928 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
00929 {
00930 int num_props = 0;
00931
00932 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
00933
00934
00935
00936
00937 return False;
00938 }
00939
00940 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
00941 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
00942 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
00943
00944 SMB_ASSERT(num_props <= 1);
00945 return (num_props != 0);
00946 }
00947
00948 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
00949 {
00950 return (e->op_type == DEFERRED_OPEN_ENTRY);
00951 }
00952
00953 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
00954 {
00955 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
00956 }
00957
00958
00959
00960
00961
00962 static void fill_share_mode_entry(struct share_mode_entry *e,
00963 files_struct *fsp,
00964 uid_t uid, uint16 mid, uint16 op_type)
00965 {
00966 ZERO_STRUCTP(e);
00967 e->pid = procid_self();
00968 e->share_access = fsp->share_access;
00969 e->private_options = fsp->fh->private_options;
00970 e->access_mask = fsp->access_mask;
00971 e->op_mid = mid;
00972 e->op_type = op_type;
00973 e->time.tv_sec = fsp->open_time.tv_sec;
00974 e->time.tv_usec = fsp->open_time.tv_usec;
00975 e->dev = fsp->dev;
00976 e->inode = fsp->inode;
00977 e->share_file_id = fsp->fh->file_id;
00978 e->uid = (uint32)uid;
00979 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
00980 }
00981
00982 static void fill_deferred_open_entry(struct share_mode_entry *e,
00983 const struct timeval request_time,
00984 SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
00985 {
00986 ZERO_STRUCTP(e);
00987 e->pid = procid_self();
00988 e->op_mid = mid;
00989 e->op_type = DEFERRED_OPEN_ENTRY;
00990 e->time.tv_sec = request_time.tv_sec;
00991 e->time.tv_usec = request_time.tv_usec;
00992 e->dev = dev;
00993 e->inode = ino;
00994 e->uid = (uint32)-1;
00995 e->flags = 0;
00996 }
00997
00998 static void add_share_mode_entry(struct share_mode_lock *lck,
00999 const struct share_mode_entry *entry)
01000 {
01001 int i;
01002
01003 for (i=0; i<lck->num_share_modes; i++) {
01004 struct share_mode_entry *e = &lck->share_modes[i];
01005 if (is_unused_share_mode_entry(e)) {
01006 *e = *entry;
01007 break;
01008 }
01009 }
01010
01011 if (i == lck->num_share_modes) {
01012
01013 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
01014 &lck->share_modes, &lck->num_share_modes);
01015 }
01016 lck->modified = True;
01017 }
01018
01019 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
01020 uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed)
01021 {
01022 struct share_mode_entry entry;
01023 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
01024 if (initial_delete_on_close_allowed) {
01025 entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01026 }
01027 add_share_mode_entry(lck, &entry);
01028 }
01029
01030 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
01031 struct timeval request_time,
01032 SMB_DEV_T dev, SMB_INO_T ino)
01033 {
01034 struct share_mode_entry entry;
01035 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
01036 add_share_mode_entry(lck, &entry);
01037 }
01038
01039
01040
01041
01042
01043
01044
01045 static BOOL share_modes_identical(struct share_mode_entry *e1,
01046 struct share_mode_entry *e2)
01047 {
01048
01049
01050
01051
01052
01053 return (procid_equal(&e1->pid, &e2->pid) &&
01054 e1->dev == e2->dev &&
01055 e1->inode == e2->inode &&
01056 e1->share_file_id == e2->share_file_id );
01057 }
01058
01059 static BOOL deferred_open_identical(struct share_mode_entry *e1,
01060 struct share_mode_entry *e2)
01061 {
01062 return (procid_equal(&e1->pid, &e2->pid) &&
01063 (e1->op_mid == e2->op_mid) &&
01064 (e1->dev == e2->dev) &&
01065 (e1->inode == e2->inode));
01066 }
01067
01068 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
01069 struct share_mode_entry *entry)
01070 {
01071 int i;
01072
01073 for (i=0; i<lck->num_share_modes; i++) {
01074 struct share_mode_entry *e = &lck->share_modes[i];
01075 if (is_valid_share_mode_entry(entry) &&
01076 is_valid_share_mode_entry(e) &&
01077 share_modes_identical(e, entry)) {
01078 return e;
01079 }
01080 if (is_deferred_open_entry(entry) &&
01081 is_deferred_open_entry(e) &&
01082 deferred_open_identical(e, entry)) {
01083 return e;
01084 }
01085 }
01086 return NULL;
01087 }
01088
01089
01090
01091
01092
01093
01094 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
01095 {
01096 struct share_mode_entry entry, *e;
01097
01098
01099 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01100
01101 e = find_share_mode_entry(lck, &entry);
01102 if (e == NULL) {
01103 return False;
01104 }
01105
01106 e->op_type = UNUSED_SHARE_MODE_ENTRY;
01107 lck->modified = True;
01108 return True;
01109 }
01110
01111 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
01112 {
01113 struct share_mode_entry entry, *e;
01114
01115 fill_deferred_open_entry(&entry, timeval_zero(),
01116 lck->dev, lck->ino, mid);
01117
01118 e = find_share_mode_entry(lck, &entry);
01119 if (e == NULL) {
01120 return;
01121 }
01122
01123 e->op_type = UNUSED_SHARE_MODE_ENTRY;
01124 lck->modified = True;
01125 }
01126
01127
01128
01129
01130
01131 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
01132 {
01133 struct share_mode_entry entry, *e;
01134
01135
01136 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01137
01138 e = find_share_mode_entry(lck, &entry);
01139 if (e == NULL) {
01140 return False;
01141 }
01142
01143 e->op_mid = 0;
01144 e->op_type = NO_OPLOCK;
01145 lck->modified = True;
01146 return True;
01147 }
01148
01149
01150
01151
01152
01153 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
01154 {
01155 struct share_mode_entry entry, *e;
01156
01157
01158 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01159
01160 e = find_share_mode_entry(lck, &entry);
01161 if (e == NULL) {
01162 return False;
01163 }
01164
01165 e->op_type = LEVEL_II_OPLOCK;
01166 lck->modified = True;
01167 return True;
01168 }
01169
01170
01171
01172
01173
01174
01175
01176 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
01177 uint32 dosmode)
01178 {
01179 if (!delete_on_close) {
01180 return NT_STATUS_OK;
01181 }
01182
01183
01184
01185
01186
01187 if ((dosmode & aRONLY) &&
01188 !lp_delete_readonly(SNUM(fsp->conn))) {
01189 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
01190 "flag set but file attribute is readonly.\n",
01191 fsp->fsp_name ));
01192 return NT_STATUS_CANNOT_DELETE;
01193 }
01194
01195
01196
01197
01198
01199 if (!CAN_WRITE(fsp->conn)) {
01200 DEBUG(10,("can_set_delete_on_close: file %s delete on "
01201 "close flag set but write access denied on share.\n",
01202 fsp->fsp_name ));
01203 return NT_STATUS_ACCESS_DENIED;
01204 }
01205
01206
01207
01208
01209
01210
01211 if (!(fsp->access_mask & DELETE_ACCESS)) {
01212 DEBUG(10,("can_set_delete_on_close: file %s delete on "
01213 "close flag set but delete access denied.\n",
01214 fsp->fsp_name ));
01215 return NT_STATUS_ACCESS_DENIED;
01216 }
01217
01218
01219 if (fsp->is_directory) {
01220 return can_delete_directory(fsp->conn, fsp->fsp_name);
01221 }
01222
01223 return NT_STATUS_OK;
01224 }
01225
01226
01227
01228
01229
01230 BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck)
01231 {
01232 int i;
01233
01234 for (i=0; i<lck->num_share_modes; i++) {
01235 if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) {
01236 return True;
01237 }
01238 }
01239 return False;
01240 }
01241
01242
01243
01244
01245
01246
01247 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
01248 {
01249 UNIX_USER_TOKEN *cpy;
01250
01251 if (tok == NULL) {
01252 return NULL;
01253 }
01254
01255 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
01256 if (!cpy) {
01257 return NULL;
01258 }
01259
01260 cpy->uid = tok->uid;
01261 cpy->gid = tok->gid;
01262 cpy->ngroups = tok->ngroups;
01263 if (tok->ngroups) {
01264
01265 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
01266 if (!cpy->groups) {
01267 return NULL;
01268 }
01269 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
01270 }
01271 return cpy;
01272 }
01273
01274
01275
01276
01277
01278 void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
01279 {
01280
01281 if (lck->delete_token) {
01282 TALLOC_FREE(lck->delete_token);
01283 lck->delete_token = NULL;
01284 }
01285
01286
01287 lck->delete_token = copy_unix_token(lck, tok);
01288 lck->modified = True;
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302 void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
01303 {
01304 if (lck->delete_on_close != delete_on_close) {
01305 set_delete_on_close_token(lck, tok);
01306 lck->delete_on_close = delete_on_close;
01307 if (delete_on_close) {
01308 SMB_ASSERT(lck->delete_token != NULL);
01309 }
01310 lck->modified = True;
01311 }
01312 }
01313
01314 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
01315 {
01316 struct share_mode_lock *lck;
01317
01318 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
01319 "fnum = %d, file %s\n",
01320 delete_on_close ? "Adding" : "Removing", fsp->fnum,
01321 fsp->fsp_name ));
01322
01323 if (fsp->is_stat) {
01324 return True;
01325 }
01326
01327 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
01328 if (lck == NULL) {
01329 return False;
01330 }
01331
01332 set_delete_on_close_lck(lck, delete_on_close, tok);
01333
01334 if (fsp->is_directory) {
01335 send_stat_cache_delete_message(fsp->fsp_name);
01336 }
01337
01338 TALLOC_FREE(lck);
01339 return True;
01340 }
01341
01342
01343
01344
01345
01346 BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close)
01347 {
01348 struct share_mode_entry entry, *e;
01349
01350
01351 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01352
01353 e = find_share_mode_entry(lck, &entry);
01354 if (e == NULL) {
01355 return False;
01356 }
01357
01358 if (delete_on_close) {
01359 e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01360 } else {
01361 e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01362 }
01363 lck->modified = True;
01364 return True;
01365 }
01366
01367 struct forall_state {
01368 void (*fn)(const struct share_mode_entry *entry,
01369 const char *sharepath,
01370 const char *fname,
01371 void *private_data);
01372 void *private_data;
01373 };
01374
01375 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
01376 void *_state)
01377 {
01378 struct forall_state *state = (struct forall_state *)_state;
01379 struct locking_data *data;
01380 struct share_mode_entry *shares;
01381 const char *sharepath;
01382 const char *fname;
01383 int i;
01384
01385
01386 if (kbuf.dsize != sizeof(struct locking_key))
01387 return 0;
01388
01389 data = (struct locking_data *)dbuf.dptr;
01390 shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
01391 sharepath = dbuf.dptr + sizeof(*data) +
01392 data->u.s.num_share_mode_entries*sizeof(*shares) +
01393 data->u.s.delete_token_size;
01394 fname = dbuf.dptr + sizeof(*data) +
01395 data->u.s.num_share_mode_entries*sizeof(*shares) +
01396 data->u.s.delete_token_size +
01397 strlen(sharepath) + 1;
01398
01399 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
01400 state->fn(&shares[i], sharepath, fname,
01401 state->private_data);
01402 }
01403 return 0;
01404 }
01405
01406
01407
01408
01409
01410
01411 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
01412 const char *, void *),
01413 void *private_data)
01414 {
01415 struct forall_state state;
01416
01417 if (tdb == NULL)
01418 return 0;
01419
01420 state.fn = fn;
01421 state.private_data = private_data;
01422
01423 return tdb_traverse(tdb, traverse_fn, (void *)&state);
01424 }