smbd/close.c

ソースコードを見る。

関数

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]

close.c31 行で定義されています。

参照先 current_user::connfiles_struct::fsp_namesmbrun()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]

close.c93 行で定義されています。

参照先 files_struct::conncurrent_user::conndelete_write_cache()errnofd_handle::fdfiles_struct::fhflush_write_cache()map_nt_error_from_unix()connection_struct::num_files_openstatusfiles_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]

close.c114 行で定義されています。

参照先 is_deferred_open_entry()message_send_pid()share_mode_lock::num_share_modesprocid_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]

close.c148 行で定義されています。

参照先 become_user()files_struct::conncurrent_user::conncurrent_userdel_share_mode()share_mode_lock::delete_on_closeshare_mode_lock::delete_tokenfiles_struct::devfiles_struct::fsp_nameget_share_mode_lock()files_struct::initial_delete_on_closefiles_struct::inodeis_valid_share_mode_entry()share_mode_lock::num_share_modesfiles_struct::posix_openset_delete_on_close_lck()share_mode_lock::share_modesstatusunbecome_user()current_user::utfiles_struct::vuidcurrent_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, &current_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]

close.c327 行で定義されています。

参照先 files_struct::aio_write_behindcancel_aio_by_fsp()check_magic()close_filestruct()close_remove_share_mode()files_struct::connfd_close()files_struct::fhfile_free()files_struct::fsp_namefiles_struct::last_write_timelocking_close_file()map_nt_error_from_unix()NORMAL_CLOSEnt_errstr()null_timespec()connection_struct::num_files_openfiles_struct::oplock_typefiles_struct::pending_modtimefiles_struct::pending_modtime_ownerfiles_struct::print_fileprint_fsp_end()fd_handle::ref_countrelease_file_oplock()statusconnection_struct::userwait_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]

close.c416 行で定義されています。

参照先 become_user()files_struct::conncurrent_userdel_share_mode()share_mode_lock::delete_on_closefiles_struct::devfiles_struct::fsp_nameget_share_mode_lock()files_struct::initial_delete_on_closefiles_struct::inodeis_valid_share_mode_entry()share_mode_lock::num_share_modesfiles_struct::posix_opensend_stat_cache_delete_message()set_delete_on_close_lck()share_mode_lock::share_modesstatusunbecome_user()current_user::utfiles_struct::vuidcurrent_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, &current_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.c527 行で定義されています。

参照先 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.c541 行で定義されています。

参照先 close_directory()close_fake_file()close_normal_file()close_stat()files_struct::fake_file_handlefiles_struct::is_directoryfiles_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

smbrun.c24 行で定義されています。


Sambaに対してSat Aug 29 21:24:25 2009に生成されました。  doxygen 1.4.7