関数 | |
static void | check_magic (files_struct *fsp, connection_struct *conn) |
static NTSTATUS | close_filestruct (files_struct *fsp) |
static void | notify_deferred_opens (struct share_mode_lock *lck) |
static NTSTATUS | close_remove_share_mode (files_struct *fsp, enum file_close_type close_type) |
static NTSTATUS | close_normal_file (files_struct *fsp, enum file_close_type close_type) |
static NTSTATUS | close_directory (files_struct *fsp, enum file_close_type close_type) |
NTSTATUS | close_stat (files_struct *fsp) |
NTSTATUS | close_file (files_struct *fsp, enum file_close_type close_type) |
変数 | |
current_user | current_user |
static void check_magic | ( | files_struct * | fsp, | |
connection_struct * | conn | |||
) | [static] |
参照先 current_user::conn・files_struct::fsp_name・smbrun()・strequal()・strrchr_m()・sys_fstat()・transfer_file().
参照元 close_normal_file().
00032 { 00033 if (!*lp_magicscript(SNUM(conn))) 00034 return; 00035 00036 DEBUG(5,("checking magic for %s\n",fsp->fsp_name)); 00037 00038 { 00039 char *p; 00040 if (!(p = strrchr_m(fsp->fsp_name,'/'))) 00041 p = fsp->fsp_name; 00042 else 00043 p++; 00044 00045 if (!strequal(lp_magicscript(SNUM(conn)),p)) 00046 return; 00047 } 00048 00049 { 00050 int ret; 00051 pstring magic_output; 00052 pstring fname; 00053 SMB_STRUCT_STAT st; 00054 int tmp_fd, outfd; 00055 00056 pstrcpy(fname,fsp->fsp_name); 00057 if (*lp_magicoutput(SNUM(conn))) 00058 pstrcpy(magic_output,lp_magicoutput(SNUM(conn))); 00059 else 00060 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname); 00061 00062 chmod(fname,0755); 00063 ret = smbrun(fname,&tmp_fd); 00064 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret)); 00065 unlink(fname); 00066 if (ret != 0 || tmp_fd == -1) { 00067 if (tmp_fd != -1) 00068 close(tmp_fd); 00069 return; 00070 } 00071 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600); 00072 if (outfd == -1) { 00073 close(tmp_fd); 00074 return; 00075 } 00076 00077 if (sys_fstat(tmp_fd,&st) == -1) { 00078 close(tmp_fd); 00079 close(outfd); 00080 return; 00081 } 00082 00083 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size); 00084 close(tmp_fd); 00085 close(outfd); 00086 } 00087 }
static NTSTATUS close_filestruct | ( | files_struct * | fsp | ) | [static] |
参照先 files_struct::conn・current_user::conn・delete_write_cache()・errno・fd_handle::fd・files_struct::fh・flush_write_cache()・map_nt_error_from_unix()・connection_struct::num_files_open・status・files_struct::wbmpx_ptr.
参照元 close_normal_file()・close_stat().
00094 { 00095 NTSTATUS status = NT_STATUS_OK; 00096 connection_struct *conn = fsp->conn; 00097 00098 if (fsp->fh->fd != -1) { 00099 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) { 00100 status = map_nt_error_from_unix(errno); 00101 } 00102 delete_write_cache(fsp); 00103 } 00104 00105 conn->num_files_open--; 00106 SAFE_FREE(fsp->wbmpx_ptr); 00107 return status; 00108 }
static void notify_deferred_opens | ( | struct share_mode_lock * | lck | ) | [static] |
参照先 is_deferred_open_entry()・message_send_pid()・share_mode_lock::num_share_modes・procid_is_me()・schedule_deferred_open_smb_message()・share_mode_entry_to_message()・share_mode_lock::share_modes.
00115 { 00116 int i; 00117 00118 for (i=0; i<lck->num_share_modes; i++) { 00119 struct share_mode_entry *e = &lck->share_modes[i]; 00120 00121 if (!is_deferred_open_entry(e)) { 00122 continue; 00123 } 00124 00125 if (procid_is_me(&e->pid)) { 00126 /* 00127 * We need to notify ourself to retry the open. Do 00128 * this by finding the queued SMB record, moving it to 00129 * the head of the queue and changing the wait time to 00130 * zero. 00131 */ 00132 schedule_deferred_open_smb_message(e->op_mid); 00133 } else { 00134 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 00135 00136 share_mode_entry_to_message(msg, e); 00137 00138 message_send_pid(e->pid, MSG_SMB_OPEN_RETRY, 00139 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 00140 } 00141 } 00142 }
static NTSTATUS close_remove_share_mode | ( | files_struct * | fsp, | |
enum file_close_type | close_type | |||
) | [static] |
参照先 become_user()・files_struct::conn・current_user::conn・current_user・del_share_mode()・share_mode_lock::delete_on_close・share_mode_lock::delete_token・files_struct::dev・files_struct::fsp_name・get_share_mode_lock()・files_struct::initial_delete_on_close・files_struct::inode・is_valid_share_mode_entry()・share_mode_lock::num_share_modes・files_struct::posix_open・set_delete_on_close_lck()・share_mode_lock::share_modes・status・unbecome_user()・current_user::ut・files_struct::vuid・current_user::vuid.
参照元 close_normal_file().
00150 { 00151 connection_struct *conn = fsp->conn; 00152 BOOL delete_file = False; 00153 struct share_mode_lock *lck; 00154 SMB_STRUCT_STAT sbuf; 00155 NTSTATUS status = NT_STATUS_OK; 00156 int ret; 00157 00158 /* 00159 * Lock the share entries, and determine if we should delete 00160 * on close. If so delete whilst the lock is still in effect. 00161 * This prevents race conditions with the file being created. JRA. 00162 */ 00163 00164 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 00165 00166 if (lck == NULL) { 00167 DEBUG(0, ("close_remove_share_mode: Could not get share mode " 00168 "lock for file %s\n", fsp->fsp_name)); 00169 return NT_STATUS_INVALID_PARAMETER; 00170 } 00171 00172 if (!del_share_mode(lck, fsp)) { 00173 DEBUG(0, ("close_remove_share_mode: Could not delete share " 00174 "entry for file %s\n", fsp->fsp_name)); 00175 } 00176 00177 if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { 00178 BOOL became_user = False; 00179 00180 /* Initial delete on close was set and no one else 00181 * wrote a real delete on close. */ 00182 00183 if (current_user.vuid != fsp->vuid) { 00184 become_user(conn, fsp->vuid); 00185 became_user = True; 00186 } 00187 set_delete_on_close_lck(lck, True, ¤t_user.ut); 00188 if (became_user) { 00189 unbecome_user(); 00190 } 00191 } 00192 00193 delete_file = lck->delete_on_close; 00194 00195 if (delete_file) { 00196 int i; 00197 /* See if others still have the file open. If this is the 00198 * case, then don't delete. If all opens are POSIX delete now. */ 00199 for (i=0; i<lck->num_share_modes; i++) { 00200 struct share_mode_entry *e = &lck->share_modes[i]; 00201 if (is_valid_share_mode_entry(e)) { 00202 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { 00203 continue; 00204 } 00205 delete_file = False; 00206 break; 00207 } 00208 } 00209 } 00210 00211 /* Notify any deferred opens waiting on this close. */ 00212 notify_deferred_opens(lck); 00213 reply_to_oplock_break_requests(fsp); 00214 00215 /* 00216 * NT can set delete_on_close of the last open 00217 * reference to a file. 00218 */ 00219 00220 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) 00221 || !delete_file 00222 || (lck->delete_token == NULL)) { 00223 TALLOC_FREE(lck); 00224 return NT_STATUS_OK; 00225 } 00226 00227 /* 00228 * Ok, we have to delete the file 00229 */ 00230 00231 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " 00232 "- deleting file.\n", fsp->fsp_name)); 00233 00234 /* Become the user who requested the delete. */ 00235 00236 if (!push_sec_ctx()) { 00237 smb_panic("close_remove_share_mode: file %s. failed to push " 00238 "sec_ctx.\n"); 00239 } 00240 00241 set_sec_ctx(lck->delete_token->uid, 00242 lck->delete_token->gid, 00243 lck->delete_token->ngroups, 00244 lck->delete_token->groups, 00245 NULL); 00246 00247 /* We can only delete the file if the name we have is still valid and 00248 hasn't been renamed. */ 00249 00250 if (fsp->posix_open) { 00251 ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf); 00252 } else { 00253 ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf); 00254 } 00255 00256 if (ret != 0) { 00257 DEBUG(5,("close_remove_share_mode: file %s. Delete on close " 00258 "was set and stat failed with error %s\n", 00259 fsp->fsp_name, strerror(errno) )); 00260 /* 00261 * Don't save the errno here, we ignore this error 00262 */ 00263 goto done; 00264 } 00265 00266 if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) { 00267 DEBUG(5,("close_remove_share_mode: file %s. Delete on close " 00268 "was set and dev and/or inode does not match\n", 00269 fsp->fsp_name )); 00270 DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, " 00271 "inode = %.0f stat dev = %x, inode = %.0f\n", 00272 fsp->fsp_name, 00273 (unsigned int)fsp->dev, (double)fsp->inode, 00274 (unsigned int)sbuf.st_dev, (double)sbuf.st_ino )); 00275 /* 00276 * Don't save the errno here, we ignore this error 00277 */ 00278 goto done; 00279 } 00280 00281 if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) { 00282 /* 00283 * This call can potentially fail as another smbd may 00284 * have had the file open with delete on close set and 00285 * deleted it when its last reference to this file 00286 * went away. Hence we log this but not at debug level 00287 * zero. 00288 */ 00289 00290 DEBUG(5,("close_remove_share_mode: file %s. Delete on close " 00291 "was set and unlink failed with error %s\n", 00292 fsp->fsp_name, strerror(errno) )); 00293 00294 status = map_nt_error_from_unix(errno); 00295 } 00296 00297 notify_fname(conn, NOTIFY_ACTION_REMOVED, 00298 FILE_NOTIFY_CHANGE_FILE_NAME, 00299 fsp->fsp_name); 00300 00301 /* As we now have POSIX opens which can unlink 00302 * with other open files we may have taken 00303 * this code path with more than one share mode 00304 * entry - ensure we only delete once by resetting 00305 * the delete on close flag. JRA. 00306 */ 00307 00308 set_delete_on_close_lck(lck, False, NULL); 00309 00310 done: 00311 00312 /* unbecome user. */ 00313 pop_sec_ctx(); 00314 00315 TALLOC_FREE(lck); 00316 return status; 00317 }
static NTSTATUS close_normal_file | ( | files_struct * | fsp, | |
enum file_close_type | close_type | |||
) | [static] |
参照先 files_struct::aio_write_behind・cancel_aio_by_fsp()・check_magic()・close_filestruct()・close_remove_share_mode()・files_struct::conn・fd_close()・files_struct::fh・file_free()・files_struct::fsp_name・files_struct::last_write_time・locking_close_file()・map_nt_error_from_unix()・NORMAL_CLOSE・nt_errstr()・null_timespec()・connection_struct::num_files_open・files_struct::oplock_type・files_struct::pending_modtime・files_struct::pending_modtime_owner・files_struct::print_file・print_fsp_end()・fd_handle::ref_count・release_file_oplock()・status・connection_struct::user・wait_for_aio_completion().
参照元 close_file().
00328 { 00329 NTSTATUS status = NT_STATUS_OK; 00330 NTSTATUS saved_status1 = NT_STATUS_OK; 00331 NTSTATUS saved_status2 = NT_STATUS_OK; 00332 NTSTATUS saved_status3 = NT_STATUS_OK; 00333 connection_struct *conn = fsp->conn; 00334 00335 if (fsp->aio_write_behind) { 00336 /* 00337 * If we're finishing write behind on a close we can get a write 00338 * error here, we must remember this. 00339 */ 00340 int ret = wait_for_aio_completion(fsp); 00341 if (ret) { 00342 saved_status1 = map_nt_error_from_unix(ret); 00343 } 00344 } else { 00345 cancel_aio_by_fsp(fsp); 00346 } 00347 00348 /* 00349 * If we're flushing on a close we can get a write 00350 * error here, we must remember this. 00351 */ 00352 00353 saved_status2 = close_filestruct(fsp); 00354 00355 if (fsp->print_file) { 00356 print_fsp_end(fsp, close_type); 00357 file_free(fsp); 00358 return NT_STATUS_OK; 00359 } 00360 00361 /* If this is an old DOS or FCB open and we have multiple opens on 00362 the same handle we only have one share mode. Ensure we only remove 00363 the share mode on the last close. */ 00364 00365 if (fsp->fh->ref_count == 1) { 00366 /* Should we return on error here... ? */ 00367 saved_status3 = close_remove_share_mode(fsp, close_type); 00368 } 00369 00370 if(fsp->oplock_type) { 00371 release_file_oplock(fsp); 00372 } 00373 00374 locking_close_file(fsp); 00375 00376 status = fd_close(conn, fsp); 00377 00378 /* check for magic scripts */ 00379 if (close_type == NORMAL_CLOSE) { 00380 check_magic(fsp,conn); 00381 } 00382 00383 /* 00384 * Ensure pending modtime is set after close. 00385 */ 00386 00387 if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) { 00388 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime); 00389 } else if (!null_timespec(fsp->last_write_time)) { 00390 set_filetime(conn, fsp->fsp_name, fsp->last_write_time); 00391 } 00392 00393 if (NT_STATUS_IS_OK(status)) { 00394 if (!NT_STATUS_IS_OK(saved_status1)) { 00395 status = saved_status1; 00396 } else if (!NT_STATUS_IS_OK(saved_status2)) { 00397 status = saved_status2; 00398 } else if (!NT_STATUS_IS_OK(saved_status3)) { 00399 status = saved_status3; 00400 } 00401 } 00402 00403 DEBUG(2,("%s closed file %s (numopen=%d) %s\n", 00404 conn->user,fsp->fsp_name, 00405 conn->num_files_open, 00406 nt_errstr(status) )); 00407 00408 file_free(fsp); 00409 return status; 00410 }
static NTSTATUS close_directory | ( | files_struct * | fsp, | |
enum file_close_type | close_type | |||
) | [static] |
参照先 become_user()・files_struct::conn・current_user・del_share_mode()・share_mode_lock::delete_on_close・files_struct::dev・files_struct::fsp_name・get_share_mode_lock()・files_struct::initial_delete_on_close・files_struct::inode・is_valid_share_mode_entry()・share_mode_lock::num_share_modes・files_struct::posix_open・send_stat_cache_delete_message()・set_delete_on_close_lck()・share_mode_lock::share_modes・status・unbecome_user()・current_user::ut・files_struct::vuid・current_user::vuid.
参照元 close_file().
00417 { 00418 struct share_mode_lock *lck = 0; 00419 BOOL delete_dir = False; 00420 NTSTATUS status = NT_STATUS_OK; 00421 00422 /* 00423 * NT can set delete_on_close of the last open 00424 * reference to a directory also. 00425 */ 00426 00427 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 00428 00429 if (lck == NULL) { 00430 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name)); 00431 return NT_STATUS_INVALID_PARAMETER; 00432 } 00433 00434 if (!del_share_mode(lck, fsp)) { 00435 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name)); 00436 } 00437 00438 if (fsp->initial_delete_on_close) { 00439 BOOL became_user = False; 00440 00441 /* Initial delete on close was set - for 00442 * directories we don't care if anyone else 00443 * wrote a real delete on close. */ 00444 00445 if (current_user.vuid != fsp->vuid) { 00446 become_user(fsp->conn, fsp->vuid); 00447 became_user = True; 00448 } 00449 send_stat_cache_delete_message(fsp->fsp_name); 00450 set_delete_on_close_lck(lck, True, ¤t_user.ut); 00451 if (became_user) { 00452 unbecome_user(); 00453 } 00454 } 00455 00456 delete_dir = lck->delete_on_close; 00457 00458 if (delete_dir) { 00459 int i; 00460 /* See if others still have the dir open. If this is the 00461 * case, then don't delete. If all opens are POSIX delete now. */ 00462 for (i=0; i<lck->num_share_modes; i++) { 00463 struct share_mode_entry *e = &lck->share_modes[i]; 00464 if (is_valid_share_mode_entry(e)) { 00465 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { 00466 continue; 00467 } 00468 delete_dir = False; 00469 break; 00470 } 00471 } 00472 } 00473 00474 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 00475 delete_dir && 00476 lck->delete_token) { 00477 00478 /* Become the user who requested the delete. */ 00479 00480 if (!push_sec_ctx()) { 00481 smb_panic("close_directory: failed to push sec_ctx.\n"); 00482 } 00483 00484 set_sec_ctx(lck->delete_token->uid, 00485 lck->delete_token->gid, 00486 lck->delete_token->ngroups, 00487 lck->delete_token->groups, 00488 NULL); 00489 00490 TALLOC_FREE(lck); 00491 00492 status = rmdir_internals(fsp->conn, fsp->fsp_name); 00493 00494 DEBUG(5,("close_directory: %s. Delete on close was set - " 00495 "deleting directory returned %s.\n", 00496 fsp->fsp_name, nt_errstr(status))); 00497 00498 /* unbecome user. */ 00499 pop_sec_ctx(); 00500 00501 /* 00502 * Ensure we remove any change notify requests that would 00503 * now fail as the directory has been deleted. 00504 */ 00505 00506 if(NT_STATUS_IS_OK(status)) { 00507 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING); 00508 } 00509 } else { 00510 TALLOC_FREE(lck); 00511 remove_pending_change_notify_requests_by_fid( 00512 fsp, NT_STATUS_OK); 00513 } 00514 00515 /* 00516 * Do the code common to files and directories. 00517 */ 00518 close_filestruct(fsp); 00519 file_free(fsp); 00520 return status; 00521 }
NTSTATUS close_stat | ( | files_struct * | fsp | ) |
参照先 close_filestruct()・file_free().
参照元 close_file().
00528 { 00529 /* 00530 * Do the code common to files and directories. 00531 */ 00532 close_filestruct(fsp); 00533 file_free(fsp); 00534 return NT_STATUS_OK; 00535 }
NTSTATUS close_file | ( | files_struct * | fsp, | |
enum file_close_type | close_type | |||
) |
参照先 close_directory()・close_fake_file()・close_normal_file()・close_stat()・files_struct::fake_file_handle・files_struct::is_directory・files_struct::is_stat.
参照元 _srv_net_file_query_secdesc()・_srv_net_file_set_secdesc()・append_parent_acl()・call_nt_transact_create()・call_trans2open()・can_delete()・can_rename()・conn_get_nt_acl()・copy_file()・copy_internals()・create_directory()・file_close_conn()・file_close_pid()・file_close_user()・file_version_is_newer()・get_correct_cversion()・reply_close()・reply_ntcreate_and_X()・reply_open()・reply_open_and_X()・reply_printclose()・reply_writeclose()・smb_posix_mkdir()・smb_posix_open()・smb_posix_unlink()・smb_set_file_allocation_info()・smb_set_file_size()・user_can_read_file()・user_can_write_file().
00542 { 00543 if(fsp->is_directory) { 00544 return close_directory(fsp, close_type); 00545 } else if (fsp->is_stat) { 00546 return close_stat(fsp); 00547 } else if (fsp->fake_file_handle != NULL) { 00548 return close_fake_file(fsp); 00549 } 00550 return close_normal_file(fsp, close_type); 00551 }
struct current_user current_user |