Changeset 740 for vendor/current/source3/smbd/close.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/close.c
r414 r740 21 21 22 22 #include "includes.h" 23 24 extern struct current_user current_user; 23 #include "system/filesys.h" 24 #include "printing.h" 25 #include "smbd/smbd.h" 26 #include "smbd/globals.h" 27 #include "fake_file.h" 28 #include "transfer_file.h" 29 #include "auth.h" 30 #include "messages.h" 25 31 26 32 /**************************************************************************** … … 154 160 ****************************************************************************/ 155 161 156 static void notify_deferred_opens(struct share_mode_lock *lck) 162 static void notify_deferred_opens(struct messaging_context *msg_ctx, 163 struct share_mode_lock *lck) 157 164 { 158 165 int i; … … 176 183 * zero. 177 184 */ 178 schedule_deferred_open_ smb_message(e->op_mid);185 schedule_deferred_open_message_smb(e->op_mid); 179 186 } else { 180 187 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; … … 182 189 share_mode_entry_to_message(msg, e); 183 190 184 messaging_send_buf(smbd_messaging_context(), 185 e->pid, MSG_SMB_OPEN_RETRY, 191 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY, 186 192 (uint8 *)msg, 187 193 MSG_SMB_SHARE_MODE_ENTRY_SIZE); … … 274 280 NTSTATUS tmp_status; 275 281 struct file_id id; 282 const struct security_unix_token *del_token = NULL; 276 283 277 284 /* Ensure any pending write time updates are done. */ … … 327 334 } 328 335 329 if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { 336 if (fsp->initial_delete_on_close && 337 !is_delete_on_close_set(lck, fsp->name_hash)) { 330 338 bool became_user = False; 331 339 … … 333 341 * wrote a real delete on close. */ 334 342 335 if ( current_user.vuid!= fsp->vuid) {343 if (get_current_vuid(conn) != fsp->vuid) { 336 344 become_user(conn, fsp->vuid); 337 345 became_user = True; 338 346 } 339 347 fsp->delete_on_close = true; 340 set_delete_on_close_lck( lck, True, ¤t_user.ut);348 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn)); 341 349 if (became_user) { 342 350 unbecome_user(); … … 344 352 } 345 353 346 delete_file = lck->delete_on_close;354 delete_file = is_delete_on_close_set(lck, fsp->name_hash); 347 355 348 356 if (delete_file) { 349 357 int i; 350 /* See if others still have the file open. If this is the 351 * case, then don't delete. If all opens are POSIX delete now. */ 358 /* See if others still have the file open via this pathname. 359 If this is the case, then don't delete. If all opens are 360 POSIX delete now. */ 352 361 for (i=0; i<lck->num_share_modes; i++) { 353 362 struct share_mode_entry *e = &lck->share_modes[i]; 354 if (is_valid_share_mode_entry(e)) { 363 if (is_valid_share_mode_entry(e) && 364 e->name_hash == fsp->name_hash) { 355 365 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { 356 366 continue; … … 363 373 364 374 /* Notify any deferred opens waiting on this close. */ 365 notify_deferred_opens( lck);375 notify_deferred_opens(conn->sconn->msg_ctx, lck); 366 376 reply_to_oplock_break_requests(fsp); 367 377 … … 371 381 */ 372 382 373 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) 374 || !delete_file 375 || (lck->delete_token == NULL)) { 383 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) || 384 !delete_file) { 376 385 TALLOC_FREE(lck); 377 386 return NT_STATUS_OK; … … 390 399 fsp->update_write_time_on_close = false; 391 400 392 if (!unix_token_equal(lck->delete_token, ¤t_user.ut)) { 401 del_token = get_delete_on_close_token(lck, fsp->name_hash); 402 SMB_ASSERT(del_token != NULL); 403 404 if (!unix_token_equal(del_token, get_current_utok(conn))) { 393 405 /* Become the user who requested the delete. */ 394 406 … … 396 408 "Change user to uid %u\n", 397 409 fsp_str_dbg(fsp), 398 (unsigned int) lck->delete_token->uid));410 (unsigned int)del_token->uid)); 399 411 400 412 if (!push_sec_ctx()) { … … 403 415 } 404 416 405 set_sec_ctx( lck->delete_token->uid,406 lck->delete_token->gid,407 lck->delete_token->ngroups,408 lck->delete_token->groups,417 set_sec_ctx(del_token->uid, 418 del_token->gid, 419 del_token->ngroups, 420 del_token->groups, 409 421 NULL); 410 422 … … 472 484 } 473 485 474 notify_fname(conn, NOTIFY_ACTION_REMOVED,475 FILE_NOTIFY_CHANGE_FILE_NAME,476 fsp->fsp_name->base_name);477 478 486 /* As we now have POSIX opens which can unlink 479 487 * with other open files we may have taken … … 484 492 485 493 fsp->delete_on_close = false; 486 set_delete_on_close_lck( lck, False, NULL);494 set_delete_on_close_lck(fsp, lck, false, NULL); 487 495 488 496 done: … … 494 502 495 503 TALLOC_FREE(lck); 504 505 if (delete_file) { 506 /* 507 * Do the notification after we released the share 508 * mode lock. Inside notify_fname we take out another 509 * tdb lock. With ctdb also accessing our databases, 510 * this can lead to deadlocks. Putting this notify 511 * after the TALLOC_FREE(lck) above we avoid locking 512 * two records simultaneously. Notifies are async and 513 * informational only, so calling the notify_fname 514 * without holding the share mode lock should not do 515 * any harm. 516 */ 517 notify_fname(conn, NOTIFY_ACTION_REMOVED, 518 FILE_NOTIFY_CHANGE_FILE_NAME, 519 fsp->fsp_name->base_name); 520 } 521 496 522 return status; 497 523 } … … 551 577 552 578 ft.mtime = fsp->close_write_time; 553 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false); 579 /* We must use NULL for the fsp handle here, as smb_set_file_time() 580 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES. 581 As this is a close based update, we are not directly changing the 582 file attributes from a client call, but indirectly from a write. */ 583 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false); 554 584 if (!NT_STATUS_IS_OK(status)) { 585 DEBUG(10,("update_write_time_on_close: smb_set_file_time " 586 "on file %s returned %s\n", 587 fsp_str_dbg(fsp), 588 nt_errstr(status))); 555 589 return status; 556 590 } … … 582 616 connection_struct *conn = fsp->conn; 583 617 584 if (fsp->aio_write_behind) { 618 if (close_type == ERROR_CLOSE) { 619 cancel_aio_by_fsp(fsp); 620 } else { 585 621 /* 586 * If we're finishing write behindon a close we can get a write622 * If we're finishing async io on a close we can get a write 587 623 * error here, we must remember this. 588 624 */ … … 592 628 status, map_nt_error_from_unix(ret)); 593 629 } 594 } else { 595 cancel_aio_by_fsp(fsp); 596 } 597 630 } 631 598 632 /* 599 633 * If we're flushing on a close we can get a write … … 605 639 606 640 if (fsp->print_file) { 607 print_fsp_end(fsp, close_type); 641 /* FIXME: return spool errors */ 642 print_spool_end(fsp, close_type); 608 643 file_free(req, fsp); 609 644 return NT_STATUS_OK; … … 625 660 } 626 661 627 locking_close_file( smbd_messaging_context(), fsp);662 locking_close_file(conn->sconn->msg_ctx, fsp, close_type); 628 663 629 664 tmp = fd_close(fsp); … … 652 687 653 688 DEBUG(2,("%s closed file %s (numopen=%d) %s\n", 654 conn->se rver_info->unix_name, fsp_str_dbg(fsp),689 conn->session_info->unix_name, fsp_str_dbg(fsp), 655 690 conn->num_files_open - 1, 656 691 nt_errstr(status) )); … … 928 963 NTSTATUS status = NT_STATUS_OK; 929 964 NTSTATUS status1 = NT_STATUS_OK; 965 const struct security_unix_token *del_token = NULL; 930 966 931 967 /* … … 956 992 * wrote a real delete on close. */ 957 993 958 if ( current_user.vuid!= fsp->vuid) {994 if (get_current_vuid(fsp->conn) != fsp->vuid) { 959 995 become_user(fsp->conn, fsp->vuid); 960 996 became_user = True; 961 997 } 962 send_stat_cache_delete_message(fsp->fsp_name->base_name); 963 set_delete_on_close_lck(lck, True, ¤t_user.ut); 998 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx, 999 fsp->fsp_name->base_name); 1000 set_delete_on_close_lck(fsp, lck, true, 1001 get_current_utok(fsp->conn)); 964 1002 fsp->delete_on_close = true; 965 1003 if (became_user) { … … 968 1006 } 969 1007 970 delete_dir = lck->delete_on_close; 1008 del_token = get_delete_on_close_token(lck, fsp->name_hash); 1009 delete_dir = (del_token != NULL); 971 1010 972 1011 if (delete_dir) { … … 976 1015 for (i=0; i<lck->num_share_modes; i++) { 977 1016 struct share_mode_entry *e = &lck->share_modes[i]; 978 if (is_valid_share_mode_entry(e)) { 1017 if (is_valid_share_mode_entry(e) && 1018 e->name_hash == fsp->name_hash) { 979 1019 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { 980 1020 continue; … … 987 1027 988 1028 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 989 delete_dir && 990 lck->delete_token) { 1029 delete_dir) { 991 1030 992 1031 /* Become the user who requested the delete. */ … … 996 1035 } 997 1036 998 set_sec_ctx( lck->delete_token->uid,999 lck->delete_token->gid,1000 lck->delete_token->ngroups,1001 lck->delete_token->groups,1037 set_sec_ctx(del_token->uid, 1038 del_token->gid, 1039 del_token->ngroups, 1040 del_token->groups, 1002 1041 NULL); 1003 1042 … … 1033 1072 fsp_str_dbg(fsp), fsp->fh->fd, errno, 1034 1073 strerror(errno))); 1035 }1036 1037 if (fsp->dptr) {1038 dptr_CloseDir(fsp->dptr);1039 1074 } 1040 1075 … … 1100 1135 DATA_BLOB *data) 1101 1136 { 1137 struct smbd_server_connection *sconn; 1102 1138 files_struct *fsp = NULL; 1103 1139 struct share_mode_entry e; 1140 1141 sconn = msg_ctx_to_sconn(msg_ctx); 1142 if (sconn == NULL) { 1143 DEBUG(1, ("could not find sconn\n")); 1144 return; 1145 } 1104 1146 1105 1147 message_to_share_mode_entry(&e, (char *)data->data); … … 1115 1157 } 1116 1158 1117 fsp = file_find_dif( e.id, e.share_file_id);1159 fsp = file_find_dif(sconn, e.id, e.share_file_id); 1118 1160 if (!fsp) { 1119 1161 DEBUG(10,("msg_close_file: failed to find file.\n"));
Note:
See TracChangeset
for help on using the changeset viewer.