Loading source3/Makefile.in +6 −0 Original line number Diff line number Diff line Loading @@ -320,6 +320,7 @@ VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o VFS_CAP_OBJ = modules/vfs_cap.o VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o Loading Loading @@ -1169,6 +1170,11 @@ bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` bin/shadow_copy.@SHLIBEXT@: $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \ Loading source3/configure.in +2 −1 Original line number Diff line number Diff line Loading @@ -360,7 +360,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs charset_CP850 charset_CP437" default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" Loading Loading @@ -4333,6 +4333,7 @@ SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHL SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS) SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS) SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS) SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) Loading source3/modules/vfs_shadow_copy.c 0 → 100644 +227 −0 Original line number Diff line number Diff line /* * implementation of an Shadow Copy module * * Copyright (C) Stefan Metzmacher 2003-2004 * * 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 * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 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. */ #include "includes.h" /* Please read the VFS module Samba-HowTo-Collection. there's a chapter about this module For this share Z:\ the ShadowCopies are in this directories Z:\@GMT-2003.08.05-12.00.00\ Z:\@GMT-2003.08.05-12.01.00\ Z:\@GMT-2003.08.05-12.02.00\ e.g. Z:\testfile.txt Z:\@GMT-2003.08.05-12.02.00\testfile.txt or: Z:\testdir\testfile.txt Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt Note: Files must differ to be displayed via Windows Explorer! Directories are always displayed... */ static int vfs_shadow_copy_debug_level = DBGC_VFS; #undef DBGC_CLASS #define DBGC_CLASS vfs_shadow_copy_debug_level #define SHADOW_COPY_PREFIX "@GMT-" #define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00" typedef struct { int pos; int num; struct dirent *dirs; } shadow_copy_Dir; 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 True; } return False; } static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { shadow_copy_Dir *dirp; DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname); if (!p) { DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname)); return NULL; } dirp = (shadow_copy_Dir *)malloc(sizeof(shadow_copy_Dir)); if (!dirp) { DEBUG(0,("shadow_copy_opendir: Out of memory\n")); SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); return NULL; } ZERO_STRUCTP(dirp); while (True) { struct dirent *d; struct dirent *r; d = SMB_VFS_NEXT_READDIR(handle, conn, p); 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)); r = (struct dirent *)Realloc(dirp->dirs,(dirp->num+1)*sizeof(struct dirent)); if (!r) { DEBUG(0,("shadow_copy_opendir: Out of memory\n")); break; } dirp->dirs = r; dirp->dirs[dirp->num++] = *d; } SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); return((DIR *)dirp); } struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; if (dirp->pos < dirp->num) { return &(dirp->dirs[dirp->pos++]); } return NULL; } int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; SAFE_FREE(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) { DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath); 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; d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p); if (d == NULL) { break; } /* */ if (!shadow_copy_match_name(d->d_name)) { DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name)); continue; } DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name)); if (!labels) { shadow_copy_data->num_volumes++; continue; } tlabels = (SHADOW_COPY_LABEL *)talloc_realloc(shadow_copy_data->mem_ctx, shadow_copy_data->labels, (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,fsp->conn,p); return -1; } snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name); shadow_copy_data->labels = tlabels; } SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p); 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_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} }; NTSTATUS vfs_shadow_copy_init(void) { NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", shadow_copy_ops); if (!NT_STATUS_IS_OK(ret)) return ret; vfs_shadow_copy_debug_level = debug_add_class("shadow_copy"); if (vfs_shadow_copy_debug_level == -1) { vfs_shadow_copy_debug_level = DBGC_VFS; DEBUG(0, ("%s: Couldn't register custom debugging class!\n", "vfs_shadow_copy_init")); } else { DEBUG(10, ("%s: Debug class number of '%s': %d\n", "vfs_shadow_copy_init","shadow_copy",vfs_shadow_copy_debug_level)); } return ret; } Loading
source3/Makefile.in +6 −0 Original line number Diff line number Diff line Loading @@ -320,6 +320,7 @@ VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o VFS_CAP_OBJ = modules/vfs_cap.o VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o Loading Loading @@ -1169,6 +1170,11 @@ bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` bin/shadow_copy.@SHLIBEXT@: $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \ Loading
source3/configure.in +2 −1 Original line number Diff line number Diff line Loading @@ -360,7 +360,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs charset_CP850 charset_CP437" default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" Loading Loading @@ -4333,6 +4333,7 @@ SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHL SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS) SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS) SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS) SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) Loading
source3/modules/vfs_shadow_copy.c 0 → 100644 +227 −0 Original line number Diff line number Diff line /* * implementation of an Shadow Copy module * * Copyright (C) Stefan Metzmacher 2003-2004 * * 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 * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 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. */ #include "includes.h" /* Please read the VFS module Samba-HowTo-Collection. there's a chapter about this module For this share Z:\ the ShadowCopies are in this directories Z:\@GMT-2003.08.05-12.00.00\ Z:\@GMT-2003.08.05-12.01.00\ Z:\@GMT-2003.08.05-12.02.00\ e.g. Z:\testfile.txt Z:\@GMT-2003.08.05-12.02.00\testfile.txt or: Z:\testdir\testfile.txt Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt Note: Files must differ to be displayed via Windows Explorer! Directories are always displayed... */ static int vfs_shadow_copy_debug_level = DBGC_VFS; #undef DBGC_CLASS #define DBGC_CLASS vfs_shadow_copy_debug_level #define SHADOW_COPY_PREFIX "@GMT-" #define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00" typedef struct { int pos; int num; struct dirent *dirs; } shadow_copy_Dir; 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 True; } return False; } static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { shadow_copy_Dir *dirp; DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname); if (!p) { DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname)); return NULL; } dirp = (shadow_copy_Dir *)malloc(sizeof(shadow_copy_Dir)); if (!dirp) { DEBUG(0,("shadow_copy_opendir: Out of memory\n")); SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); return NULL; } ZERO_STRUCTP(dirp); while (True) { struct dirent *d; struct dirent *r; d = SMB_VFS_NEXT_READDIR(handle, conn, p); 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)); r = (struct dirent *)Realloc(dirp->dirs,(dirp->num+1)*sizeof(struct dirent)); if (!r) { DEBUG(0,("shadow_copy_opendir: Out of memory\n")); break; } dirp->dirs = r; dirp->dirs[dirp->num++] = *d; } SMB_VFS_NEXT_CLOSEDIR(handle,conn,p); return((DIR *)dirp); } struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; if (dirp->pos < dirp->num) { return &(dirp->dirs[dirp->pos++]); } return NULL; } int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp) { shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp; SAFE_FREE(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) { DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath); 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; d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p); if (d == NULL) { break; } /* */ if (!shadow_copy_match_name(d->d_name)) { DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name)); continue; } DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name)); if (!labels) { shadow_copy_data->num_volumes++; continue; } tlabels = (SHADOW_COPY_LABEL *)talloc_realloc(shadow_copy_data->mem_ctx, shadow_copy_data->labels, (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,fsp->conn,p); return -1; } snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name); shadow_copy_data->labels = tlabels; } SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p); 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_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} }; NTSTATUS vfs_shadow_copy_init(void) { NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", shadow_copy_ops); if (!NT_STATUS_IS_OK(ret)) return ret; vfs_shadow_copy_debug_level = debug_add_class("shadow_copy"); if (vfs_shadow_copy_debug_level == -1) { vfs_shadow_copy_debug_level = DBGC_VFS; DEBUG(0, ("%s: Couldn't register custom debugging class!\n", "vfs_shadow_copy_init")); } else { DEBUG(10, ("%s: Debug class number of '%s': %d\n", "vfs_shadow_copy_init","shadow_copy",vfs_shadow_copy_debug_level)); } return ret; }