diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/vfs_audit.c | 232 | ||||
-rw-r--r-- | source3/modules/vfs_extd_audit.c | 241 | ||||
-rw-r--r-- | source3/modules/vfs_fake_perms.c | 240 | ||||
-rw-r--r-- | source3/modules/vfs_netatalk.c | 78 | ||||
-rw-r--r-- | source3/modules/vfs_recycle.c | 508 |
5 files changed, 493 insertions, 806 deletions
diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index 4f9dc1b1e4..ccb2d47fc4 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -2,8 +2,9 @@ * Auditing VFS module for samba. Log selected file operations to syslog * facility. * - * Copyright (C) Tim Potter, 1999-2000 - * Copyright (C) Alexander Bokovoy, 2002 + * Copyright (C) Tim Potter 1999-2000 + * Copyright (C) Alexander Bokovoy 2002 + * Copyright (C) Stefan (metze) Metzmacher 2002 * * 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 @@ -20,118 +21,111 @@ * 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> - -#ifndef SYSLOG_FACILITY -#define SYSLOG_FACILITY LOG_USER -#endif - -#ifndef SYSLOG_PRIORITY -#define SYSLOG_PRIORITY LOG_NOTICE -#endif + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS /* Function prototypes */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(struct connection_struct *conn); -static DIR *audit_opendir(struct connection_struct *conn, const char *fname); -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(struct connection_struct *conn, const char *path); -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode); -static int audit_close(struct files_struct *fsp, int fd); -static int audit_rename(struct connection_struct *conn, const char *old, const char *new); -static int audit_unlink(struct connection_struct *conn, const char *path); -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode); -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode); -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); /* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *audit_handle; - -static vfs_op_tuple audit_ops[] = { +static vfs_op_tuple audit_op_tuples[] = { /* Disk operations */ - {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, - {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, /* Directory operations */ - {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, - {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, - {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, /* File operations */ - {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, - {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, - {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, - {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, - {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int audit_syslog_facility(vfs_handle_struct *handle) { - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - audit_handle = vfs_handle; + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog facility", + * audit_enum_facility,LOG_USER); + */ + return LOG_USER; +} - openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY); - syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n"); - return audit_ops; + +static int audit_syslog_priority(vfs_handle_struct *handle) +{ + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog priority", + * audit_enum_priority,LOG_NOTICE); + */ + return LOG_NOTICE; } /* 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) +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) { - syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", + int result; + + openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle)); + + syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", svc, user); - return default_vfs_ops.connect(conn, svc, user); + result = VFS_NEXT_CONNECT(handle, conn, svc, user); + + return result; } -static void audit_disconnect(struct connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) { - syslog(SYSLOG_PRIORITY, "disconnected\n"); - default_vfs_ops.disconnect(conn); + syslog(audit_syslog_priority(handle), "disconnected\n"); + VFS_NEXT_DISCONNECT(handle, conn); + + return; } -static DIR *audit_opendir(struct connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { - DIR *result = default_vfs_ops.opendir(conn, fname); + DIR *result; + + result = VFS_NEXT_OPENDIR(handle, conn, fname); - syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n", + syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : ""); @@ -139,11 +133,13 @@ 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) +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.mkdir(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n", + int result; + + result = VFS_NEXT_MKDIR(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -151,11 +147,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_rmdir(struct connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.rmdir(conn, path); + int result; + + result = VFS_NEXT_RMDIR(handle, conn, path); - syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n", + syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -163,11 +161,13 @@ 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) +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { - int result = default_vfs_ops.open(conn, fname, flags, mode); + int result; + + result = VFS_NEXT_OPEN(handle, conn, fname, flags, mode); - syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n", + syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", (result < 0) ? "failed: " : "", @@ -176,11 +176,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla return result; } -static int audit_close(struct files_struct *fsp, int fd) +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { - int result = default_vfs_ops.close(fsp, fd); + int result; + + result = VFS_NEXT_CLOSE(handle, fsp, fd); - syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n", + syslog(audit_syslog_priority(handle), "close fd %d %s%s\n", fd, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -188,11 +190,13 @@ 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) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { - int result = default_vfs_ops.rename(conn, old, new); + int result; + + result = VFS_NEXT_RENAME(handle, conn, old, new); - syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n", + syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", old, new, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -200,11 +204,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c return result; } -static int audit_unlink(struct connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.unlink(conn, path); + int result; + + result = VFS_NEXT_UNLINK(handle, conn, path); - syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n", + syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -212,11 +218,13 @@ 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) +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod(conn, path, mode); + int result; + + result = VFS_NEXT_CHMOD(handle, conn, path, mode); - syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -224,16 +232,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { int result; - if ( !default_vfs_ops.chmod_acl ) - return 0; + result = VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); - result = default_vfs_ops.chmod_acl(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -241,11 +246,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod return result; } -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod(fsp, fd, mode); + int result; - syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n", + result = VFS_NEXT_FCHMOD(handle, fsp, fd, mode); + + syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -253,16 +260,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) return result; } -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { int result; - if ( !default_vfs_ops.fchmod_acl ) - return 0; - - result = default_vfs_ops.fchmod_acl(fsp, fd, mode); + result = VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -272,5 +276,5 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) NTSTATUS vfs_audit_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_op_tuples); } diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index ef30ca7027..c5ac2cfb4a 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -5,6 +5,7 @@ * Copyright (C) Tim Potter, 1999-2000 * Copyright (C) Alexander Bokovoy, 2002 * Copyright (C) John H Terpstra, 2003 + * Copyright (C) Stefan (metze) Metzmacher, 2003 * * 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 @@ -21,127 +22,120 @@ * 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> - -#ifndef SYSLOG_FACILITY -#define SYSLOG_FACILITY LOG_USER -#endif - -#ifndef SYSLOG_PRIORITY -#define SYSLOG_PRIORITY LOG_NOTICE -#endif + +#include "includes.h" + +static int vfs_extd_audit_debug_level = DBGC_VFS; + +#undef DBGC_CLASS +#define DBGC_CLASS vfs_extd_audit_debug_level /* Function prototypes */ -static int audit_connect(struct connection_struct *conn, const char *svc, const char *user); -static void audit_disconnect(struct connection_struct *conn); -static DIR *audit_opendir(struct connection_struct *conn, const char *fname); -static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_rmdir(struct connection_struct *conn, const char *path); -static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode); -static int audit_close(struct files_struct *fsp, int fd); -static int audit_rename(struct connection_struct *conn, const char *old, const char *new); -static int audit_unlink(struct connection_struct *conn, const char *path); -static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode); -static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode); -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode); -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode); +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user); +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode); +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd); +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new); +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path); +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode); +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode); +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode); /* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *audit_handle; - -static vfs_op_tuple audit_ops[] = { +static vfs_op_tuple audit_op_tuples[] = { /* Disk operations */ - {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, - {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER}, /* Directory operations */ - {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, - {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, - {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER}, /* File operations */ - {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, - {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, - {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, - {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, - {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, - {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, - {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, + {VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int audit_syslog_facility(vfs_handle_struct *handle) { - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - audit_handle = vfs_handle; + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog facility", + * audit_enum_facility,LOG_USER); + */ + return LOG_USER; +} - openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY); - syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n"); - return audit_ops; +static int audit_syslog_priority(vfs_handle_struct *handle) +{ + /* fix me: let this be configurable by: + * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog priority", + * audit_enum_priority,LOG_NOTICE); + */ + return LOG_NOTICE; } /* 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) +static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user) { - syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", + int result; + + openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle)); + + syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", svc, user); DEBUG(10, ("Connected to service %s as user %s\n", svc, user)); - return default_vfs_ops.connect(conn, svc, user); + result = VFS_NEXT_CONNECT(handle, conn, svc, user); + + return result; } -static void audit_disconnect(struct connection_struct *conn) +static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn) { - syslog(SYSLOG_PRIORITY, "disconnected\n"); + syslog(audit_syslog_priority(handle), "disconnected\n"); DEBUG(10, ("Disconnected from VFS module extd_audit\n")); + VFS_NEXT_DISCONNECT(handle, conn); - default_vfs_ops.disconnect(conn); + return; } -static DIR *audit_opendir(struct connection_struct *conn, const char *fname) +static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { - DIR *result = default_vfs_ops.opendir(conn, fname); + DIR *result; + + result = VFS_NEXT_OPENDIR(handle, conn, fname); - syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n", + syslog(audit_syslog_priority(handle), "opendir %s %s%s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : ""); - DEBUG(1, ("vfs_extd_audit: opendir %s %s %s", + DEBUG(1, ("vfs_extd_audit: opendir %s %s %s\n", fname, (result == NULL) ? "failed: " : "", (result == NULL) ? strerror(errno) : "")); @@ -149,11 +143,13 @@ 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) +static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.mkdir(conn, path, mode); - - syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n", + int result; + + result = VFS_NEXT_MKDIR(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -165,11 +161,13 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_rmdir(struct connection_struct *conn, const char *path) +static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.rmdir(conn, path); + int result; + + result = VFS_NEXT_RMDIR(handle, conn, path); - syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n", + syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -181,11 +179,13 @@ 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) +static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { - int result = default_vfs_ops.open(conn, fname, flags, mode); + int result; + + result = VFS_NEXT_OPEN(handle, conn, fname, flags, mode); - syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n", + syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", fname, result, ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", (result < 0) ? "failed: " : "", @@ -198,11 +198,13 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla return result; } -static int audit_close(struct files_struct *fsp, int fd) +static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { - int result = default_vfs_ops.close(fsp, fd); + int result; + + result = VFS_NEXT_CLOSE(handle, fsp, fd); - syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n", + syslog(audit_syslog_priority(handle), "close fd %d %s%s\n", fd, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -214,11 +216,13 @@ 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) +static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { - int result = default_vfs_ops.rename(conn, old, new); + int result; + + result = VFS_NEXT_RENAME(handle, conn, old, new); - syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n", + syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n", old, new, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -230,11 +234,13 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c return result; } -static int audit_unlink(struct connection_struct *conn, const char *path) +static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result = default_vfs_ops.unlink(conn, path); + int result; + + result = VFS_NEXT_UNLINK(handle, conn, path); - syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n", + syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", path, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -246,11 +252,13 @@ 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) +static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod(conn, path, mode); + int result; - syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n", + result = VFS_NEXT_CHMOD(handle, conn, path, mode); + + syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -262,11 +270,13 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t return result; } -static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode) +static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result = default_vfs_ops.chmod_acl(conn, path, mode); + int result; + + result = VFS_NEXT_CHMOD_ACL(handle, conn, path, mode); - syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n", path, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -278,11 +288,13 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod return result; } -static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod(fsp, fd, mode); + int result; + + result = VFS_NEXT_FCHMOD(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -294,11 +306,13 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode) return result; } -static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) +static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { - int result = default_vfs_ops.fchmod_acl(fsp, fd, mode); + int result; + + result = VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode); - syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n", + syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", fsp->fsp_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -312,5 +326,18 @@ static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) NTSTATUS vfs_extd_audit_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_init); + NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples); + + if (NT_STATUS_IS_ERR(ret)) + return ret; + + vfs_extd_audit_debug_level = debug_add_class("extd_audit"); + if (vfs_extd_audit_debug_level == -1) { + vfs_extd_audit_debug_level = DBGC_VFS; + DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level)); + } + + return ret; } diff --git a/source3/modules/vfs_fake_perms.c b/source3/modules/vfs_fake_perms.c index 3a18fbb730..2e1267ef1b 100644 --- a/source3/modules/vfs_fake_perms.c +++ b/source3/modules/vfs_fake_perms.c @@ -22,31 +22,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "config.h" +#include "includes.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS -#include <includes.h> -#include <vfs.h> - -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *fake_perms_handle; /* use fake_perms_handle->data for storing per-instance private data */ - -static int fake_perms_stat(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) +static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) { - int ret = default_vfs_ops.stat(conn, fname, sbuf); + int ret = -1; + + ret = VFS_NEXT_STAT(handle, conn, fname, sbuf); if (ret == 0) { extern struct current_user current_user; @@ -58,12 +43,15 @@ static int fake_perms_stat(struct connection_struct *conn, const char *fname, SM sbuf->st_uid = current_user.uid; sbuf->st_gid = current_user.gid; } + return ret; } -static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) +static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) { - int ret = default_vfs_ops.fstat(fsp, fd, sbuf); + int ret = -1; + + ret = VFS_NEXT_FSTAT(handle, fsp, fd, sbuf); if (ret == 0) { extern struct current_user current_user; @@ -78,210 +66,16 @@ static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *s return ret; } -#if 0 -static size_t fake_perms_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc) -{ - return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc); -} - -static size_t fake_perms_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); -} - -static BOOL fake_perms_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); -} - -static BOOL fake_perms_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 fake_perms_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode) -{ - return default_vfs_ops.chmod_acl(conn, name, mode); -} - -static BOOL fake_perms_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode) -{ - return default_vfs_ops.fchmod_acl(fsp, fd, mode); -} - -static int fake_perms_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 fake_perms_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 fake_perms_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 *fake_perms_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 fake_perms_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 fake_perms_sys_acl_get_fd(struct files_struct *fsp, int fd) -{ - return default_vfs_ops.sys_acl_get_fd(fsp, fd); -} - -static int fake_perms_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 fake_perms_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 *fake_perms_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 fake_perms_sys_acl_init(struct connection_struct *conn, int count) -{ - return default_vfs_ops.sys_acl_init(conn, count); -} - -static int fake_perms_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 fake_perms_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 fake_perms_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 fake_perms_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 fake_perms_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl ) -{ - return default_vfs_ops.sys_acl_valid(conn, theacl ); -} - -static int fake_perms_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 fake_perms_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 fake_perms_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 fake_perms_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 fake_perms_sys_acl_free_text(struct connection_struct *conn, char *text) -{ - return default_vfs_ops.sys_acl_free_text(conn, text); -} - -static int fake_perms_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 fake_perms_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); -} -#endif - /* VFS operations structure */ -static vfs_op_tuple fake_perms_ops[] = { - - /* NT File ACL operations */ -#if 0 - {fake_perms_fget_nt_acl, SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_get_nt_acl, SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fset_nt_acl, SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_set_nt_acl, SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, - - /* POSIX ACL operations */ +static vfs_op_tuple fake_perms_ops[] = { + {VFS_OP(fake_perms_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(fake_perms_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, - - {fake_perms_sys_acl_get_entry, SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_tag_type, SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_permset, SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_qualifier, SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_file, SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_fd, SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_clear_perms, SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_add_perm, SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_to_text, SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_init, SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_create_entry, SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_tag_type, SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_qualifier, SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_permset, SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_valid, SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_file, SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_set_fd, SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_delete_def_file, SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_get_perm, SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_text, SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_acl, SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_sys_acl_free_qualifier, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, -#endif - - {fake_perms_stat, SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT}, - {fake_perms_fstat, SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT}, - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */ - -static vfs_op_tuple *fake_perms_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) -{ - DEBUG(3, ("Initialising default vfs hooks\n")); - - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - /* Remember vfs_handle for further allocation and referencing of private - information in vfs_handle->data - */ - fake_perms_handle = vfs_handle; - return fake_perms_ops; -} - NTSTATUS vfs_fake_perms_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_ops); } diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c index 718bc2a35c..f6c33c0a33 100644 --- a/source3/modules/vfs_netatalk.c +++ b/source3/modules/vfs_netatalk.c @@ -2,6 +2,7 @@ * AppleTalk VFS module for Samba-3.x * * Copyright (C) Alexei Kotovich, 2002 + * Copyright (C) Stefan (metze) Metzmacher, 2003 * * 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 @@ -18,22 +19,10 @@ * 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 -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> -#include <includes.h> -#include <vfs.h> +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS #define APPLEDOUBLE ".AppleDouble" #define ADOUBLEMODE 0777 @@ -46,9 +35,6 @@ static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, static int atalk_unlink_file(const char *path); -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ -static struct smb_vfs_handle_struct *atalk_handle; - static int atalk_get_path_ptr(char *path) { int i = 0; @@ -187,11 +173,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path) /* Directory operations */ -DIR *atalk_opendir(struct connection_struct *conn, const char *fname) +DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname) { DIR *ret = 0; - - ret = default_vfs_ops.opendir(conn, fname); + + ret = VFS_NEXT_OPENDIR(handle, conn, fname); /* * when we try to perform delete operation upon file which has fork @@ -208,7 +194,7 @@ DIR *atalk_opendir(struct connection_struct *conn, const char *fname) return ret; } -static int atalk_rmdir(struct connection_struct *conn, const char *path) +static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) { BOOL add = False; TALLOC_CTX *ctx = 0; @@ -233,12 +219,12 @@ static int atalk_rmdir(struct connection_struct *conn, const char *path) exit_rmdir: talloc_destroy(ctx); - return default_vfs_ops.rmdir(conn, path); + return VFS_NEXT_RMDIR(handle, conn, path); } /* File operations */ -static int atalk_rename(struct connection_struct *conn, const char *old, const char *new) +static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new) { int ret = 0; char *adbl_path = 0; @@ -247,7 +233,7 @@ static int atalk_rename(struct connection_struct *conn, const char *old, const c SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.rename(conn, old, new); + ret = VFS_NEXT_RENAME(handle, conn, old, new); if (!conn || !old) return ret; @@ -270,7 +256,7 @@ exit_rename: return ret; } -static int atalk_unlink(struct connection_struct *conn, const char *path) +static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) { int ret = 0, i; char *adbl_path = 0; @@ -279,7 +265,7 @@ static int atalk_unlink(struct connection_struct *conn, const char *path) SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.unlink(conn, path); + ret = VFS_NEXT_UNLINK(handle, conn, path); if (!conn || !path) return ret; @@ -326,7 +312,7 @@ exit_unlink: return ret; } -static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t mode) +static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode) { int ret = 0; char *adbl_path = 0; @@ -335,7 +321,7 @@ static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.chmod(conn, path, mode); + ret = VFS_NEXT_CHMOD(handle, conn, path, mode); if (!conn || !path) return ret; @@ -358,7 +344,7 @@ exit_chmod: return ret; } -static int atalk_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid) +static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid) { int ret = 0; char *adbl_path = 0; @@ -367,7 +353,7 @@ static int atalk_chown(struct connection_struct *conn, const char *path, uid_t u SMB_STRUCT_STAT orig_info; TALLOC_CTX *ctx; - ret = default_vfs_ops.chown(conn, path, uid, gid); + ret = VFS_NEXT_CHOWN(handle, conn, path, uid, gid); if (!conn || !path) return ret; @@ -394,34 +380,22 @@ static vfs_op_tuple atalk_ops[] = { /* Directory operations */ - {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, /* File operations */ - {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, - {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, + {VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, /* Finish VFS operations definition */ - {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */ -static vfs_op_tuple *netatalk_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) -{ - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - - atalk_handle = vfs_handle; - - DEBUG(3, ("ATALK: vfs module loaded\n")); - return atalk_ops; -} - NTSTATUS vfs_netatalk_init(void) { - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", netatalk_init); + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", atalk_ops); } diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 87dea944ac..03e2c5eabc 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -6,6 +6,7 @@ * Copyright (C) 2002, Alexander Bokovoy - cascaded VFS adoption, * Copyright (C) 2002, Juergen Hasch - added some options. * Copyright (C) 2002, Simo Sorce + * Copyright (C) 2002, Stefan (metze) Metzmacher * * 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 @@ -30,45 +31,10 @@ static int vfs_recycle_debug_level = DBGC_VFS; #undef DBGC_CLASS #define DBGC_CLASS vfs_recycle_debug_level - -static const char *delimiter = "|"; /* delimiter for options */ - -/* One per connection */ - -typedef struct recycle_bin_struct -{ - TALLOC_CTX *mem_ctx; - char *repository; /* name of the recycle bin directory */ - BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */ - BOOL versions; /* create versions of deleted files with identical name */ - BOOL touch; /* touch access date of deleted file */ - char *exclude; /* which files to exclude */ - char *exclude_dir; /* which directories to exclude */ - char *noversions; /* which files to exclude from versioning */ - SMB_OFF_T maxsize; /* maximum file size to be saved */ -} recycle_bin_struct; - -typedef struct recycle_bin_connections { - int conn; - recycle_bin_struct *data; - struct recycle_bin_connections *next; -} recycle_bin_connections; - -typedef struct recycle_bin_private_data { - TALLOC_CTX *mem_ctx; - recycle_bin_connections *conns; -} recycle_bin_private_data; - -struct smb_vfs_handle_struct *recycle_bin_private_handle; - -/* VFS operations */ -static struct vfs_ops default_vfs_ops; /* For passthrough operation */ - -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); -static void recycle_disconnect(struct connection_struct *conn); -static int recycle_unlink(connection_struct *, const char *); - -#define VFS_OP(x) ((void *) x) + +static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user); +static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn); +static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name); static vfs_op_tuple recycle_ops[] = { @@ -82,179 +48,116 @@ static vfs_op_tuple recycle_ops[] = { {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; -/** - * VFS initialisation function. - * - * @retval initialised vfs_op_tuple array - **/ -static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops, - struct smb_vfs_handle_struct *vfs_handle) +static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) { - TALLOC_CTX *mem_ctx = NULL; + DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n", + service,user)); - DEBUG(10, ("Initializing VFS module recycle\n")); - memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops)); - vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin"); - if (vfs_recycle_debug_level == -1) { - vfs_recycle_debug_level = DBGC_VFS; - DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n")); - } else { - DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level)); - } - - recycle_bin_private_handle = vfs_handle; - if (!(mem_ctx = talloc_init("recycle bin data"))) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return NULL; - } + return VFS_NEXT_CONNECT(handle, conn, service, user); +} - recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data)); - if (recycle_bin_private_handle->data == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return NULL; - } - ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx; - ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL; +static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn) +{ + DEBUG(10,("recycle_disconnect() connect to service[%s].\n", + lp_servicename(SNUM(conn)))); - return recycle_ops; + VFS_NEXT_DISCONNECT(handle, conn); } -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) +static const char *recycle_repository(vfs_handle_struct *handle) { - TALLOC_CTX *ctx = NULL; - recycle_bin_struct *recbin; - recycle_bin_connections *recconn; - recycle_bin_connections *recconnbase; - recycle_bin_private_data *recdata; - const char *tmp_str; + const char *tmp_str = NULL; + - DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user)); + tmp_str = lp_parm_const_string(SNUM(handle->conn), "recycle", "repository",".recycle"); - if (recycle_bin_private_handle) - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - else { - DEBUG(0, ("Recycle bin not initialized!\n")); - return -1; - } + DEBUG(10, ("recycle: repository = %s\n", tmp_str)); + + return tmp_str; +} - if (!(ctx = talloc_init("recycle bin connection"))) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return -1; - } +static BOOL recycle_keep_dir_tree(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "keeptree", False); - recbin = talloc_zero(ctx, sizeof(recycle_bin_struct)); - if (recbin == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - return -1; - } - recbin->mem_ctx = ctx; - - /* parse configuration options */ - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "repository", ".recycle")) != NULL) { - recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str); - ALLOC_CHECK(recbin->repository, error); - trim_string(recbin->repository, "/", "/"); - DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository)); - } else { - DEBUG(0,("recycle.bin: no repository found (fail) !\n")); - goto error; - } + DEBUG(10, ("recycle_bin: keeptree = %s\n", ret?"True":"False")); - recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False); - DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree)); + return ret; +} + +static BOOL recycle_versions(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "versions", False); + + DEBUG(10, ("recycle: versions = %s\n", ret?"True":"False")); - recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False); - DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions)); + return ret; +} + +static BOOL recycle_touch(vfs_handle_struct *handle) +{ + BOOL ret; + + ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch", False); + + DEBUG(10, ("recycle: touch = %s\n", ret?"True":"False")); - recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False); - DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch)); + return ret; +} - recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize" , 0); - if (recbin->maxsize == 0) { - recbin->maxsize = -1; - DEBUG(5, ("recycle.bin: maxsize = -infinite-\n")); - } else { - DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize)); - } +static const char **recycle_exclude(vfs_handle_struct *handle) +{ + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude", NULL); - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude", "")) != NULL) { - recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->exclude, error); - DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude)); - } - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir", "")) != NULL) { - recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->exclude_dir, error); - DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir)); - } - if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "noversions", "")) != NULL) { - recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str); - ALLOC_CHECK(recbin->noversions, error); - DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions)); - } + DEBUG(10, ("recycle: exclude = %s ...\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; +} - recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections)); - if (recconn == NULL) { - DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); - goto error; - } - recconn->conn = SNUM(conn); - recconn->data = recbin; - recconn->next = NULL; - if (recdata->conns) { - recconnbase = recdata->conns; - while (recconnbase->next != NULL) recconnbase = recconnbase->next; - recconnbase->next = recconn; - } else { - recdata->conns = recconn; - } - return default_vfs_ops.connect(conn, service, user); +static const char **recycle_exclude_dir(vfs_handle_struct *handle) +{ + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude_dir", NULL); -error: - talloc_destroy(ctx); - return -1; + DEBUG(10, ("recycle: exclude_dir = %s ...\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; } -static void recycle_disconnect(struct connection_struct *conn) +static const char **recycle_noversions(vfs_handle_struct *handle) { - recycle_bin_private_data *recdata; - recycle_bin_connections *recconn; + const char **tmp_lp; + + tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "noversions", NULL); - DEBUG(10, ("Disconnecting VFS module recycle bin\n")); + DEBUG(10, ("recycle: noversions = %s\n", tmp_lp?*tmp_lp:"")); + + return tmp_lp; +} - if (recycle_bin_private_handle) - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - else { - DEBUG(0, ("Recycle bin not initialized!\n")); - return; - } +static int recycle_maxsize(vfs_handle_struct *handle) +{ + int maxsize; + + maxsize = lp_parm_int(SNUM(handle->conn), "recycle", "maxsize", -1); - if (recdata) { - if (recdata->conns) { - if (recdata->conns->conn == SNUM(conn)) { - talloc_destroy(recdata->conns->data->mem_ctx); - recdata->conns = recdata->conns->next; - } else { - recconn = recdata->conns; - while (recconn->next) { - if (recconn->next->conn == SNUM(conn)) { - talloc_destroy(recconn->next->data->mem_ctx); - recconn->next = recconn->next->next; - break; - } - recconn = recconn->next; - } - } - } - } - default_vfs_ops.disconnect(conn); + DEBUG(10, ("recycle: maxsize = %d\n", maxsize)); + + return maxsize; } -static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) +static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, dname, &st) == 0) { + if (VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) { if (S_ISDIR(st.st_mode)) { return True; } @@ -263,11 +166,11 @@ static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) return False; } -static BOOL recycle_file_exist(connection_struct *conn, const char *fname) +static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, fname, &st) == 0) { + if (VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) { if (S_ISREG(st.st_mode)) { return True; } @@ -282,13 +185,15 @@ static BOOL recycle_file_exist(connection_struct *conn, const char *fname) * @param fname file name * @return size in bytes **/ -static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) +static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; - if (default_vfs_ops.stat(conn, fname, &st) != 0) { - DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno))); + + if (VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return (SMB_OFF_T)0; } + return(st.st_size); } @@ -298,7 +203,7 @@ static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fnam * @param dname Directory tree to be created * @return Returns True for success **/ -static BOOL recycle_create_dir(connection_struct *conn, const char *dname) +static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname) { int len; mode_t mode; @@ -322,18 +227,18 @@ static BOOL recycle_create_dir(connection_struct *conn, const char *dname) /* Create directory tree if neccessary */ for(token = strtok(tok_str, "/"); token; token = strtok(NULL, "/")) { safe_strcat(new_dir, token, len); - if (recycle_directory_exist(conn, new_dir)) - DEBUG(10, ("recycle.bin: dir %s already exists\n", new_dir)); + if (recycle_directory_exist(handle, new_dir)) + DEBUG(10, ("recycle: dir %s already exists\n", new_dir)); else { - DEBUG(5, ("recycle.bin: creating new dir %s\n", new_dir)); - if (default_vfs_ops.mkdir(conn, new_dir, mode) != 0) { - DEBUG(1,("recycle.bin: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); + DEBUG(5, ("recycle: creating new dir %s\n", new_dir)); + if (VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) { + DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); ret = False; goto done; } } safe_strcat(new_dir, "/", len); - } + } ret = True; done: @@ -348,30 +253,22 @@ done: * @param needle string to be matched exactly to haystack * @return True if found **/ -static BOOL checkparam(const char *haystack, const char *needle) +static BOOL checkparam(const char **haystack_list, const char *needle) { - char *token; - char *tok_str; - char *tmp_str; - BOOL ret = False; + int i; - if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) { + if (haystack_list == NULL || haystack_list[0] == NULL || + *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') { return False; } - tmp_str = strdup(haystack); - ALLOC_CHECK(tmp_str, done); - token = tok_str = tmp_str; - - for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) { - if(strcmp(token, needle) == 0) { - ret = True; - goto done; + for(i=0; haystack_list[i] ; i++) { + if(strequal(haystack_list[i], needle)) { + return True; } } -done: - SAFE_FREE(tmp_str); - return ret; + + return False; } /** @@ -380,110 +277,87 @@ done: * @param needle string to be matched exectly to haystack including pattern matching * @return True if found **/ -static BOOL matchparam(const char *haystack, const char *needle) +static BOOL matchparam(const char **haystack_list, const char *needle) { - char *token; - char *tok_str; - char *tmp_str; - BOOL ret = False; + int i; - if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) { + if (haystack_list == NULL || haystack_list[0] == NULL || + *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') { return False; } - tmp_str = strdup(haystack); - ALLOC_CHECK(tmp_str, done); - token = tok_str = tmp_str; - - for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) { - if (!unix_wild_match(token, needle)) { - ret = True; - goto done; + for(i=0; haystack_list[i] ; i++) { + if(!unix_wild_match((char *)haystack_list[i], (char *)needle)) { + return True; } } -done: - SAFE_FREE(tmp_str); - return ret; + + return False; } /** * Touch access date **/ -static void recycle_touch(connection_struct *conn, const char *fname) +static void recycle_do_touch(vfs_handle_struct *handle, const char *fname) { SMB_STRUCT_STAT st; struct utimbuf tb; time_t currtime; - - if (default_vfs_ops.stat(conn, fname, &st) != 0) { - DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno))); + + if (VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } currtime = time(&currtime); tb.actime = currtime; tb.modtime = st.st_mtime; - if (default_vfs_ops.utime(conn, fname, &tb) == -1 ) - DEBUG(0, ("recycle.bin: touching %s failed, reason = %s\n", fname, strerror(errno))); + if (VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) { + DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno))); } +} /** * Check if file should be recycled **/ -static int recycle_unlink(connection_struct *conn, const char *file_name) +static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name) { - recycle_bin_private_data *recdata; - recycle_bin_connections *recconn; - recycle_bin_struct *recbin; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; const char *base; - int i; -/* SMB_BIG_UINT dfree, dsize, bsize; */ + char *repository = NULL; + int i = 1; + int maxsize; SMB_OFF_T file_size; /* space_avail; */ BOOL exist; int rc = -1; - recbin = NULL; - if (recycle_bin_private_handle) { - recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data); - if (recdata) { - if (recdata->conns) { - recconn = recdata->conns; - while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next; - if (recconn != NULL) { - recbin = recconn->data; - } - } - } - } - if (recbin == NULL) { - DEBUG(0, ("Recycle bin not initialized!\n")); - rc = default_vfs_ops.unlink(conn, file_name); - goto done; - } - - if(!recbin->repository || *(recbin->repository) == '\0') { - DEBUG(3, ("Recycle path not set, purging %s...\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + repository = alloc_sub_conn(conn, (char *)recycle_repository(handle)); + ALLOC_CHECK(repository, done); + /* shouldn't we allow absolute path names here? --metze */ + trim_string(repository, "/", "/"); + + if(!repository || *(repository) == '\0') { + DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* we don't recycle the recycle bin... */ - if (strncmp(file_name, recbin->repository, strlen(recbin->repository)) == 0) { - DEBUG(3, ("File is within recycling bin, unlinking ...\n")); - rc = default_vfs_ops.unlink(conn, file_name); + if (strncmp(file_name, repository, strlen(repository)) == 0) { + DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } - file_size = recycle_get_file_size(conn, file_name); + file_size = recycle_get_file_size(handle, file_name); /* it is wrong to purge filenames only because they are empty imho * --- simo * if(fsize == 0) { - DEBUG(3, ("File %s is empty, purging...\n", file_name)); - rc = default_vfs_ops.unlink(conn,file_name); + DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name)); + rc = VFS_NEXT_UNLINK(handle,conn,file_name); goto done; } */ @@ -492,20 +366,21 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) * not greater then maxsize, not the size of the single file, also it is better * to remove older files */ - if(recbin->maxsize > 0 && file_size > recbin->maxsize) { - DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + maxsize = recycle_maxsize(handle); + if(maxsize > 0 && file_size > maxsize) { + DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation * - space_avail = default_vfs_ops.disk_free(conn, ".", True, &bsize, &dfree, &dsize) * 1024L; + space_avail = VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L; DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size)); if(space_avail < file_size) { - DEBUG(3, ("Not enough diskspace, purging file %s\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } */ @@ -524,13 +399,13 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) base++; } - DEBUG(10, ("recycle.bin: fname = %s\n", file_name)); /* original filename with path */ - DEBUG(10, ("recycle.bin: fpath = %s\n", path_name)); /* original path */ - DEBUG(10, ("recycle.bin: base = %s\n", base)); /* filename without path */ + DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */ + DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */ + DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */ - if (matchparam(recbin->exclude, base)) { - DEBUG(3, ("recycle.bin: file %s is excluded \n", base)); - rc = default_vfs_ops.unlink(conn, file_name); + if (matchparam(recycle_exclude(handle), base)) { + DEBUG(3, ("recycle: file %s is excluded \n", base)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } @@ -538,72 +413,85 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 .... * ---simo */ - if (checkparam(recbin->exclude_dir, path_name)) { - DEBUG(3, ("recycle.bin: directory %s is excluded \n", path_name)); - rc = default_vfs_ops.unlink(conn, file_name); + if (checkparam(recycle_exclude_dir(handle), path_name)) { + DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } - /* see if we need to recreate the original directory structure in the recycle bin */ - if (recbin->keep_dir_tree == True) { - asprintf(&temp_name, "%s/%s", recbin->repository, path_name); + if (recycle_keep_dir_tree(handle) == True) { + asprintf(&temp_name, "%s/%s", repository, path_name); } else { - temp_name = strdup(recbin->repository); + temp_name = strdup(repository); } ALLOC_CHECK(temp_name, done); - exist = recycle_directory_exist(conn, temp_name); + exist = recycle_directory_exist(handle, temp_name); if (exist) { - DEBUG(10, ("recycle.bin: Directory already exists\n")); + DEBUG(10, ("recycle: Directory already exists\n")); } else { - DEBUG(10, ("recycle.bin: Creating directory %s\n", temp_name)); - if (recycle_create_dir(conn, temp_name) == False) { - DEBUG(3, ("Could not create directory, purging %s...\n", file_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); + if (recycle_create_dir(handle, temp_name) == False) { + DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } } asprintf(&final_name, "%s/%s", temp_name, base); ALLOC_CHECK(final_name, done); - DEBUG(10, ("recycle.bin: recycled file name: %s\n", temp_name)); /* new filename with path */ + DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */ /* check if we should delete file from recycle bin */ - if (recycle_file_exist(conn, final_name)) { - if (recbin->versions == False || matchparam(recbin->noversions, base) == True) { - DEBUG(3, ("recycle.bin: Removing old file %s from recycle bin\n", final_name)); - if (default_vfs_ops.unlink(conn, final_name) != 0) { - DEBUG(1, ("recycle.bin: Error deleting old file: %s\n", strerror(errno))); + if (recycle_file_exist(handle, final_name)) { + if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { + DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name)); + if (VFS_NEXT_UNLINK(handle, conn, final_name) != 0) { + DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } } /* rename file we move to recycle bin */ i = 1; - while (recycle_file_exist(conn, final_name)) { - snprintf(final_name, PATH_MAX, "%s/Copy #%d of %s", temp_name, i++, base); + while (recycle_file_exist(handle, final_name)) { + snprintf(final_name, PATH_MAX -1, "%s/Copy #%d of %s", temp_name, i++, base); } - DEBUG(10, ("recycle.bin: Moving %s to %s\n", file_name, final_name)); - rc = default_vfs_ops.rename(conn, file_name, final_name); + DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name)); + rc = VFS_NEXT_RENAME(handle, conn, file_name, final_name); if (rc != 0) { - DEBUG(3, ("recycle.bin: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); - rc = default_vfs_ops.unlink(conn, file_name); + DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); + rc = VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* touch access date of moved file */ - if (recbin->touch == True ) - recycle_touch(conn, final_name); + if (recycle_touch(handle) == True ) + recycle_do_touch(handle, final_name); done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); + SAFE_FREE(repository); return rc; } NTSTATUS vfs_recycle_init(void) -{ - return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_init); +{ + NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops); + + if (NT_STATUS_IS_ERR(ret)) + return ret; + + vfs_recycle_debug_level = debug_add_class("recycle"); + if (vfs_recycle_debug_level == -1) { + vfs_recycle_debug_level = DBGC_VFS; + DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("vfs_recycle: Debug class number of 'recycle': %d\n", vfs_recycle_debug_level)); + } + + return ret; } |