#include "includes.h"
#include "smbd/smbd.h"
#include "ntioctl.h"
+#include "source3/smbd/dir.h"
/*
Please read the VFS module Samba-HowTo-Collection.
return False;
}
-static DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
-{
- shadow_copy_Dir *dirp;
- DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fname,mask,attr);
-
- if (!p) {
- DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname));
- 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 attr)
+static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32_t attr)
{
shadow_copy_Dir *dirp;
DIR *p = SMB_VFS_NEXT_FDOPENDIR(handle,fsp,mask,attr);
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;
}
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;
}
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;
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;
struct shadow_copy_data *shadow_copy_data,
bool labels)
{
- DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0);
-
- shadow_copy_data->num_volumes = 0;
- shadow_copy_data->labels = 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,
+ 0,
+ 0);
+ if (smb_fname == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
- if (!p) {
- DEBUG(0,("shadow_copy_get_shadow_copy_data: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fsp->conn->connectpath));
+ 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;
+
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;
}
(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);