*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "smbd/smbd.h"
+#include "ntioctl.h"
/*
Please read the VFS module Samba-HowTo-Collection.
typedef struct {
int pos;
int num;
- SMB_STRUCT_DIRENT *dirs;
+ struct dirent *dirs;
} shadow_copy_Dir;
-static BOOL shadow_copy_match_name(const char *name)
+static bool shadow_copy_match_name(const char *name)
{
if (strncmp(SHADOW_COPY_PREFIX,name, sizeof(SHADOW_COPY_PREFIX)-1)==0 &&
(strlen(SHADOW_COPY_SAMPLE) == strlen(name))) {
return False;
}
-static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
+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;
- SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fname,mask,attr);
+ 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",fname));
+ DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() "
+ "failed for [%s]\n",
+ smb_fname->base_name));
return NULL;
}
ZERO_STRUCTP(dirp);
while (True) {
- SMB_STRUCT_DIRENT *d;
+ struct dirent *d;
- d = SMB_VFS_NEXT_READDIR(handle, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p, NULL);
if (d == NULL) {
break;
}
DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name));
- dirp->dirs = SMB_REALLOC_ARRAY(dirp->dirs,SMB_STRUCT_DIRENT, dirp->num+1);
+ 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;
}
SMB_VFS_NEXT_CLOSEDIR(handle,p);
- return((SMB_STRUCT_DIR *)dirp);
+ return((DIR *)dirp);
}
-static SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
+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);
+
+ if (!p) {
+ DEBUG(10,("shadow_copy_opendir: SMB_VFS_NEXT_FDOPENDIR() failed for [%s]\n",
+ smb_fname_str_dbg(fsp->fsp_name)));
+ return NULL;
+ }
+
+ dirp = SMB_MALLOC_P(shadow_copy_Dir);
+ if (!dirp) {
+ 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;
+ 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_fdopendir: hide [%s]\n",d->d_name));
+ continue;
+ }
+
+ DEBUG(10,("shadow_copy_fdopendir: 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_fdopendir: Out of memory\n"));
+ break;
+ }
+
+ dirp->dirs[dirp->num++] = *d;
+ }
+
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
+ /* We have now closed the fd in fsp. */
+ fsp->fh->fd = -1;
+ return((DIR *)dirp);
+}
+
+static struct dirent *shadow_copy_readdir(vfs_handle_struct *handle,
+ DIR *_dirp,
+ SMB_STRUCT_STAT *sbuf)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
return NULL;
}
-static void shadow_copy_seekdir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp, long offset)
+static void shadow_copy_seekdir(struct vfs_handle_struct *handle, DIR *_dirp, long offset)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
}
}
-static long shadow_copy_telldir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
+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, SMB_STRUCT_DIR *_dirp)
+static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
dirp->pos = 0 ;
}
-static int shadow_copy_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
+static int shadow_copy_closedir(vfs_handle_struct *handle, DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
return 0;
}
-static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
+static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle,
+ files_struct *fsp,
+ struct shadow_copy_data *shadow_copy_data,
+ bool labels)
{
- SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0);
+ DIR *p = NULL;
+ struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
+ fsp->conn->connectpath,
+ NULL,
+ NULL);
+ if (smb_fname == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ p = SMB_VFS_NEXT_OPENDIR(handle,smb_fname,NULL,0);
+
+ TALLOC_FREE(smb_fname);
shadow_copy_data->num_volumes = 0;
shadow_copy_data->labels = NULL;
while (True) {
SHADOW_COPY_LABEL *tlabels;
- SMB_STRUCT_DIRENT *d;
+ struct dirent *d;
- d = SMB_VFS_NEXT_READDIR(handle, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p, NULL);
if (d == NULL) {
break;
}
continue;
}
- tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data->mem_ctx,
+ tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data,
shadow_copy_data->labels,
(shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL));
if (tlabels == NULL) {
return 0;
}
-/* VFS operations structure */
-
-static vfs_op_tuple shadow_copy_ops[] = {
- {SMB_VFS_OP(shadow_copy_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(shadow_copy_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+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)
{
- NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", shadow_copy_ops);
+ NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+ "shadow_copy", &vfs_shadow_copy_fns);
if (!NT_STATUS_IS_OK(ret))
return ret;