From 16bb009dbbe6302febf3848cee61e9927eeb0fb5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 05:17:25 +0000 Subject: Mega-VFS merge. Yeah baby! Synopsis: change every disk access function to work through a vfs_ops structure contained in the connection_struct. (This used to be commit 3aad500c0fb61232ed3431ff4b743b5d18ec852f) --- source3/smbd/close.c | 7 ++- source3/smbd/dir.c | 13 ++---- source3/smbd/dosmode.c | 10 ++-- source3/smbd/fileio.c | 11 +++-- source3/smbd/filename.c | 14 +++--- source3/smbd/files.c | 2 +- source3/smbd/ipc.c | 2 +- source3/smbd/nttrans.c | 25 +++++----- source3/smbd/open.c | 71 ++++++++++++++-------------- source3/smbd/predict.c | 10 ++-- source3/smbd/reply.c | 120 +++++++++++++++++++++++++----------------------- source3/smbd/server.c | 4 +- source3/smbd/service.c | 92 ++++++++++++++++++++++++++++++++++++- source3/smbd/trans2.c | 38 ++++++++------- 14 files changed, 261 insertions(+), 158 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 7f5769b368..8e2ed0de0e 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -117,10 +117,10 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) locking_close_file(fsp); - if(fd_attempt_close(fsp->fd_ptr,&err) == 0) + if(fd_attempt_close(fsp, &err) == 0) last_reference = True; - fsp->fd_ptr = NULL; + fsp->fd_ptr = NULL; if (lp_share_modes(SNUM(conn))) unlock_share_entry(conn, dev, inode); @@ -142,8 +142,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) if (normal_close && last_reference && delete_on_close) { DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); - if(dos_unlink(fsp->fsp_name) != 0) { - + if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) { /* * This call can potentially fail as another smbd may have * had the file open with delete on close set and deleted diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f3f261f0b2..32fc523541 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -617,14 +617,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (dos_stat(pathreal,&sbuf) != 0) + if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; } - - if (check_descend && !strequal(fname,".") && !strequal(fname,"..")) - continue; *mode = dos_mode(conn,pathreal,&sbuf); @@ -673,19 +670,19 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = dos_opendir(name); + DIR *p = conn->vfs_ops.opendir(name); int used=0; if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { - closedir(p); + conn->vfs_ops.closedir(p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = dos_readdirname(p))) + while ((n = vfs_readdirname(conn, p))) { int l = strlen(n)+1; @@ -709,7 +706,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->numentries++; } - closedir(p); + conn->vfs_ops.closedir(p); return((void *)dirp); } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9690f115c4..1ae1e7e2cb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -189,7 +189,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (!st) { st = &st1; - if (dos_stat(fname,st)) return(-1); + if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -225,7 +225,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - return(dos_chmod(fname,unixmode)); + return(conn->vfs_ops.chmod(fname,unixmode)); } @@ -241,7 +241,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(dos_utime(fname, times) == 0) + if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -256,7 +256,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(dos_stat(fname,&sb) != 0) + if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0) return -1; /* Check if we have write access. */ @@ -269,7 +269,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(False); - ret = dos_utime(fname, times); + ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); unbecome_root(False); } } diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index fa04e671f8..348486d430 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -37,7 +37,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); /* * We want to maintain the fiction that we can seek @@ -120,7 +120,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } if (n > 0) { - readret = read(fsp->fd_ptr->fd,data,n); + readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n); if (readret > 0) ret += readret; } @@ -173,7 +173,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -644,16 +644,17 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) return real_write_file(fsp, wcp->data, wcp->offset, data_size); } + /******************************************************************* sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp) +void sys_fsync_file(connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) { flush_write_cache(fsp, SYNC_FLUSH); - fsync(fsp->fd_ptr->fd); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); } #endif } diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 2f8e92d98e..b1550e5c73 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -239,7 +239,8 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path) Return True if we translated (and did a scuccessful stat on) the entire name. *****************************************************************************/ -static BOOL stat_cache_lookup( char *name, char *dirpath, char **start, SMB_STRUCT_STAT *pst) +static BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath, + char **start, SMB_STRUCT_STAT *pst) { stat_cache_entry *scp; stat_cache_entry *longest_hit = NULL; @@ -294,7 +295,7 @@ static BOOL stat_cache_lookup( char *name, char *dirpath, char **start, SMB_STRU scp = (stat_cache_entry *)(hash_elem->value); global_stat_cache_hits++; trans_name = scp->names+scp->name_len+1; - if(dos_stat( trans_name, pst) != 0) { + if(conn->vfs_ops.stat(dos_to_unix(trans_name,False), pst) != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ hash_remove(&stat_cache, hash_elem); return False; @@ -433,7 +434,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, pstrcpy(orig_path, name); - if(stat_cache_lookup( name, dirpath, &start, &st)) { + if(stat_cache_lookup(conn, name, dirpath, &start, &st)) { if(pst) *pst = st; return True; @@ -443,7 +444,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, * stat the name - if it exists then we are all done! */ - if (dos_stat(name,&st) == 0) { + if (conn->vfs_ops.stat(name,&st) == 0) { stat_cache_add(orig_path, name); DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); if(pst) @@ -509,7 +510,8 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, /* * Check if the name exists up to this point. */ - if (dos_stat(name, &st) == 0) { + + if (conn->vfs_ops.stat(name, &st) == 0) { /* * It exists. it must either be a directory or this must be * the last part of the path for it to be OK. @@ -661,7 +663,7 @@ BOOL check_name(char *name,connection_struct *conn) if (!lp_symlinks(SNUM(conn))) { SMB_STRUCT_STAT statbuf; - if ( (dos_lstat(name,&statbuf) != -1) && + if ( (conn->vfs_ops.lstat(dos_to_unix(name,False),&statbuf) != -1) && (S_ISLNK(statbuf.st_mode)) ) { DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name)); diff --git a/source3/smbd/files.c b/source3/smbd/files.c index dd1f7037f6..d62950c568 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -335,7 +335,7 @@ void file_sync_all(connection_struct *conn) for (fsp=Files;fsp;fsp=next) { next=fsp->next; if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)) { - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); } } } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 737b364c6b..3e16dba4f5 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -2073,7 +2073,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha !become_service(fconn,True)) break; - if (dos_rename(fsp->fsp_name,name) == 0) { + if (fsp->conn->vfs_ops.rename(fsp->fsp_name,name) == 0) { string_set(&fsp->fsp_name,name); } break; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index f4015d50df..4b344c3318 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -842,13 +842,15 @@ int reply_ntcreate_and_X(connection_struct *conn, } if(fsp->is_directory) { - if(dos_stat(fsp->fsp_name, &sbuf) != 0) { + if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), + &sbuf) != 0) { close_file(fsp,True); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } } else { - if (!fsp->stat_open && sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) + != 0) { close_file(fsp,False); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); @@ -1096,7 +1098,8 @@ static int call_nt_transact_create(connection_struct *conn, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if(dos_stat(fsp->fsp_name, &sbuf) != 0) { + if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), + &sbuf) != 0) { close_file(fsp,True); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); @@ -1169,13 +1172,13 @@ static int call_nt_transact_create(connection_struct *conn, } if(fsp->is_directory) { - if(dos_stat(fsp->fsp_name, &sbuf) != 0) { + if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) { close_file(fsp,True); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } } else { - if (!fsp->stat_open && sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (!fsp->stat_open && conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { close_file(fsp,False); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); @@ -1790,7 +1793,7 @@ static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) return 0; } } else { - if(sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { return 0; } } @@ -2288,9 +2291,9 @@ security descriptor.\n")); int ret; if(fsp->fd_ptr == NULL) - ret = dos_stat(fsp->fsp_name, &sbuf); + ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf); else - ret = sys_fstat(fsp->fd_ptr->fd,&sbuf); + ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf); if(ret != 0) { return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2326,9 +2329,9 @@ security descriptor.\n")); int ret; if(fsp->fd_ptr == NULL) - ret = dos_stat(fsp->fsp_name, &sbuf); + ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf); else - ret = sys_fstat(fsp->fd_ptr->fd,&sbuf); + ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf); if(ret != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2374,7 +2377,7 @@ security descriptor.\n")); DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n", fsp->fsp_name, (unsigned int)perms )); - if(dos_chmod( fsp->fsp_name, perms) == -1) { + if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) { DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n", fsp->fsp_name, (unsigned int)perms, strerror(errno) )); return(UNIXERROR(ERRDOS,ERRnoaccess)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 57fbdb24c4..1b4179da33 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -30,17 +30,17 @@ extern BOOL global_client_failed_oplock_break; /**************************************************************************** fd support routines - attempt to do a dos_open ****************************************************************************/ - -static int fd_attempt_open(char *fname, int flags, mode_t mode) +static int fd_attempt_open(struct connection_struct *conn, char *fname, + int flags, mode_t mode) { - int fd = dos_open(fname,flags,mode); + int fd = conn->vfs_ops.open(fname,flags,mode); /* Fix for files ending in '.' */ if((fd == -1) && (errno == ENOENT) && (strchr(fname,'.')==NULL)) { pstrcat(fname,"."); - fd = dos_open(fname,flags,mode); + fd = conn->vfs_ops.open(fname,flags,mode); } #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF)) @@ -71,7 +71,7 @@ static int fd_attempt_open(char *fname, int flags, mode_t mode) char tmp = p[max_len]; p[max_len] = '\0'; - if ((fd = dos_open(fname,flags,mode)) == -1) + if ((fd = conn->vfs_ops.open(fname,flags,mode)) == -1) p[max_len] = tmp; } } @@ -128,9 +128,10 @@ fd support routines - attempt to re-open an already open fd as O_RDWR. Save the already open fd (we cannot close due to POSIX file locking braindamage. ****************************************************************************/ -static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr) +static void fd_attempt_reopen(char *fname, mode_t mode, files_struct *fsp) { - int fd = dos_open( fname, O_RDWR, mode); + int fd = fsp->conn->vfs_ops.open(dos_to_unix(fname, False), O_RDWR, mode); + file_fd_struct *fd_ptr = fsp->fd_ptr; if(fd == -1) return; @@ -148,10 +149,10 @@ static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr) fd support routines - attempt to close the file referenced by this fd. Decrements the ref_count and returns it. ****************************************************************************/ - -uint16 fd_attempt_close(file_fd_struct *fd_ptr, int *err_ret) +uint16 fd_attempt_close(files_struct *fsp, int *err_ret) { extern struct current_user current_user; + file_fd_struct *fd_ptr = fsp->fd_ptr; uint16 ret_ref = fd_ptr->ref_count; *err_ret = 0; @@ -169,19 +170,19 @@ uint16 fd_attempt_close(file_fd_struct *fd_ptr, int *err_ret) if(fd_ptr->ref_count == 0) { if(fd_ptr->fd != -1) { - if(close(fd_ptr->fd) < 0) + if(fsp->conn->vfs_ops.close(fd_ptr->fd) < 0) *err_ret = errno; } if(fd_ptr->fd_readonly != -1) { - if(close(fd_ptr->fd_readonly) < 0) { + if(fsp->conn->vfs_ops.close(fd_ptr->fd_readonly) < 0) { if(*err_ret == 0) *err_ret = errno; } } if(fd_ptr->fd_writeonly != -1) { - if( close(fd_ptr->fd_writeonly) < 0) { + if(fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly) < 0) { if(*err_ret == 0) *err_ret = errno; } @@ -205,8 +206,9 @@ This is really ugly code, as due to POSIX locking braindamage we must fork and then attempt to open the file, and return success or failure via an exit code. ****************************************************************************/ - -static BOOL check_access_allowed_for_current_user( char *fname, int accmode ) +static BOOL check_access_allowed_for_current_user(struct connection_struct + *conn, char *fname, + int accmode ) { pid_t child_pid; @@ -277,11 +279,11 @@ is no longer waiting ! Error = %s\n", strerror(errno) )); */ int fd; DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode )); - if((fd = fd_attempt_open( fname, accmode, 0)) < 0) { + if((fd = fd_attempt_open(conn, fname, accmode, 0)) < 0) { /* Access denied. */ _exit(EACCES); } - close(fd); + conn->vfs_ops.close(fd); DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n")); _exit(0); } @@ -369,7 +371,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, * open fd table. */ if(sbuf == 0) { - if(dos_stat(fname, &statbuf) < 0) { + if(conn->vfs_ops.stat(dos_to_unix(fname,False), &statbuf) < 0) { if(errno != ENOENT) { DEBUG(3,("Error doing stat on file %s (%s)\n", fname,strerror(errno))); @@ -410,7 +412,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, */ if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) { - if(!check_access_allowed_for_current_user( fname, accmode )) { + if(!check_access_allowed_for_current_user(conn, fname, accmode )) { /* Error - permission denied. */ DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n", fname, flags, accmode)); @@ -430,7 +432,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, * between the last open and now. */ if(fd_ptr->real_open_flags != O_RDWR) - fd_attempt_reopen(fname, mode, fd_ptr); + fd_attempt_reopen(fname, mode, fsp); /* * Ensure that if we wanted write access @@ -467,7 +469,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, fd_ptr->real_open_flags = O_RDWR; /* Set the flags as needed without the read/write modes. */ open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY); - fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode); + fd_ptr->fd = fd_attempt_open(conn, fname, open_flags|O_RDWR, mode); /* * On some systems opening a file for R/W access on a read only * filesystems sets errno to EROFS. @@ -478,7 +480,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, if((fd_ptr->fd == -1) && (errno == EACCES)) { #endif /* EROFS */ if(accmode != O_RDWR) { - fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode); + fd_ptr->fd = fd_attempt_open(conn, fname, open_flags|accmode, mode); fd_ptr->real_open_flags = accmode; } } @@ -492,10 +494,11 @@ static void open_file(files_struct *fsp,connection_struct *conn, pstrcpy(dname,fname); p = strrchr(dname,'/'); if (p) *p = 0; - if (sys_disk_free(dname,False,&dum1,&dum2,&dum3) < (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) { + if (conn->vfs_ops.disk_free(dname,False,&dum1,&dum2,&dum3) < + (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) { int err; - if(fd_attempt_close(fd_ptr, &err) == 0) - dos_unlink(fname); + if(fd_attempt_close(fsp, &err) == 0) + conn->vfs_ops.unlink(dos_to_unix(fname, False)); fsp->fd_ptr = 0; errno = ENOSPC; return; @@ -508,7 +511,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, DEBUG(3,("Error opening file %s (%s) (flags=%d)\n", fname,strerror(errno),flags)); /* Ensure the ref_count is decremented. */ - fd_attempt_close(fd_ptr,&err); + fd_attempt_close(fsp,&err); check_for_pipe(fname); return; } @@ -517,13 +520,13 @@ static void open_file(files_struct *fsp,connection_struct *conn, { if(sbuf == 0) { /* Do the fstat */ - if(sys_fstat(fd_ptr->fd, &statbuf) == -1) { - int err; + if(conn->vfs_ops.fstat(fd_ptr->fd, &statbuf) == -1) { + int err; /* Error - backout !! */ DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n", fd_ptr->fd, fname,strerror(errno))); /* Ensure the ref_count is decremented. */ - fd_attempt_close(fd_ptr,&err); + fd_attempt_close(fsp,&err); return; } sbuf = &statbuf; @@ -573,7 +576,7 @@ static void open_file(files_struct *fsp,connection_struct *conn, */ if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) { DEBUG(3,("Writing postscript line\n")); - write_file(fsp,"%!\n",-1,3); + conn->vfs_ops.write(fsp->fd_ptr->fd,"%!\n",3); } DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -794,7 +797,7 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int int deny_mode = GET_DENY_MODE(share_mode); BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode); SMB_STRUCT_STAT sbuf; - BOOL file_existed = dos_file_exist(fname,&sbuf); + BOOL file_existed = vfs_file_exist(conn, dos_to_unix(fname,False), &sbuf); BOOL share_locked = False; BOOL fcbopen = False; int token = 0; @@ -1093,7 +1096,7 @@ int open_file_stat(files_struct *fsp,connection_struct *conn, { extern struct current_user current_user; - if(dos_stat(fname, pst) < 0) { + if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) { DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n", fname, strerror(errno) )); return -1; @@ -1157,7 +1160,7 @@ int open_directory(files_struct *fsp,connection_struct *conn, SMB_STRUCT_STAT st; BOOL got_stat = False; - if(dos_stat(fname, &st) == 0) { + if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) { got_stat = True; } @@ -1189,7 +1192,7 @@ int open_directory(files_struct *fsp,connection_struct *conn, return -1; } - if(dos_mkdir(fname, unix_mode(conn,aDIR, fname)) < 0) { + if(conn->vfs_ops.mkdir(dos_to_unix(fname, False), unix_mode(conn,aDIR, fname)) < 0) { DEBUG(0,("open_directory: unable to create %s. Error was %s\n", fname, strerror(errno) )); return -1; @@ -1275,7 +1278,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op) if(!lp_share_modes(SNUM(conn))) return True; - if (dos_stat(fname,&sbuf) == -1) return(True); + if (conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf) == -1) return(True); dev = sbuf.st_dev; inode = sbuf.st_ino; diff --git a/source3/smbd/predict.c b/source3/smbd/predict.c index de85a4a553..34044b82f2 100644 --- a/source3/smbd/predict.c +++ b/source3/smbd/predict.c @@ -42,7 +42,7 @@ extern struct timeval smb_last_time; /**************************************************************************** handle read prediction on a file ****************************************************************************/ -ssize_t read_predict(int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num) +ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num) { ssize_t ret = 0; ssize_t possible = rp_length - (offset - rp_offset); @@ -70,7 +70,7 @@ ssize_t read_predict(int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num) /* Find the end of the file - ensure we don't read predict beyond it. */ - if(sys_fstat(fd,&rp_stat) < 0) + if(fsp->conn->vfs_ops.fstat(fd,&rp_stat) < 0) { DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno))); predict_skip = True; @@ -95,7 +95,7 @@ ssize_t read_predict(int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num) /**************************************************************************** pre-read some data ****************************************************************************/ -void do_read_prediction(void) +void do_read_prediction(connection_struct *conn) { static size_t readsize = 0; @@ -134,13 +134,13 @@ void do_read_prediction(void) } } - if (sys_lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) { + if (conn->vfs_ops.lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) { rp_fd = -1; rp_predict_fd = -1; return; } - rp_length = read(rp_fd,rp_buffer,rp_predict_length); + rp_length = conn->vfs_ops.read(rp_fd,rp_buffer,rp_predict_length); rp_time = time(NULL); if (rp_length < 0) rp_length = 0; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d1ccda1750..f022301450 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -981,7 +981,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int user we should become. */ { - struct passwd *pw = Get_Pwnam(user,False); + const struct passwd *pw = Get_Pwnam(user,False); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); return bad_password_error(inbuf,outbuf); @@ -1032,7 +1032,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if(VALID_STAT(st)) ok = S_ISDIR(st.st_mode); else - ok = dos_directory_exist(name,NULL); + ok = vfs_directory_exist(conn,dos_to_unix(name,False),NULL); } if (!ok) @@ -1167,7 +1167,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size mode = SVAL(inbuf,smb_vwv0); mtime = make_unix_date3(inbuf+smb_vwv1); - if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL)) + if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, dos_to_unix(fname,False),NULL)) mode |= aDIR; if (check_name(fname,conn)) ok = (file_chmod(conn,fname,mode,NULL) == 0); @@ -1201,7 +1201,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz int outsize = 0; SMB_BIG_UINT dfree,dsize,bsize; - sys_disk_free(".",True,&bsize,&dfree,&dsize); + conn->vfs_ops.disk_free(".",True,&bsize,&dfree,&dsize); outsize = set_message(outbuf,5,0,True); @@ -1563,7 +1563,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1665,7 +1665,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { close_file(fsp,False); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1918,7 +1918,7 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype) if (!CAN_WRITE(conn)) return(False); - if (dos_lstat(fname,&sbuf) != 0) return(False); + if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False); fmode = dos_mode(conn,fname,&sbuf); if (fmode & aDIR) return(False); if (!lp_delete_readonly(SNUM(conn))) { @@ -1989,7 +1989,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (can_delete(directory,conn,dirtype) && !dos_unlink(directory)) count++; if (!count) - exists = dos_file_exist(directory,NULL); + exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL); } else { void *dirptr = NULL; char *dname; @@ -2019,7 +2019,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size error = ERRnoaccess; slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); if (!can_delete(fname,conn,dirtype)) continue; - if (!dos_unlink(fname)) count++; + if (!conn->vfs_ops.unlink(fname)) count++; DEBUG(3,("reply_unlink : doing unlink on %s\n",fname)); } CloseDir(dirptr); @@ -2137,7 +2137,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s if (size < sizeneeded) { SMB_STRUCT_STAT st; - if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) size = st.st_size; if (!fsp->can_write) fsp->size = size; @@ -2161,11 +2161,11 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s #if USE_READ_PREDICTION if (!fsp->can_write) - predict = read_predict(fsp->fd_ptr->fd,startpos,header+4,NULL,nread); + predict = read_predict(fsp, fsp->fd_ptr->fd,startpos,header+4,NULL,nread); #endif /* USE_READ_PREDICTION */ if ((nread-predict) > 0) { - if(seek_file(fsp,startpos + predict) == -1) { + if(conn->vfs_ops.seek(fsp,startpos + predict) == -1) { DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n")); ret = 0; seek_fail = True; @@ -2173,7 +2173,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s } if(!seek_fail) - ret = (ssize_t)transfer_file(fsp->fd_ptr->fd,Client, + ret = (ssize_t)vfs_transfer_file(-1, fsp->fd_ptr->fd, Client, NULL, (SMB_OFF_T)(nread-predict),header,4+predict, startpos+predict); } @@ -2439,8 +2439,9 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, (int)tcount,(int)nwritten,(int)numtowrite)); } - nwritten = transfer_file(Client,fsp->fd_ptr->fd,(SMB_OFF_T)numtowrite,NULL,0, - startpos+nwritten); + nwritten = vfs_transfer_file(Client, NULL, -1, fsp, + (SMB_OFF_T)numtowrite,NULL,0, + startpos+nwritten); total_written += nwritten; /* Set up outbuf to return the correct return */ @@ -2453,8 +2454,9 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, SSVAL(outbuf,smb_err,ERRdiskfull); } - if (lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); + if ((lp_syncalways(SNUM(conn)) || write_through) && + lp_strict_sync(SNUM(conn))) + conn->vfs_ops.fsync(fsp->fd_ptr->fd); DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n", fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written)); @@ -2502,7 +2504,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz nwritten = write_file(fsp,data,startpos,numtowrite); if (lp_syncalways(SNUM(conn))) - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2551,13 +2553,13 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d zero then the file size should be extended or truncated to the size given in smb_vwv[2-3] */ if(numtowrite == 0) { - if((nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos)) >= 0) + if((nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos)) >= 0) /* tpot vfs */ set_filelen_write_cache(fsp, startpos); } else nwritten = write_file(fsp,data,startpos,numtowrite); if (lp_syncalways(SNUM(conn))) - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2651,7 +2653,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng fsp->fnum, (int)numtowrite, (int)nwritten)); if (lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); return chain_reply(inbuf,outbuf,length,bufsize); } @@ -2685,7 +2687,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int umode = SEEK_SET; break; } - if((res = sys_lseek(fsp->fd_ptr->fd,startpos,umode)) == -1) { + if((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,startpos,umode)) == -1) { /* * Check for the special case where a seek before the start * of the file sets the offset to zero. Added in the CIFS spec, @@ -2697,7 +2699,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int if(umode == SEEK_CUR) { - if((current_pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1) + if((current_pos = conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); current_pos += startpos; @@ -2706,14 +2708,14 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int SMB_STRUCT_STAT sbuf; - if(sys_fstat( fsp->fd_ptr->fd, &sbuf) == -1) + if(conn->vfs_ops.fstat( fsp->fd_ptr->fd, &sbuf) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); current_pos += sbuf.st_size; } if(current_pos < 0) - res = sys_lseek(fsp->fd_ptr->fd,0,SEEK_SET); + res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_SET); } if(res == -1) @@ -2748,7 +2750,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (!fsp) { file_sync_all(conn); } else { - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); } DEBUG(3,("flush\n")); @@ -3235,7 +3237,8 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_convert(directory,conn,0,&bad_path,NULL); if (check_name(directory, conn)) - ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory)); + ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False), + unix_mode(conn,aDIR,directory)); if (ret < 0) { @@ -3259,7 +3262,7 @@ Static function used by reply_rmdir to delete an entire directory tree recursively. ****************************************************************************/ -static BOOL recursive_rmdir(char *directory) +static BOOL recursive_rmdir(connection_struct *conn, char *directory) { char *dname = NULL; BOOL ret = False; @@ -3287,7 +3290,7 @@ static BOOL recursive_rmdir(char *directory) pstrcat(fullname, "/"); pstrcat(fullname, dname); - if(dos_lstat(fullname, &st) != 0) + if(conn->vfs_ops.lstat(fullname, &st) != 0) { ret = True; break; @@ -3295,18 +3298,18 @@ static BOOL recursive_rmdir(char *directory) if(st.st_mode & S_IFDIR) { - if(recursive_rmdir(fullname)!=0) + if(recursive_rmdir(conn, fullname)!=0) { ret = True; break; } - if(dos_rmdir(fullname) != 0) + if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0) { ret = True; break; } } - else if(dos_unlink(fullname) != 0) + else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0) { ret = True; break; @@ -3324,7 +3327,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory) { BOOL ok; - ok = (dos_rmdir(directory) == 0); + ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0); if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) { /* @@ -3371,24 +3374,24 @@ BOOL rmdir_internals(connection_struct *conn, char *directory) pstrcat(fullname, "/"); pstrcat(fullname, dname); - if(dos_lstat(fullname, &st) != 0) + if(conn->vfs_ops.lstat(dos_to_unix(fullname, False), &st) != 0) break; if(st.st_mode & S_IFDIR) { if(lp_recursive_veto_delete(SNUM(conn))) { - if(recursive_rmdir(fullname) != 0) + if(recursive_rmdir(conn, fullname) != 0) break; } - if(dos_rmdir(fullname) != 0) + if(conn->vfs_ops.rmdir(dos_to_unix(fullname, False)) != 0) break; } - else if(dos_unlink(fullname) != 0) + else if(conn->vfs_ops.unlink(dos_to_unix(fullname, False)) != 0) break; } CloseDir(dirptr); /* Retry the rmdir */ - ok = (dos_rmdir(directory) == 0); + ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0); } else CloseDir(dirptr); @@ -3515,7 +3518,7 @@ static BOOL can_rename(char *fname,connection_struct *conn) if (!CAN_WRITE(conn)) return(False); - if (dos_lstat(fname,&sbuf) != 0) return(False); + if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False); if (!check_file_sharing(conn,fname,True)) return(False); return(True); @@ -3645,21 +3648,23 @@ int rename_internals(connection_struct *conn, */ if(resolve_wildcards(directory,newname) && can_rename(directory,conn) && - !dos_rename(directory,newname)) + !conn->vfs_ops.rename(dos_to_unix(directory,False), + newname)) count++; } else { if (resolve_wildcards(directory,newname) && can_rename(directory,conn) && - !dos_file_exist(newname,NULL) && - !dos_rename(directory,newname)) + !vfs_file_exist(conn,dos_to_unix(newname,False),NULL) && + !conn->vfs_ops.rename(dos_to_unix(directory,False), + newname)) count++; } DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed", directory,newname)); - if (!count) exists = dos_file_exist(directory,NULL); - if (!count && exists && dos_file_exist(newname,NULL)) { + if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL); + if (!count && exists && vfs_file_exist(conn,dos_to_unix(newname,False),NULL)) { exists = True; error = ERRrename; } @@ -3700,13 +3705,13 @@ int rename_internals(connection_struct *conn, continue; } - if (!replace_if_exists && dos_file_exist(destname,NULL)) { - DEBUG(6,("dos_file_exist %s\n", destname)); + if (!replace_if_exists && vfs_file_exist(conn,dos_to_unix(destname,False),NULL)) { + DEBUG(6,("file_exist %s\n", destname)); error = 183; continue; } - if (!dos_rename(fname,destname)) + if (!conn->vfs_ops.rename(dos_to_unix(fname,False),destname)) count++; DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname)); } @@ -3777,7 +3782,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, pstrcat(dest,p); } - if (!dos_file_exist(src,&st)) + if (!vfs_file_exist(conn,dos_to_unix(src,False),&st)) return(False); fsp1 = file_new(); @@ -3810,7 +3815,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } if ((ofun&3) == 1) { - if(sys_lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) { + if(conn->vfs_ops.lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) { DEBUG(0,("copy_file: error - sys_lseek returned error %s\n", strerror(errno) )); /* @@ -3822,8 +3827,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } if (st.st_size) - ret = transfer_file(fsp1->fd_ptr->fd, - fsp2->fd_ptr->fd,st.st_size,NULL,0,0); + ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0); close_file(fsp1,False); /* @@ -3878,7 +3882,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, rc = unix_convert(name,conn,0,&bad_path1,NULL); unix_convert(newname,conn,0,&bad_path2,NULL); - target_is_directory = dos_directory_exist(newname,NULL); + target_is_directory = vfs_directory_exist(conn,dos_to_unix(newname,False),NULL); if ((flags&1) && target_is_directory) { return(ERROR(ERRDOS,ERRbadfile)); @@ -3888,7 +3892,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(ERROR(ERRDOS,ERRbadpath)); } - if ((flags&(1<<5)) && dos_directory_exist(name,NULL)) { + if ((flags&(1<<5)) && vfs_directory_exist(conn,dos_to_unix(name,False),NULL)) { /* wants a tree copy! XXXX */ DEBUG(3,("Rejecting tree copy\n")); return(ERROR(ERRSRV,ERRerror)); @@ -3928,7 +3932,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, errno = err; return(UNIXERROR(ERRHRD,ERRgeneral)); } - if (!count) exists = dos_file_exist(directory,NULL); + if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL); } else { void *dirptr = NULL; char *dname; @@ -4008,7 +4012,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (strlen(newdir) == 0) { ok = True; } else { - ok = dos_directory_exist(newdir,NULL); + ok = vfs_directory_exist(conn,dos_to_unix(newdir,False),NULL); if (ok) { string_set(&conn->connectpath,newdir); } @@ -4426,7 +4430,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, nwritten = write_file(fsp,data,startpos,numtowrite); if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); if(nwritten < (ssize_t)numtowrite) return(UNIXERROR(ERRHRD,ERRdiskfull)); @@ -4527,7 +4531,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz nwritten = write_file(fsp,data,startpos,numtowrite); if(lp_syncalways(SNUM(conn)) || write_through) - sync_file(conn,fsp); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); if (nwritten < (ssize_t)numtowrite) { @@ -4634,7 +4638,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, CHECK_ERROR(fsp); /* Do an fstat on this file */ - if(sys_fstat(fsp->fd_ptr->fd, &sbuf)) + if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd, &sbuf)) return(UNIXERROR(ERRDOS,ERRnoaccess)); mode = dos_mode(conn,fsp->fsp_name,&sbuf); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 0e9675076f..44e347b104 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -707,8 +707,8 @@ static void usage(char *pname) DEBUG( 3, ( "Becoming a daemon.\n" ) ); become_daemon(); } - - check_kernel_oplocks(); + + check_kernel_oplocks(); if (!directory_exist(lp_lockdir(), NULL)) { mkdir(lp_lockdir(), 0755); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index ec723e13b9..3abd55de0c 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -142,6 +142,11 @@ int find_service(char *service) } } + /* Check for default vfs service? Unsure whether to implement this */ + if (iService < 0) + { + } + /* just possibly it's a default service? */ if (iService < 0) { @@ -351,6 +356,60 @@ connection_struct *make_connection(char *service,char *user,char *password, int string_set(&conn->dirpath,""); string_set(&conn->user,user); + conn->vfs_conn = (struct vfs_connection_struct *) + malloc(sizeof(struct vfs_connection_struct)); + + if (conn->vfs_conn == NULL) { + DEBUG(0, ("No memory to create vfs_connection_struct")); + return NULL; + } + + ZERO_STRUCTP(conn->vfs_conn); + + /* Copy across relevant data from connection struct */ + + conn->vfs_conn->printer = conn->printer; + conn->vfs_conn->ipc = conn->ipc; + conn->vfs_conn->read_only = conn->read_only; + conn->vfs_conn->admin_user = conn->admin_user; + + pstrcpy(conn->vfs_conn->dirpath, conn->dirpath); + pstrcpy(conn->vfs_conn->connectpath, conn->connectpath); + pstrcpy(conn->vfs_conn->origpath, conn->origpath); + + pstrcpy(conn->vfs_conn->service, service); + pstrcpy(conn->vfs_conn->user, conn->user); + + conn->vfs_conn->uid = conn->uid; + conn->vfs_conn->gid = conn->gid; + conn->vfs_conn->ngroups = conn->ngroups; + conn->vfs_conn->groups = (gid_t *)memdup(conn->groups, + conn->ngroups * sizeof(gid_t)); + + /* Initialise VFS function pointers */ + + if (*lp_vfsobj(SNUM(conn))) { + +#ifdef HAVE_LIBDL + + /* Loadable object file */ + + if (!vfs_init_custom(conn)) { + return NULL; + } +#else + DEBUG(0, ("No libdl present - cannot use VFS objects\n")); + conn_free(conn); + return NULL; +#endif + + } else { + + /* Normal share - initialise with disk access functions */ + + vfs_init_default(conn); + } + /* * If force user is true, then store the * given userid and also the primary groupid @@ -560,7 +619,15 @@ connection_struct *make_connection(char *service,char *user,char *password, int set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn))); } - return(conn); + /* Invoke VFS make connection hook */ + + if (conn->vfs_ops.connect) { + if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) { + return NULL; + } + } + + return(conn); } @@ -577,6 +644,29 @@ void close_cnum(connection_struct *conn, uint16 vuid) remote_machine,conn->client_address, lp_servicename(SNUM(conn)))); + if (conn->vfs_ops.disconnect != NULL) { + + /* Call VFS disconnect hook */ + + conn->vfs_ops.disconnect(); + + } + + /* Close dlopen() handle */ + + if (conn->vfs_conn->dl_handle != NULL) { + dlclose(conn->vfs_conn->dl_handle); /* should we check return val? */ + } + + /* Free vfs_connection_struct */ + + if (conn->vfs_conn != NULL) { + if (conn->vfs_conn->groups != NULL) { + free(conn->vfs_conn->groups); + } + free(conn->vfs_conn); + } + yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn))); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 4b774a4ed1..bd2237253e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -255,7 +255,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { close_file(fsp,False); return(UNIXERROR(ERRDOS,ERRnoaccess)); } @@ -404,7 +404,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, if(needslash) pstrcat(pathreal,"/"); pstrcat(pathreal,dname); - if (dos_stat(pathreal,&sbuf) != 0) + if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0) { DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno))); continue; @@ -1124,7 +1124,7 @@ static int call_trans2qfsinfo(connection_struct *conn, DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - if(dos_stat(".",&st)!=0) { + if(conn->vfs_ops.stat(".",&st)!=0) { DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); return (ERROR(ERRSRV,ERRinvdevice)); } @@ -1138,7 +1138,7 @@ static int call_trans2qfsinfo(connection_struct *conn, { SMB_BIG_UINT dfree,dsize,bsize; data_len = 18; - sys_disk_free(".",False,&bsize,&dfree,&dsize); + conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); SIVAL(pdata,l1_idFileSystem,st.st_dev); SIVAL(pdata,l1_cSectorUnit,bsize/512); SIVAL(pdata,l1_cUnit,dsize); @@ -1216,7 +1216,7 @@ static int call_trans2qfsinfo(connection_struct *conn, { SMB_BIG_UINT dfree,dsize,bsize; data_len = 24; - sys_disk_free(".",False,&bsize,&dfree,&dsize); + conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); SBIG_UINT(pdata,0,dsize); SBIG_UINT(pdata,8,dfree); SIVAL(pdata,16,bsize/512); @@ -1315,7 +1315,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, */ fname = fsp->fsp_name; unix_convert(fname,conn,0,&bad_path,&sbuf); - if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && dos_stat(fname,&sbuf))) { + if (!check_name(fname,conn) || + (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); if((errno == ENOENT) && bad_path) { @@ -1335,11 +1336,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn, CHECK_ERROR(fsp); fname = fsp->fsp_name; - if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } - if((pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1) + if((pos = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1) return(UNIXERROR(ERRDOS,ERRnoaccess)); delete_pending = fsp->fd_ptr->delete_on_close; @@ -1353,7 +1354,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, fname = &fname1[0]; pstrcpy(fname,¶ms[6]); unix_convert(fname,conn,0,&bad_path,&sbuf); - if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && dos_stat(fname,&sbuf))) { + if (!check_name(fname,conn) || + (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); if((errno == ENOENT) && bad_path) { @@ -1593,7 +1595,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn, */ fname = fsp->fsp_name; unix_convert(fname,conn,0,&bad_path,&st); - if (!check_name(fname,conn) || (!VALID_STAT(st) && dos_stat(fname,&st))) { + if (!check_name(fname,conn) || + (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); if((errno == ENOENT) && bad_path) { @@ -1612,7 +1615,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, fname = fsp->fsp_name; fd = fsp->fd_ptr->fd; - if (sys_fstat(fd,&st) != 0) { + if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) { DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); return(UNIXERROR(ERRDOS,ERRbadfid)); } @@ -1633,7 +1636,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, return(UNIXERROR(ERRDOS,ERRbadpath)); } - if(!VALID_STAT(st) && dos_stat(fname,&st)!=0) { + if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) { DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno))); if((errno == ENOENT) && bad_path) { @@ -1980,13 +1983,13 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode)) fname, (double)size )); if (fd == -1) { - fd = dos_open(fname,O_RDWR,0); + fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0); if (fd == -1) return(UNIXERROR(ERRDOS,ERRbadpath)); - set_filelen(fd, size); - close(fd); + set_filelen(fd, size); /* tpot vfs */ + conn->vfs_ops.close(fd); } else { - set_filelen(fd, size); + set_filelen(fd, size); /* tpot vfs */ } if(fsp) @@ -2021,7 +2024,8 @@ static int call_trans2mkdir(connection_struct *conn, unix_convert(directory,conn,0,&bad_path,NULL); if (check_name(directory,conn)) - ret = dos_mkdir(directory,unix_mode(conn,aDIR,directory)); + ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False), + unix_mode(conn,aDIR,directory)); if(ret < 0) { -- cgit