Sync up the VFS changes from 2.2.x.
authorJeremy Allison <jra@samba.org>
Tue, 19 Mar 2002 02:51:48 +0000 (02:51 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 19 Mar 2002 02:51:48 +0000 (02:51 +0000)
Jeremy.
(This used to be commit e758bdc8a8f37e1d1e1fb0d1d27990dba2067920)

examples/VFS/Makefile
examples/VFS/audit.c
examples/VFS/block/block.c
examples/VFS/recycle.c [new file with mode: 0644]
examples/VFS/skel.c

index 581e1a06fb5e78e74c75aa5c50064beeb49a96e0..716e48da88d280cf6fbcb7f4f5fffbe0700f0411 100644 (file)
@@ -1,7 +1,6 @@
 #
 # Makefile for samba-vfs examples
 #
-# $Id: Makefile,v 1.4 2000/11/06 20:01:03 jra Exp $
 #
 
 # Variables
@@ -13,8 +12,9 @@ SAMBA_SRC = ../../source
 SAMBA_INCL = ../../source/include
 UBIQX_SRC = ../../source/ubiqx
 SMBWR_SRC = ../../source/smbwrapper
-CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
-VFS_OBJS = audit.so skel.so
+KRB5_SRC = /usr/kerberos/include
+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(KRB5_SRC) -Wall -g
+VFS_OBJS = audit.so skel.so recycle.so
 
 # Default target
 
index 7fbcb97837e89d1be9a005a4da212da337934aa0..aad483c295ae5ce12b3384e05e188ecb31a1e931 100644 (file)
@@ -2,7 +2,7 @@
  * Auditing VFS module for samba.  Log selected file operations to syslog
  * facility.
  *
- * Copyright (C) Tim Potter, 1999-2001
+ * Copyright (C) Tim Potter, 1999-2000
  *
  * 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
 #define SYSLOG_PRIORITY   LOG_NOTICE
 #endif
 
-static struct vfs_ops default_vfs_ops;
+/* Function prototypes */
+
+int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
+void audit_disconnect(struct connection_struct *conn);
+DIR *audit_opendir(struct connection_struct *conn, const char *fname);
+int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
+int audit_rmdir(struct connection_struct *conn, const char *path);
+int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
+int audit_close(struct files_struct *fsp, int fd);
+int audit_rename(struct connection_struct *conn, const char *old, const char *new);
+int audit_unlink(struct connection_struct *conn, const char *path);
+int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
+int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
+int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
+int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
+
+/* VFS operations */
+
+extern struct vfs_ops default_vfs_ops;   /* For passthrough operation */
+
+struct vfs_ops audit_ops = {
+    
+       /* Disk operations */
+
+       audit_connect,
+       audit_disconnect,
+       NULL,                     /* disk free */
+
+       /* Directory operations */
+
+       audit_opendir,
+       NULL,                     /* readdir */
+       audit_mkdir,
+       audit_rmdir,
+       NULL,                     /* closedir */
+
+       /* File operations */
+
+       audit_open,
+       audit_close,
+       NULL,                     /* read  */
+       NULL,                     /* write */
+       NULL,                     /* lseek */
+       audit_rename,
+       NULL,                     /* fsync */
+       NULL,                     /* stat  */
+       NULL,                     /* fstat */
+       NULL,                     /* lstat */
+       audit_unlink,
+       audit_chmod,
+       audit_fchmod,
+       NULL,                     /* chown */
+       NULL,                     /* fchown */
+       NULL,                     /* chdir */
+       NULL,                     /* getwd */
+       NULL,                     /* utime */
+       NULL,                     /* ftruncate */
+       NULL,                     /* lock */
+       NULL,                     /* symlink */
+       NULL,                     /* readlink */
+       NULL,                     /* link */
+       NULL,                     /* mknod */
+       NULL,                     /* realpath */
+       NULL,                     /* fget_nt_acl */
+       NULL,                     /* get_nt_acl */
+       NULL,                     /* fset_nt_acl */
+       NULL,                      /* set_nt_acl */
+
+       audit_chmod_acl,                /* chmod_acl */
+       audit_fchmod_acl,               /* fchmod_acl */
+
+       NULL,                   /* sys_acl_get_entry */
+       NULL,                   /* sys_acl_get_tag_type */
+       NULL,                   /* sys_acl_get_permset */
+       NULL,                   /*sys_acl_get_qualifier */
+       NULL,                   /* sys_acl_get_file */
+       NULL,                   /* sys_acl_get_fd */
+       NULL,                   /* sys_acl_clear_perms */
+       NULL,                   /* sys_acl_add_perm */
+       NULL,                   /* sys_acl_to_text */
+       NULL,                   /* sys_acl_init */
+       NULL,                   /* sys_acl_create_entry */
+       NULL,                   /* sys_acl_set_tag_type */
+       NULL,                   /* sys_acl_set_qualifier */
+       NULL,                   /* sys_acl_set_permset */
+       NULL,                   /* sys_acl_valid */
+       NULL,                   /* sys_acl_set_file */
+       NULL,                   /* sys_acl_set_fd */
+       NULL,                   /* sys_acl_delete_def_file */
+       NULL,                   /* sys_acl_get_perm */
+       NULL,                   /* sys_acl_free_text */
+       NULL,                   /* sys_acl_free_acl */
+       NULL                    /* sys_acl_free_qualifier */
+};
+
+/* VFS initialisation function.  Return initialised vfs_ops structure
+   back to SAMBA. */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+       struct vfs_ops tmp_ops;
+
+       *vfs_version = SMB_VFS_INTERFACE_VERSION;
+       memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+       tmp_ops.connect = audit_connect;
+       tmp_ops.disconnect = audit_disconnect;
+       tmp_ops.opendir = audit_opendir;
+       tmp_ops.mkdir = audit_mkdir;
+       tmp_ops.rmdir = audit_rmdir;
+       tmp_ops.open = audit_open;
+       tmp_ops.close = audit_close;
+       tmp_ops.rename = audit_rename;
+       tmp_ops.unlink = audit_unlink;
+       tmp_ops.chmod = audit_chmod;
+       tmp_ops.chmod_acl = audit_chmod_acl;
+       tmp_ops.fchmod = audit_fchmod;
+       tmp_ops.fchmod_acl = audit_fchmod_acl;
+
+       memcpy(&audit_ops, &tmp_ops, sizeof(struct vfs_ops));
+
+       openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
+       syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
+       return &audit_ops;
+}
 
 /* Implementation of vfs_ops.  Pass everything on to the default
    operation but log event first. */
 
-static int audit_connect(struct connection_struct *conn, const char *svc,
-                         const char *user)
+int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
 {
        syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", 
               svc, user);
 
-       return 0;               /* Success */
+       return default_vfs_ops.connect(conn, svc, user);
 }
 
-static void audit_disconnect(struct connection_struct *conn)
+void audit_disconnect(struct connection_struct *conn)
 {
        syslog(SYSLOG_PRIORITY, "disconnected\n");
+       default_vfs_ops.disconnect(conn);
 }
 
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
+DIR *audit_opendir(struct connection_struct *conn, const char *fname)
 {
        DIR *result = default_vfs_ops.opendir(conn, fname);
 
@@ -76,8 +200,7 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
        return result;
 }
 
-static int audit_mkdir(struct connection_struct *conn, const char *path, 
-                       mode_t mode)
+int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
 {
        int result = default_vfs_ops.mkdir(conn, path, mode);
 
@@ -89,7 +212,7 @@ static int audit_mkdir(struct connection_struct *conn, const char *path,
        return result;
 }
 
-static int audit_rmdir(struct connection_struct *conn, const char *path)
+int audit_rmdir(struct connection_struct *conn, const char *path)
 {
        int result = default_vfs_ops.rmdir(conn, path);
 
@@ -101,8 +224,7 @@ static int audit_rmdir(struct connection_struct *conn, const char *path)
        return result;
 }
 
-static int audit_open(struct connection_struct *conn, const char *fname, 
-                      int flags, mode_t mode) 
+int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
 {
        int result = default_vfs_ops.open(conn, fname, flags, mode);
 
@@ -115,7 +237,7 @@ static int audit_open(struct connection_struct *conn, const char *fname,
        return result;
 }
 
-static int audit_close(struct files_struct *fsp, int fd)
+int audit_close(struct files_struct *fsp, int fd)
 {
        int result = default_vfs_ops.close(fsp, fd);
 
@@ -127,8 +249,7 @@ static int audit_close(struct files_struct *fsp, int fd)
        return result;
 }
 
-static int audit_rename(struct connection_struct *conn, const char *old, 
-                        const char *new)
+int audit_rename(struct connection_struct *conn, const char *old, const char *new)
 {
        int result = default_vfs_ops.rename(conn, old, new);
 
@@ -140,7 +261,7 @@ static int audit_rename(struct connection_struct *conn, const char *old,
        return result;    
 }
 
-static int audit_unlink(struct connection_struct *conn, const char *path)
+int audit_unlink(struct connection_struct *conn, const char *path)
 {
        int result = default_vfs_ops.unlink(conn, path);
 
@@ -152,8 +273,7 @@ static int audit_unlink(struct connection_struct *conn, const char *path)
        return result;
 }
 
-static int audit_chmod(struct connection_struct *conn, const char *path, 
-                       mode_t mode)
+int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
 {
        int result = default_vfs_ops.chmod(conn, path, mode);
 
@@ -165,32 +285,38 @@ static int audit_chmod(struct connection_struct *conn, const char *path,
        return result;
 }
 
-/* VFS initialisation function.  Return initialised vfs_ops structure
-   back to SAMBA. */
-
-struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *ops)
+int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
 {
-        *vfs_version = SMB_VFS_INTERFACE_VERSION;
+       int result = default_vfs_ops.chmod_acl(conn, path, mode);
 
-       openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
-       syslog(SYSLOG_PRIORITY, "initialised\n");
+       syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
+              path, mode,
+              (result < 0) ? "failed: " : "",
+              (result < 0) ? strerror(errno) : "");
+
+       return result;
+}
 
-        /* Save a copy of the default ops */
+int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+{
+       int result = default_vfs_ops.fchmod(fsp, fd, mode);
+
+       syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
+              fsp->fsp_name, mode,
+              (result < 0) ? "failed: " : "",
+              (result < 0) ? strerror(errno) : "");
 
-        default_vfs_ops = *ops;
+       return result;
+}
 
-        /* Override our ones */
+int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+{
+       int result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
 
-        ops->connect = audit_connect;
-        ops->disconnect = audit_disconnect;
-        ops->opendir = audit_opendir;
-        ops->mkdir = audit_mkdir;
-        ops->rmdir = audit_rmdir;
-        ops->open = audit_open;
-        ops->close = audit_close;
-        ops->rename = audit_rename;
-        ops->unlink = audit_unlink;
-        ops->chmod = audit_chmod;
+       syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
+              fsp->fsp_name, mode,
+              (result < 0) ? "failed: " : "",
+              (result < 0) ? strerror(errno) : "");
 
-       return(ops);
+       return result;
 }
index 3c4f736e84913fcc0c74353471f19fdbf49c1907..f83ab6e07e0761d25784dfeaa04afa2335ee2f60 100644 (file)
@@ -48,7 +48,7 @@
 
 
 DIR *block_opendir(struct connection_struct *conn, char *fname);
-int block_connect(struct connection_struct *conn, char *service, char *user);    
+int block_connect(struct connection_struct *conn, const char *service, const char *user);    
 void block_disconnect(struct connection_struct *conn);    
 
 
@@ -63,44 +63,77 @@ struct vfs_ops execute_vfs_ops = {
 
        block_connect,
        block_disconnect,
-       NULL,                     /* disk free */
+       NULL,                                   /* disk free */
 
        /* Directory operations */
 
        block_opendir,
-       NULL,                     /* readdir */
-       NULL,
-       NULL,
-       NULL,                     /* closedir */
+       NULL,                                   /* readdir */
+       NULL,                                   /* mkdir */
+       NULL,                                   /* rmdir */
+       NULL,                                   /* closedir */
 
        /* File operations */
 
-       NULL,
-       NULL,
-       NULL,                     /* read  */
-       NULL,                     /* write */
-       NULL,                     /* lseek */
-       NULL,
-       NULL,                     /* fsync */
-       NULL,                     /* stat  */
-       NULL,                     /* fstat */
-       NULL,                     /* lstat */
-       NULL,
-       NULL,
-       NULL,
-       NULL,                     /* chown */
-       NULL,
-       NULL,                     /* chdir */
-       NULL,                     /* getwd */
-       NULL,                     /* utime */
-       NULL,                     /* ftruncate */
-       NULL,                     /* lock */
-       NULL,                     /* fget_nt_acl */
-       NULL,                     /* get_nt_acl */
-       NULL,                     /* fset_nt_acl */
-       NULL,                      /* set_nt_acl */
-       NULL,
-       NULL
+       NULL,                                   /* open */
+       NULL,                                   /* close */
+       NULL,                                   /* read  */
+       NULL,                                   /* write */
+       NULL,                                   /* lseek */
+       NULL,                                   /* rename */
+       NULL,                                   /* fsync */
+       NULL,                                   /* stat  */
+       NULL,                                   /* fstat */
+       NULL,                                   /* lstat */
+       NULL,                                   /* unlink */
+       NULL,                                   /* chmod */
+       NULL,                                   /* fchmod */
+       NULL,                                   /* chown */
+       NULL,                                   /* fchown */
+       NULL,                                   /* chdir */
+       NULL,                                   /* getwd */
+       NULL,                                   /* utime */
+       NULL,                                   /* ftruncate */
+       NULL,                                   /* lock */
+       NULL,                                   /* symlink */
+       NULL,                                   /* readlink */
+       NULL,                                   /* link */
+       NULL,                                   /* mknod */
+       NULL,                                   /* realpath */
+
+       /* NT ACL operations */
+
+       NULL,                                   /* fget_nt_acl */
+       NULL,                                   /* get_nt_acl */
+       NULL,                                   /* fset_nt_acl */
+       NULL,                                   /* set_nt_acl */
+
+       /* POSIX ACL operations. */
+
+       NULL,                                   /* chmod_acl */
+       NULL,                                   /* fchmod_acl */
+       NULL,                                   /* sys_acl_get_entry */
+       NULL,                                   /* sys_acl_get_tag_type */
+       NULL,                                   /* sys_acl_get_permset */
+       NULL,                                   /* sys_acl_get_qualifier */
+       NULL,                                   /* sys_acl_get_file */
+       NULL,                                   /* sys_acl_get_fd */
+       NULL,                                   /* sys_acl_clear_perms */
+       NULL,                                   /* sys_acl_add_perm */
+       NULL,                                   /* sys_acl_to_text */
+       NULL,                                   /* sys_acl_init */
+       NULL,                                   /* sys_acl_create_entry */
+       NULL,                                   /* sys_acl_set_tag_type */
+       NULL,                                   /* sys_acl_set_qualifier */
+       NULL,                                   /* sys_acl_set_permset */
+       NULL,                                   /* sys_acl_valid */
+       NULL,                                   /* sys_acl_set_file */
+       NULL,                                   /* sys_acl_set_fd */
+       NULL,                                   /* sys_acl_delete_def_file */
+       NULL,                                   /* sys_acl_get_perm */
+       NULL,                                   /* sys_acl_free_text */
+       NULL,                                   /* sys_acl_free_acl */
+       NULL                                    /* sys_acl_free_qualifier */
 };
 
 
@@ -297,10 +330,20 @@ BOOL get_parameter_value(char *param, char *value)
 /* VFS initialisation function.  Return initialised vfs_ops structure
    back to SAMBA. */
 
-struct vfs_ops *vfs_init(int *vfs_version)
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
 {
+       struct vfs_ops tmp_ops;
+
        *vfs_version = SMB_VFS_INTERFACE_VERSION;
        
+       memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+       /* Override the ones we want. */
+       tmp_ops.connect = block_connect;
+       tmp_ops.disconnect = block_disconnect;
+       tmp_ops.opendir = block_opendir;
+
+       memcpy(&execute_vfs_ops, &tmp_ops, sizeof(struct vfs_ops));
        return(&execute_vfs_ops);
 }
 
@@ -457,90 +500,3 @@ BOOL dir_search(char *link, char *dir)
        return FALSE;
        
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/VFS/recycle.c b/examples/VFS/recycle.c
new file mode 100644 (file)
index 0000000..4e032bb
--- /dev/null
@@ -0,0 +1,284 @@
+/* 
+ * Auditing VFS module for samba.  Log selected file operations to syslog
+ * facility.
+ *
+ * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>.
+ * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module.
+ *
+ * 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 "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <syslog.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <includes.h>
+#include <vfs.h>
+/* VFS operations */
+
+extern struct vfs_ops default_vfs_ops;   /* For passthrough operation */
+
+static int recycle_unlink(connection_struct *, const char *);
+static int recycle_connect(struct connection_struct *conn, const char *service, const char *user);
+static void recycle_disconnect(struct connection_struct *conn);
+
+struct vfs_ops recycle_ops = {
+    
+       /* Disk operations */
+
+       recycle_connect,                /* connect */
+       recycle_disconnect,             /* disconnect */
+       NULL,                           /* disk free */
+
+       /* Directory operations */
+
+       NULL,                           /* opendir */
+       NULL,                           /* readdir */
+       NULL,                           /* mkdir */
+       NULL,                           /* rmdir */
+       NULL,                           /* closedir */
+
+       /* File operations */
+
+       NULL,                           /* open */
+       NULL,                           /* close */
+       NULL,                           /* read  */
+       NULL,                           /* write */
+       NULL,                           /* lseek */
+       NULL,                           /* rename */
+       NULL,                           /* fsync */
+       NULL,                           /* stat  */
+       NULL,                           /* fstat */
+       NULL,                           /* lstat */
+       recycle_unlink,
+       NULL,                           /* chmod */
+       NULL,                           /* fchmod */
+       NULL,                           /* chown */
+       NULL,                           /* fchown */
+       NULL,                           /* chdir */
+       NULL,                           /* getwd */
+       NULL,                           /* utime */
+       NULL,                           /* ftruncate */
+       NULL,                           /* lock */
+       NULL,                           /* symlink */
+       NULL,                           /* readlink */
+       NULL,                           /* link */
+       NULL,                           /* mknod */
+       NULL,                           /* realpath */
+       NULL,                           /* fget_nt_acl */
+       NULL,                           /* get_nt_acl */
+       NULL,                           /* fset_nt_acl */
+       NULL,                           /* set_nt_acl */
+
+       NULL,                           /* chmod_acl */
+       NULL,                           /* fchmod_acl */
+
+       NULL,                           /* sys_acl_get_entry */
+       NULL,                           /* sys_acl_get_tag_type */
+       NULL,                           /* sys_acl_get_permset */
+       NULL,                           /* sys_acl_get_qualifier */
+       NULL,                           /* sys_acl_get_file */
+       NULL,                           /* sys_acl_get_fd */
+       NULL,                           /* sys_acl_clear_perms */
+       NULL,                           /* sys_acl_add_perm */
+       NULL,                           /* sys_acl_to_text */
+       NULL,                           /* sys_acl_init */
+       NULL,                           /* sys_acl_create_entry */
+       NULL,                           /* sys_acl_set_tag_type */
+       NULL,                           /* sys_acl_set_qualifier */
+       NULL,                           /* sys_acl_set_permset */
+       NULL,                           /* sys_acl_valid */
+       NULL,                           /* sys_acl_set_file */
+       NULL,                           /* sys_acl_set_fd */
+       NULL,                           /* sys_acl_delete_def_file */
+       NULL,                           /* sys_acl_get_perm */
+       NULL,                           /* sys_acl_free_text */
+       NULL,                           /* sys_acl_free_acl */
+       NULL                            /* sys_acl_free_qualifier */
+};
+
+/* VFS initialisation function.  Return initialised vfs_ops structure
+   back to SAMBA. */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+       struct vfs_ops tmp_ops;
+
+       *vfs_version = SMB_VFS_INTERFACE_VERSION;
+       memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+       tmp_ops.unlink = recycle_unlink;
+       tmp_ops.connect = recycle_connect;
+       tmp_ops.disconnect = recycle_disconnect;
+       memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops));
+       return &recycle_ops;
+}
+
+static int recycle_connect(struct connection_struct *conn, const char *service, const char *user)
+{
+       pstring opts_str;
+       fstring recycle_bin;
+       char *p;
+
+       DEBUG(3,("recycle_connect: called for service %s as user %s\n", service, user));
+
+       pstrcpy(opts_str, (const char *)lp_vfs_options(SNUM(conn)));
+       if (!*opts_str) {
+               DEBUG(3,("recycle_connect: No options listed (%s).\n", lp_vfs_options(SNUM(conn)) ));
+               return 0; /* No options. */
+       }
+
+       p = opts_str;
+       if (next_token(&p,recycle_bin,"=",sizeof(recycle_bin))) {
+               if (!strequal("recycle", recycle_bin)) {
+                       DEBUG(3,("recycle_connect: option %s is not recycle\n", recycle_bin ));
+                       return -1;
+               }
+       }
+
+       if (!next_token(&p,recycle_bin," \n",sizeof(recycle_bin))) {
+               DEBUG(3,("recycle_connect: no option after recycle=\n"));
+               return -1;
+       }
+
+       DEBUG(10,("recycle_connect: recycle name is %s\n", recycle_bin ));
+
+       conn->vfs_private = (void *)strdup(recycle_bin);
+       return 0;
+}
+
+static void recycle_disconnect(struct connection_struct *conn)
+{
+       SAFE_FREE(conn->vfs_private);
+}
+
+static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir)
+{
+        SMB_STRUCT_STAT st;
+
+        if (default_vfs_ops.stat(conn,dname,&st) != 0)
+                return(False);
+
+       if (isdir)
+               return S_ISDIR(st.st_mode) ? True : False;
+       else
+               return S_ISREG(st.st_mode) ? True : False;
+}
+
+static BOOL recycle_directory_exist(connection_struct *conn, const char *dname)
+{
+       return recycle_XXX_exist(conn, dname, True);
+}
+
+static BOOL recycle_file_exist(connection_struct *conn, const char *fname)
+{
+       return recycle_XXX_exist(conn, fname, False);
+}
+
+static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname)
+{
+        SMB_STRUCT_STAT st;
+
+        if (default_vfs_ops.stat(conn,fname,&st) != 0)
+               return (SMB_OFF_T)-1;
+
+       return(st.st_size);
+}
+
+/********************************************************************
+ Check if file should be recycled
+*********************************************************************/
+
+static int recycle_unlink(connection_struct *conn, const char *inname)
+{
+       fstring recycle_bin;
+       pstring fname;
+       char *base, *ext;
+       pstring bin;
+       int i=1, len, addlen;
+       int dir_mask=0700;
+       SMB_BIG_UINT dfree,dsize,bsize;
+
+       *recycle_bin = '\0';
+       pstrcpy(fname, inname);
+
+       if (conn->vfs_private)
+               fstrcpy(recycle_bin, (const char *)conn->vfs_private);
+
+       if(!*recycle_bin) {
+               DEBUG(3, ("recycle bin: share parameter not set, purging %s...\n", fname));
+               return default_vfs_ops.unlink(conn,fname);
+       }
+
+       if(recycle_get_file_size(conn, fname) == 0) {
+               DEBUG(3, ("recycle bin: file %s is empty, purging...\n", fname));
+               return default_vfs_ops.unlink(conn,fname);
+       }
+
+       base = strrchr(fname, '/') + 1;
+       if(base == (char*)1)
+               ext = strrchr(fname, '.');
+       else
+               ext = strrchr(base, '.');
+
+       pstrcpy(bin, recycle_bin);
+       pstrcat(bin, "/");
+       pstrcat(bin, base);
+
+       if(strcmp(fname,bin) == 0) {
+               DEBUG(3, ("recycle bin: file %s exists, purging...\n", fname));
+               return default_vfs_ops.unlink(conn,fname);
+       }
+
+       len = strlen(bin);
+       addlen = sizeof(pstring)-len-1;
+       while(recycle_file_exist(conn,bin)) {
+               slprintf(bin+len, addlen, " (Copy #%d)", i++);
+               pstrcat(bin, ext);
+       }
+
+       DEBUG(3, ("recycle bin: moving source=%s to  dest=%s\n", fname, bin));
+       default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
+       if((unsigned int)dfree > 0) {
+               int ret;
+               if(!recycle_directory_exist(conn,recycle_bin)) {
+                       DEBUG(3, ("recycle bin: directory %s nonexistant, creating...\n", recycle_bin));
+                       if (default_vfs_ops.mkdir(conn,recycle_bin,dir_mask) == -1) {
+                               DEBUG(3, ("recycle bin: unable to create directory %s. Error was %s\n",
+                                       recycle_bin, strerror(errno) ));
+                       }
+               }
+               DEBUG(3, ("recycle bin: move %s -> %s\n", fname, bin));
+
+               ret = default_vfs_ops.rename(conn, fname, bin);
+               if (ret == -1)
+                       DEBUG(3, ("recycle bin: move error %d (%s)\n", errno, strerror(errno) ));
+               return ret;
+       } else { 
+               DEBUG(3, ("recycle bin: move failed, purging...\n"));
+               return default_vfs_ops.unlink(conn,fname);
+       }
+}
index 9bb84fe2b1c190d7b76e83171a3eb90ebbe4899d..bb5486e690b17ce7d886febbcd02e330894b72ef 100644 (file)
 #include <includes.h>
 #include <vfs.h>
 
-/* Function prototypes */
-
-    /* Disk operations */
-
-    int skel_connect(struct connection_struct *conn, char *service, char *user);    void skel_disconnect(struct connection_struct *conn);
-    SMB_BIG_UINT skel_disk_free(struct connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize,
-                              SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
-
-    /* Directory operations */
-
-    DIR *skel_opendir(struct connection_struct *conn, char *fname);
-    struct dirent *skel_readdir(struct connection_struct *conn, DIR *dirp);
-    int skel_mkdir(struct connection_struct *conn, char *path, mode_t mode);
-    int skel_rmdir(struct connection_struct *conn, char *path);
-    int skel_closedir(struct connection_struct *conn, DIR *dir);
-
-    /* File operations */
-
-    int skel_open(struct connection_struct *conn, char *fname, int flags, mode_t mode);
-    int skel_close(struct files_struct *fsp, int fd);
-    ssize_t skel_read(struct files_struct *fsp, int fd, char *data, size_t n);
-    ssize_t skel_write(struct files_struct *fsp, int fd, char *data, size_t n);
-    SMB_OFF_T skel_lseek(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
-    int skel_rename(struct connection_struct *conn, char *old, char *new);
-    int skel_fsync(struct files_struct *fsp, int fd);
-    int skel_stat(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
-    int skel_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
-    int skel_lstat(struct connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf);
-    int skel_unlink(struct connection_struct *conn, char *path);
-    int skel_chmod(struct connection_struct *conn, char *path, mode_t mode);
-        int skel_chown(struct connection_struct *conn, char *path, uid_t uid, gid_t gid);
-        int skel_chdir(struct connection_struct *conn, char *path);
-        char *skel_getwd(struct connection_struct *conn, char *buf);
-    int skel_utime(struct connection_struct *conn, char *path, struct utimbuf *times);
-        int skel_ftruncate(struct files_struct *fsp, int fd, SMB_OFF_T offset);
-        BOOL skel_lock(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
-
-    /* NT file access control list operations */
-
-        size_t skel_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc);
-        size_t skel_get_nt_acl(struct files_struct *fsp, char *name, struct security_descriptor_info **ppdesc);
-        BOOL skel_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
-        BOOL skel_set_nt_acl(struct files_struct *fsp, char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
-
-
-/* VFS operations structure */
-
-struct vfs_ops skel_ops = {
-
-       /* Disk operations */
-
-       skel_connect,
-       skel_disconnect,
-       skel_disk_free,
-       
-       /* Directory operations */
-
-       skel_opendir,
-       skel_readdir,
-       skel_mkdir,
-       skel_rmdir,
-       skel_closedir,
-
-       /* File operations */
-
-       skel_open,
-       skel_close,
-       skel_read,
-       skel_write,
-       skel_lseek,
-       skel_rename,
-       skel_fsync,
-       skel_stat,
-       skel_fstat,
-       skel_lstat,
-       skel_unlink,
-       skel_chmod,
-        skel_chown,
-        skel_chdir,
-        skel_getwd,
-       skel_utime,
-       skel_ftruncate,
-       skel_lock,
-
-       /* NT File ACL operations */
-
-        skel_fget_nt_acl,
-        skel_get_nt_acl,
-        skel_fset_nt_acl,
-        skel_set_nt_acl
-};
-
-/* VFS initialisation - return vfs_ops function pointer structure */
-
-struct vfs_ops *vfs_init(int *vfs_version)
-{
-       *vfs_version = SMB_VFS_INTERFACE_VERSION;
-       return(&skel_ops);
-}
-
-/* Implementation of VFS functions.  Insert your useful stuff here */
-
 extern struct vfs_ops default_vfs_ops;   /* For passthrough operation */
+extern struct vfs_ops skel_ops;
 
-int skel_connect(struct connection_struct *conn, char *service, char *user)    
+static int skel_connect(struct connection_struct *conn, const char *service, const char *user)    
 {
        return default_vfs_ops.connect(conn, service, user);
 }
 
-void skel_disconnect(struct connection_struct *conn)
+static void skel_disconnect(struct connection_struct *conn)
 {
        default_vfs_ops.disconnect(conn);
 }
 
-SMB_BIG_UINT skel_disk_free(struct connection_struct *conn, char *path,
+static SMB_BIG_UINT skel_disk_free(struct connection_struct *conn, const char *path,
        BOOL small_query, SMB_BIG_UINT *bsize,
        SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
@@ -160,138 +59,462 @@ SMB_BIG_UINT skel_disk_free(struct connection_struct *conn, char *path,
                                         dfree, dsize);
 }
 
-DIR *skel_opendir(struct connection_struct *conn, char *fname)
+static DIR *skel_opendir(struct connection_struct *conn, const char *fname)
 {
        return default_vfs_ops.opendir(conn, fname);
 }
 
-struct dirent *skel_readdir(struct connection_struct *conn, DIR *dirp)
+static struct dirent *skel_readdir(struct connection_struct *conn, DIR *dirp)
 {
        return default_vfs_ops.readdir(conn, dirp);
 }
 
-int skel_mkdir(struct connection_struct *conn, char *path, mode_t mode)
+static int skel_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
 {
        return default_vfs_ops.mkdir(conn, path, mode);
 }
 
-int skel_rmdir(struct connection_struct *conn, char *path)
+static int skel_rmdir(struct connection_struct *conn, const char *path)
 {
        return default_vfs_ops.rmdir(conn, path);
 }
 
-int skel_closedir(struct connection_struct *conn, DIR *dir)
+static int skel_closedir(struct connection_struct *conn, DIR *dir)
 {
        return default_vfs_ops.closedir(conn, dir);
 }
 
-int skel_open(struct connection_struct *conn, char *fname, int flags, mode_t mode)
+static int skel_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
 {
        return default_vfs_ops.open(conn, fname, flags, mode);
 }
 
-int skel_close(struct files_struct *fsp, int fd)
+static int skel_close(struct files_struct *fsp, int fd)
 {
        return default_vfs_ops.close(fsp, fd);
 }
 
-ssize_t skel_read(struct files_struct *fsp, int fd, char *data, size_t n)
+static ssize_t skel_read(struct files_struct *fsp, int fd, void *data, size_t n)
 {
        return default_vfs_ops.read(fsp, fd, data, n);
 }
 
-ssize_t skel_write(struct files_struct *fsp, int fd, char *data, size_t n)
+static ssize_t skel_write(struct files_struct *fsp, int fd, const void *data, size_t n)
 {
        return default_vfs_ops.write(fsp, fd, data, n);
 }
 
-SMB_OFF_T skel_lseek(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
+static SMB_OFF_T skel_lseek(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
 {
        return default_vfs_ops.lseek(fsp, filedes, offset, whence);
 }
 
-int skel_rename(struct connection_struct *conn, char *old, char *new)
+static int skel_rename(struct connection_struct *conn, const char *old, const char *new)
 {
        return default_vfs_ops.rename(conn, old, new);
 }
 
-int skel_fsync(struct files_struct *fsp, int fd)
+static int skel_fsync(struct files_struct *fsp, int fd)
 {
        return default_vfs_ops.fsync(fsp, fd);
 }
 
-int skel_stat(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf)
+static int skel_stat(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
 {
        return default_vfs_ops.stat(conn, fname, sbuf);
 }
 
-int skel_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+static int skel_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
 {
        return default_vfs_ops.fstat(fsp, fd, sbuf);
 }
 
-int skel_lstat(struct connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf)
+static int skel_lstat(struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
 {
        return default_vfs_ops.lstat(conn, path, sbuf);
 }
 
-int skel_unlink(struct connection_struct *conn, char *path)
+static int skel_unlink(struct connection_struct *conn, const char *path)
 {
        return default_vfs_ops.unlink(conn, path);
 }
 
-int skel_chmod(struct connection_struct *conn, char *path, mode_t mode)
+static int skel_chmod(struct connection_struct *conn, const char *path, mode_t mode)
 {
        return default_vfs_ops.chmod(conn, path, mode);
 }
 
-int skel_chown(struct connection_struct *conn, char *path, uid_t uid, gid_t gid)
+static int skel_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+{
+       return default_vfs_ops.fchmod(fsp, fd, mode);
+}
+
+static int skel_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
 {
        return default_vfs_ops.chown(conn, path, uid, gid);
 }
 
-int skel_chdir(struct connection_struct *conn, char *path)
+static int skel_fchown(struct files_struct *fsp, int fd, uid_t uid, gid_t gid)
+{
+       return default_vfs_ops.fchown(fsp, fd, uid, gid);
+}
+
+static int skel_chdir(struct connection_struct *conn, const char *path)
 {
        return default_vfs_ops.chdir(conn, path);
 }
 
-char *skel_getwd(struct connection_struct *conn, char *buf)
+static char *skel_getwd(struct connection_struct *conn, char *buf)
 {
        return default_vfs_ops.getwd(conn, buf);
 }
 
-int skel_utime(struct connection_struct *conn, char *path, struct utimbuf *times)
+static int skel_utime(struct connection_struct *conn, const char *path, struct utimbuf *times)
 {
        return default_vfs_ops.utime(conn, path, times);
 }
 
-int skel_ftruncate(struct files_struct *fsp, int fd, SMB_OFF_T offset)
+static int skel_ftruncate(struct files_struct *fsp, int fd, SMB_OFF_T offset)
 {
        return default_vfs_ops.ftruncate(fsp, fd, offset);
 }
 
-BOOL skel_lock(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+static BOOL skel_lock(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
        return default_vfs_ops.lock(fsp, fd, op, offset, count, type);
 }
 
-size_t skel_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc)
+static BOOL skel_symlink(struct connection_struct *conn, const char *oldpath, const char *newpath)
+{
+       return default_vfs_ops.symlink(conn, oldpath, newpath);
+}
+
+static BOOL skel_readlink(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz)
+{
+       return default_vfs_ops.readlink(conn, path, buf, bufsiz);
+}
+
+static int skel_link(struct connection_struct *conn, const char *oldpath, const char *newpath)
+{
+       return default_vfs_ops.link(conn, oldpath, newpath);
+}
+
+static int skel_mknod(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
+{
+       return default_vfs_ops.mknod(conn, path, mode, dev);
+}
+
+static char *skel_realpath(struct connection_struct *conn, const char *path, char *resolved_path)
+{
+       return default_vfs_ops.realpath(conn, path, resolved_path);
+}
+
+static size_t skel_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc)
 {
        return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc);
 }
 
-size_t skel_get_nt_acl(struct files_struct *fsp, char *name, struct security_descriptor_info **ppdesc)
+static size_t skel_get_nt_acl(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc)
 {
        return default_vfs_ops.get_nt_acl(fsp, name, ppdesc);
 }
 
-BOOL skel_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
+static BOOL skel_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
 {
        return default_vfs_ops.fset_nt_acl(fsp, fd, security_info_sent, psd);
 }
 
-BOOL skel_set_nt_acl(struct files_struct *fsp, char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
+static BOOL skel_set_nt_acl(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
 {
        return default_vfs_ops.set_nt_acl(fsp, name, security_info_sent, psd);
 }
 
+static BOOL skel_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode)
+{
+       return default_vfs_ops.chmod_acl(conn, name, mode);
+}
+
+static BOOL skel_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+{
+       return default_vfs_ops.fchmod_acl(fsp, fd, mode);
+}
+
+static int skel_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+       return default_vfs_ops.sys_acl_get_entry(conn, theacl, entry_id, entry_p);
+}
+
+static int skel_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+{
+       return default_vfs_ops.sys_acl_get_tag_type(conn, entry_d, tag_type_p);
+}
+
+static int skel_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+       return default_vfs_ops.sys_acl_get_permset(conn, entry_d, permset_p);
+}
+
+static void *skel_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
+{
+       return default_vfs_ops.sys_acl_get_qualifier(conn, entry_d);
+}
+
+static SMB_ACL_T skel_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
+{
+       return default_vfs_ops.sys_acl_get_file(conn, path_p, type);
+}
+
+static SMB_ACL_T skel_sys_acl_get_fd(struct files_struct *fsp, int fd)
+{
+       return default_vfs_ops.sys_acl_get_fd(fsp, fd);
+}
+
+static int skel_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset)
+{
+       return default_vfs_ops.sys_acl_clear_perms(conn, permset);
+}
+
+static int skel_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+       return default_vfs_ops.sys_acl_add_perm(conn, permset, perm);
+}
+
+static char *skel_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
+{
+       return default_vfs_ops.sys_acl_to_text(conn, theacl, plen);
+}
+
+static SMB_ACL_T skel_sys_acl_init(struct connection_struct *conn, int count)
+{
+       return default_vfs_ops.sys_acl_init(conn, count);
+}
+
+static int skel_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+{
+       return default_vfs_ops.sys_acl_create_entry(conn, pacl, pentry);
+}
+
+static int skel_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+{
+       return default_vfs_ops.sys_acl_set_tag_type(conn, entry, tagtype);
+}
+
+static int skel_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
+{
+       return default_vfs_ops.sys_acl_set_qualifier(conn, entry, qual);
+}
+
+static int skel_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+{
+       return default_vfs_ops.sys_acl_set_permset(conn, entry, permset);
+}
+
+static int skel_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl )
+{
+       return default_vfs_ops.sys_acl_valid(conn, theacl );
+}
+
+static int skel_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+{
+       return default_vfs_ops.sys_acl_set_file(conn, name, acltype, theacl);
+}
+
+static int skel_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
+{
+       return default_vfs_ops.sys_acl_set_fd(fsp, fd, theacl);
+}
+
+static int skel_sys_acl_delete_def_file(struct connection_struct *conn, const char *path)
+{
+       return default_vfs_ops.sys_acl_delete_def_file(conn, path);
+}
+
+static int skel_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+       return default_vfs_ops.sys_acl_get_perm(conn, permset, perm);
+}
+
+static int skel_sys_acl_free_text(struct connection_struct *conn, char *text)
+{
+       return default_vfs_ops.sys_acl_free_text(conn, text);
+}
+
+static int skel_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl)
+{
+       return default_vfs_ops.sys_acl_free_acl(conn, posix_acl);
+}
+
+static int skel_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
+{
+       return default_vfs_ops.sys_acl_free_qualifier(conn, qualifier, tagtype);
+}
+
+/* VFS initialisation - return vfs_ops function pointer structure */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+       struct vfs_ops tmp_ops;
+
+       DEBUG(3, ("Initialising default vfs hooks\n"));
+
+       *vfs_version = SMB_VFS_INTERFACE_VERSION;
+       memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+       tmp_ops.connect = skel_connect;
+       tmp_ops.disconnect = skel_disconnect;
+       tmp_ops.disk_free = skel_disk_free;
+
+       /* Directory operations */
+
+       tmp_ops.opendir = skel_opendir;
+       tmp_ops.readdir = skel_readdir;
+       tmp_ops.mkdir = skel_mkdir;
+       tmp_ops.rmdir = skel_rmdir;
+       tmp_ops.closedir = skel_closedir;
+
+       /* File operations */
+
+       tmp_ops.open = skel_open;
+       tmp_ops.close = skel_close;
+       tmp_ops.read = skel_read;
+       tmp_ops.write = skel_write;
+       tmp_ops.lseek = skel_lseek;
+       tmp_ops.rename = skel_rename;
+       tmp_ops.fsync = skel_fsync;
+       tmp_ops.stat = skel_stat;
+       tmp_ops.fstat = skel_fstat;
+       tmp_ops.lstat = skel_lstat;
+       tmp_ops.unlink = skel_unlink;
+       tmp_ops.chmod = skel_chmod;
+       tmp_ops.fchmod = skel_fchmod;
+       tmp_ops.chown = skel_chown;
+       tmp_ops.fchown = skel_fchown;
+       tmp_ops.chdir = skel_chdir;
+       tmp_ops.getwd = skel_getwd;
+       tmp_ops.utime = skel_utime;
+       tmp_ops.ftruncate = skel_ftruncate;
+       tmp_ops.lock = skel_lock;
+       tmp_ops.symlink = skel_symlink;
+       tmp_ops.readlink = skel_readlink;
+       tmp_ops.link = skel_link;
+       tmp_ops.mknod = skel_mknod;
+       tmp_ops.realpath = skel_realpath;
+
+       tmp_ops.fget_nt_acl = skel_fget_nt_acl;
+       tmp_ops.get_nt_acl = skel_get_nt_acl;
+       tmp_ops.fset_nt_acl = skel_fset_nt_acl;
+       tmp_ops.set_nt_acl = skel_set_nt_acl;
+
+       /* POSIX ACL operations. */
+
+       tmp_ops.chmod_acl = skel_chmod_acl;
+       tmp_ops.fchmod_acl = skel_fchmod_acl;
+       tmp_ops.sys_acl_get_entry = skel_sys_acl_get_entry;
+       tmp_ops.sys_acl_get_tag_type = skel_sys_acl_get_tag_type;
+       tmp_ops.sys_acl_get_permset = skel_sys_acl_get_permset;
+       tmp_ops.sys_acl_get_qualifier = skel_sys_acl_get_qualifier;
+       tmp_ops.sys_acl_get_file = skel_sys_acl_get_file;
+       tmp_ops.sys_acl_get_fd = skel_sys_acl_get_fd;
+       tmp_ops.sys_acl_clear_perms = skel_sys_acl_clear_perms;
+       tmp_ops.sys_acl_add_perm = skel_sys_acl_add_perm;
+       tmp_ops.sys_acl_to_text = skel_sys_acl_to_text;
+       tmp_ops.sys_acl_init = skel_sys_acl_init;
+       tmp_ops.sys_acl_create_entry = skel_sys_acl_create_entry;
+       tmp_ops.sys_acl_set_tag_type = skel_sys_acl_set_tag_type;
+       tmp_ops.sys_acl_set_qualifier = skel_sys_acl_set_qualifier;
+       tmp_ops.sys_acl_set_permset = skel_sys_acl_set_permset;
+       tmp_ops.sys_acl_valid = skel_sys_acl_valid;
+       tmp_ops.sys_acl_set_file = skel_sys_acl_set_file;
+       tmp_ops.sys_acl_set_fd = skel_sys_acl_set_fd;
+       tmp_ops.sys_acl_delete_def_file = skel_sys_acl_delete_def_file;
+       tmp_ops.sys_acl_get_perm = skel_sys_acl_get_perm;
+       tmp_ops.sys_acl_free_text = skel_sys_acl_free_text;
+       tmp_ops.sys_acl_free_acl = skel_sys_acl_free_acl;
+       tmp_ops.sys_acl_free_qualifier = skel_sys_acl_free_qualifier;
+
+       memcpy(&skel_ops, &tmp_ops, sizeof(struct vfs_ops));
+
+       return &skel_ops;
+}
+
+/* VFS operations structure */
+
+struct vfs_ops skel_ops = {
+
+       /* Disk operations */
+
+       skel_connect,
+       skel_disconnect,
+       skel_disk_free,
+       
+       /* Directory operations */
+
+       skel_opendir,
+       skel_readdir,
+       skel_mkdir,
+       skel_rmdir,
+       skel_closedir,
+
+       /* File operations */
+
+       skel_open,
+       skel_close,
+       skel_read,
+       skel_write,
+       skel_lseek,
+       skel_rename,
+       skel_fsync,
+       skel_stat,
+       skel_fstat,
+       skel_lstat,
+       skel_unlink,
+       skel_chmod,
+       skel_fchmod,
+       skel_chown,
+       skel_fchown,
+       skel_chdir,
+       skel_getwd,
+       skel_utime,
+       skel_ftruncate,
+       skel_lock,
+       skel_symlink,
+       skel_readlink,
+       skel_link,
+       skel_mknod,
+       skel_realpath,
+
+       /* NT File ACL operations */
+
+       skel_fget_nt_acl,
+       skel_get_nt_acl,
+       skel_fset_nt_acl,
+       skel_set_nt_acl,
+
+       /* POSIX ACL operations */
+
+       skel_chmod_acl,
+       skel_fchmod_acl,
+
+       skel_sys_acl_get_entry,
+       skel_sys_acl_get_tag_type,
+       skel_sys_acl_get_permset,
+       skel_sys_acl_get_qualifier,
+       skel_sys_acl_get_file,
+       skel_sys_acl_get_fd,
+       skel_sys_acl_clear_perms,
+       skel_sys_acl_add_perm,
+       skel_sys_acl_to_text,
+       skel_sys_acl_init,
+       skel_sys_acl_create_entry,
+       skel_sys_acl_set_tag_type,
+       skel_sys_acl_set_qualifier,
+       skel_sys_acl_set_permset,
+       skel_sys_acl_valid,
+       skel_sys_acl_set_file,
+       skel_sys_acl_set_fd,
+       skel_sys_acl_delete_def_file,
+       skel_sys_acl_get_perm,
+       skel_sys_acl_free_text,
+       skel_sys_acl_free_acl,
+       skel_sys_acl_free_qualifier
+};