X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_shadow_copy.c;h=b597644869b70d4547e679354e69f350f193ecc4;hb=HEAD;hp=77dc1636c91f8dd8835c34ddb7ec803a261e78b2;hpb=c74ae37fe6df0c7a80733e6ed3ae8844345743a5;p=samba.git diff --git a/source3/modules/vfs_shadow_copy.c b/source3/modules/vfs_shadow_copy.c index 77dc1636c91..62b92918886 100644 --- a/source3/modules/vfs_shadow_copy.c +++ b/source3/modules/vfs_shadow_copy.c @@ -20,6 +20,7 @@ #include "includes.h" #include "smbd/smbd.h" #include "ntioctl.h" +#include "source3/smbd/dir.h" /* Please read the VFS module Samba-HowTo-Collection. @@ -73,58 +74,6 @@ static bool shadow_copy_match_name(const char *name) return False; } -static DIR *shadow_copy_opendir(vfs_handle_struct *handle, - const struct smb_filename *smb_fname, - const char *mask, - uint32_t attr) -{ - shadow_copy_Dir *dirp; - DIR *p = SMB_VFS_NEXT_OPENDIR(handle,smb_fname,mask,attr); - - if (!p) { - DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() " - "failed for [%s]\n", - smb_fname->base_name)); - return NULL; - } - - dirp = SMB_MALLOC_P(shadow_copy_Dir); - if (!dirp) { - DEBUG(0,("shadow_copy_opendir: Out of memory\n")); - SMB_VFS_NEXT_CLOSEDIR(handle,p); - return NULL; - } - - ZERO_STRUCTP(dirp); - - while (True) { - struct dirent *d; - - d = SMB_VFS_NEXT_READDIR(handle, p, NULL); - if (d == NULL) { - break; - } - - if (shadow_copy_match_name(d->d_name)) { - DEBUG(8,("shadow_copy_opendir: hide [%s]\n",d->d_name)); - continue; - } - - DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name)); - - dirp->dirs = SMB_REALLOC_ARRAY(dirp->dirs,struct dirent, dirp->num+1); - if (!dirp->dirs) { - DEBUG(0,("shadow_copy_opendir: Out of memory\n")); - break; - } - - dirp->dirs[dirp->num++] = *d; - } - - SMB_VFS_NEXT_CLOSEDIR(handle,p); - return((DIR *)dirp); -} - static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32_t attr) { shadow_copy_Dir *dirp; @@ -141,7 +90,7 @@ static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp, DEBUG(0,("shadow_copy_fdopendir: Out of memory\n")); SMB_VFS_NEXT_CLOSEDIR(handle,p); /* We have now closed the fd in fsp. */ - fsp->fh->fd = -1; + fsp_set_fd(fsp, -1); return NULL; } @@ -150,7 +99,7 @@ static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp, while (True) { struct dirent *d; - d = SMB_VFS_NEXT_READDIR(handle, p, NULL); + d = SMB_VFS_NEXT_READDIR(handle, fsp, p); if (d == NULL) { break; } @@ -173,13 +122,13 @@ static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp, SMB_VFS_NEXT_CLOSEDIR(handle,p); /* We have now closed the fd in fsp. */ - fsp->fh->fd = -1; + fsp_set_fd(fsp, -1); return((DIR *)dirp); } static struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, - DIR *_dirp, - SMB_STRUCT_STAT *sbuf) + struct files_struct *dirfsp, + DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; @@ -190,21 +139,6 @@ static struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, return NULL; } -static void shadow_copy_seekdir(struct vfs_handle_struct *handle, DIR *_dirp, long offset) -{ - shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; - - if (offset < dirp->num) { - dirp->pos = offset ; - } -} - -static long shadow_copy_telldir(struct vfs_handle_struct *handle, DIR *_dirp) -{ - shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; - return( dirp->pos ) ; -} - static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; @@ -226,47 +160,58 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, struct shadow_copy_data *shadow_copy_data, bool labels) { - DIR *p = NULL; + struct smb_Dir *dir_hnd = NULL; + const char *dname = NULL; + char *talloced = NULL; + NTSTATUS status; struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(), fsp->conn->connectpath, NULL, - NULL); + NULL, + 0, + 0); if (smb_fname == NULL) { errno = ENOMEM; return -1; } - p = SMB_VFS_NEXT_OPENDIR(handle,smb_fname,NULL,0); - + status = OpenDir(talloc_tos(), + handle->conn, + smb_fname, + NULL, + 0, + &dir_hnd); TALLOC_FREE(smb_fname); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("OpenDir() failed for [%s]\n", fsp->conn->connectpath); + errno = map_errno_from_nt_status(status); + return -1; + } shadow_copy_data->num_volumes = 0; shadow_copy_data->labels = NULL; - if (!p) { - DEBUG(0,("shadow_copy_get_shadow_copy_data: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fsp->conn->connectpath)); - return -1; - } - while (True) { SHADOW_COPY_LABEL *tlabels; - struct dirent *d; + int ret; - d = SMB_VFS_NEXT_READDIR(handle, p, NULL); - if (d == NULL) { + dname = ReadDirName(dir_hnd, &talloced); + if (dname == NULL) { break; } /* */ - if (!shadow_copy_match_name(d->d_name)) { - DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name)); + if (!shadow_copy_match_name(dname)) { + DBG_DEBUG("ignore [%s]\n", dname); + TALLOC_FREE(talloced); continue; } - DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name)); + DBG_DEBUG("not ignore [%s]\n", dname); if (!labels) { shadow_copy_data->num_volumes++; + TALLOC_FREE(talloced); continue; } @@ -275,32 +220,39 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, (shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL)); if (tlabels == NULL) { DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n")); - SMB_VFS_NEXT_CLOSEDIR(handle,p); + TALLOC_FREE(talloced); + TALLOC_FREE(dir_hnd); return -1; } - snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name); + ret = strlcpy(tlabels[shadow_copy_data->num_volumes], dname, + sizeof(tlabels[shadow_copy_data->num_volumes])); + if (ret != sizeof(tlabels[shadow_copy_data->num_volumes]) - 1) { + DBG_ERR("malformed label %s\n", dname); + TALLOC_FREE(talloced); + TALLOC_FREE(dir_hnd); + return -1; + } + shadow_copy_data->num_volumes++; shadow_copy_data->labels = tlabels; + TALLOC_FREE(talloced); } - SMB_VFS_NEXT_CLOSEDIR(handle,p); + TALLOC_FREE(dir_hnd); return 0; } static struct vfs_fn_pointers vfs_shadow_copy_fns = { - .opendir_fn = shadow_copy_opendir, .fdopendir_fn = shadow_copy_fdopendir, .readdir_fn = shadow_copy_readdir, - .seekdir_fn = shadow_copy_seekdir, - .telldir_fn = shadow_copy_telldir, .rewind_dir_fn = shadow_copy_rewinddir, .closedir_fn = shadow_copy_closedir, .get_shadow_copy_data_fn = shadow_copy_get_shadow_copy_data, }; -NTSTATUS vfs_shadow_copy_init(void); -NTSTATUS vfs_shadow_copy_init(void) +static_decl_vfs; +NTSTATUS vfs_shadow_copy_init(TALLOC_CTX *ctx) { NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", &vfs_shadow_copy_fns);