vfs: Add dirfsp to connectpath_fn()
[samba.git] / source3 / modules / vfs_full_audit.c
index 5e1963c025fc51d46a466459a42b12b80e677020..011e483de2ffe630d5b369b55b5556ad1adecf37 100644 (file)
@@ -73,6 +73,7 @@
 #include "passdb/machine_sid.h"
 #include "lib/util/tevent_ntstatus.h"
 #include "lib/util/string_wrappers.h"
+#include "source3/lib/substitute.h"
 
 static int vfs_full_audit_debug_level = DBGC_VFS;
 
@@ -139,6 +140,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_STAT,
        SMB_VFS_OP_FSTAT,
        SMB_VFS_OP_LSTAT,
+       SMB_VFS_OP_FSTATAT,
        SMB_VFS_OP_GET_ALLOC_SIZE,
        SMB_VFS_OP_UNLINKAT,
        SMB_VFS_OP_FCHMOD,
@@ -151,7 +153,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_FTRUNCATE,
        SMB_VFS_OP_FALLOCATE,
        SMB_VFS_OP_LOCK,
-       SMB_VFS_OP_KERNEL_FLOCK,
+       SMB_VFS_OP_FILESYSTEM_SHAREMODE,
        SMB_VFS_OP_FCNTL,
        SMB_VFS_OP_LINUX_SETLEASE,
        SMB_VFS_OP_GETLOCK,
@@ -160,11 +162,12 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_LINKAT,
        SMB_VFS_OP_MKNODAT,
        SMB_VFS_OP_REALPATH,
-       SMB_VFS_OP_CHFLAGS,
+       SMB_VFS_OP_FCHFLAGS,
        SMB_VFS_OP_FILE_ID_CREATE,
        SMB_VFS_OP_FS_FILE_ID,
        SMB_VFS_OP_FSTREAMINFO,
        SMB_VFS_OP_GET_REAL_FILENAME,
+       SMB_VFS_OP_GET_REAL_FILENAME_AT,
        SMB_VFS_OP_CONNECTPATH,
        SMB_VFS_OP_BRL_LOCK_WINDOWS,
        SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
@@ -202,7 +205,6 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_SYS_ACL_DELETE_DEF_FD,
 
        /* EA operations. */
-       SMB_VFS_OP_GETXATTR,
        SMB_VFS_OP_GETXATTRAT_SEND,
        SMB_VFS_OP_GETXATTRAT_RECV,
        SMB_VFS_OP_FGETXATTR,
@@ -276,6 +278,7 @@ static struct {
        { SMB_VFS_OP_STAT,      "stat" },
        { SMB_VFS_OP_FSTAT,     "fstat" },
        { SMB_VFS_OP_LSTAT,     "lstat" },
+       { SMB_VFS_OP_FSTATAT,   "fstatat" },
        { SMB_VFS_OP_GET_ALLOC_SIZE,    "get_alloc_size" },
        { SMB_VFS_OP_UNLINKAT,  "unlinkat" },
        { SMB_VFS_OP_FCHMOD,    "fchmod" },
@@ -288,7 +291,7 @@ static struct {
        { SMB_VFS_OP_FTRUNCATE, "ftruncate" },
        { SMB_VFS_OP_FALLOCATE,"fallocate" },
        { SMB_VFS_OP_LOCK,      "lock" },
-       { SMB_VFS_OP_KERNEL_FLOCK,      "kernel_flock" },
+       { SMB_VFS_OP_FILESYSTEM_SHAREMODE,      "filesystem_sharemode" },
        { SMB_VFS_OP_FCNTL,     "fcntl" },
        { SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
        { SMB_VFS_OP_GETLOCK,   "getlock" },
@@ -297,11 +300,12 @@ static struct {
        { SMB_VFS_OP_LINKAT,    "linkat" },
        { SMB_VFS_OP_MKNODAT,   "mknodat" },
        { SMB_VFS_OP_REALPATH,  "realpath" },
-       { SMB_VFS_OP_CHFLAGS,   "chflags" },
+       { SMB_VFS_OP_FCHFLAGS,  "fchflags" },
        { SMB_VFS_OP_FILE_ID_CREATE,    "file_id_create" },
        { SMB_VFS_OP_FS_FILE_ID,        "fs_file_id" },
        { SMB_VFS_OP_FSTREAMINFO,       "fstreaminfo" },
        { SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
+       { SMB_VFS_OP_GET_REAL_FILENAME_AT, "get_real_filename_at" },
        { SMB_VFS_OP_CONNECTPATH,       "connectpath" },
        { SMB_VFS_OP_BRL_LOCK_WINDOWS,  "brl_lock_windows" },
        { SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
@@ -329,7 +333,6 @@ static struct {
        { SMB_VFS_OP_SYS_ACL_BLOB_GET_FD,       "sys_acl_blob_get_fd" },
        { SMB_VFS_OP_SYS_ACL_SET_FD,    "sys_acl_set_fd" },
        { SMB_VFS_OP_SYS_ACL_DELETE_DEF_FD,     "sys_acl_delete_def_fd" },
-       { SMB_VFS_OP_GETXATTR,  "getxattr" },
        { SMB_VFS_OP_GETXATTRAT_SEND, "getxattrat_send" },
        { SMB_VFS_OP_GETXATTRAT_RECV, "getxattrat_recv" },
        { SMB_VFS_OP_FGETXATTR, "fgetxattr" },
@@ -512,13 +515,13 @@ static struct bitmap *init_bitmap(TALLOC_CTX *mem_ctx, const char **ops)
        struct bitmap *bm;
 
        if (ops == NULL) {
+               DBG_ERR("init_bitmap, ops list is empty (logic error)\n");
                return NULL;
        }
 
        bm = bitmap_talloc(mem_ctx, SMB_VFS_OP_LAST);
        if (bm == NULL) {
-               DEBUG(0, ("Could not alloc bitmap -- "
-                         "defaulting to logging everything\n"));
+               DBG_ERR("Could not alloc bitmap\n");
                return NULL;
        }
 
@@ -560,8 +563,7 @@ static struct bitmap *init_bitmap(TALLOC_CTX *mem_ctx, const char **ops)
                        }
                }
                if (i == SMB_VFS_OP_LAST) {
-                       DEBUG(0, ("Could not find opname %s, logging all\n",
-                                 *ops));
+                       DBG_ERR("Could not find opname %s\n", *ops);
                        TALLOC_FREE(bm);
                        return NULL;
                }
@@ -749,9 +751,19 @@ static int smb_full_audit_connect(vfs_handle_struct *handle,
        pd->success_ops = init_bitmap(
                pd, lp_parm_string_list(SNUM(handle->conn), "full_audit",
                                        "success", none));
+       if (pd->success_ops == NULL) {
+               DBG_ERR("Invalid success operations list. Failing connect\n");
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
        pd->failure_ops = init_bitmap(
                pd, lp_parm_string_list(SNUM(handle->conn), "full_audit",
                                        "failure", none));
+       if (pd->failure_ops == NULL) {
+               DBG_ERR("Invalid failure operations list. Failing connect\n");
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
 
        /* Store the private data. */
        SMB_VFS_HANDLE_SET_DATA(handle, pd, NULL,
@@ -921,8 +933,16 @@ static NTSTATUS smb_full_audit_read_dfs_pathat(struct vfs_handle_struct *handle,
                        struct referral **ppreflist,
                        size_t *preferral_count)
 {
+       struct smb_filename *full_fname = NULL;
        NTSTATUS status;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
                        mem_ctx,
                        dirfsp,
@@ -934,8 +954,9 @@ static NTSTATUS smb_full_audit_read_dfs_pathat(struct vfs_handle_struct *handle,
                NT_STATUS_IS_OK(status),
                handle,
                "%s",
-               smb_fname_str_do_log(handle->conn, smb_fname));
+               smb_fname_str_do_log(handle->conn, full_fname));
 
+       TALLOC_FREE(full_fname);
        return status;
 }
 
@@ -1091,15 +1112,14 @@ static int smb_full_audit_openat(vfs_handle_struct *handle,
                                 const struct files_struct *dirfsp,
                                 const struct smb_filename *smb_fname,
                                 struct files_struct *fsp,
-                                int flags,
-                                mode_t mode)
+                                const struct vfs_open_how *how)
 {
        int result;
 
-       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 
        do_log(SMB_VFS_OP_OPENAT, (result >= 0), handle, "%s|%s",
-              ((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
+              ((how->flags & O_WRONLY) || (how->flags & O_RDWR))?"w":"r",
               fsp_str_do_log(fsp));
 
        return result;
@@ -1107,6 +1127,7 @@ static int smb_full_audit_openat(vfs_handle_struct *handle,
 
 static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle,
                                      struct smb_request *req,
+                                     struct files_struct *dirfsp,
                                      struct smb_filename *smb_fname,
                                      uint32_t access_mask,
                                      uint32_t share_access,
@@ -1153,6 +1174,7 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_CREATE_FILE(
                handle,                                 /* handle */
                req,                                    /* req */
+               dirfsp,                                 /* dirfsp */
                smb_fname,                              /* fname */
                access_mask,                            /* access_mask */
                share_access,                           /* share_access */
@@ -1410,6 +1432,25 @@ static int smb_full_audit_renameat(vfs_handle_struct *handle,
                                const struct smb_filename *smb_fname_dst)
 {
        int result;
+       int saved_errno;
+       struct smb_filename *full_fname_src = NULL;
+       struct smb_filename *full_fname_dst = NULL;
+
+       full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
+                                                     srcfsp,
+                                                     smb_fname_src);
+       if (full_fname_src == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+       full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
+                                                     dstfsp,
+                                                     smb_fname_dst);
+       if (full_fname_dst == NULL) {
+               TALLOC_FREE(full_fname_src);
+               errno = ENOMEM;
+               return -1;
+       }
 
        result = SMB_VFS_NEXT_RENAMEAT(handle,
                                srcfsp,
@@ -1417,10 +1458,19 @@ static int smb_full_audit_renameat(vfs_handle_struct *handle,
                                dstfsp,
                                smb_fname_dst);
 
+       if (result == -1) {
+               saved_errno = errno;
+       }
        do_log(SMB_VFS_OP_RENAMEAT, (result >= 0), handle, "%s|%s",
-              smb_fname_str_do_log(handle->conn, smb_fname_src),
-              smb_fname_str_do_log(handle->conn, smb_fname_dst));
+              smb_fname_str_do_log(handle->conn, full_fname_src),
+              smb_fname_str_do_log(handle->conn, full_fname_dst));
 
+       TALLOC_FREE(full_fname_src);
+       TALLOC_FREE(full_fname_dst);
+
+       if (result == -1) {
+               errno = saved_errno;
+       }
        return result;
 }
 
@@ -1532,6 +1582,26 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle,
        return result;    
 }
 
+static int smb_full_audit_fstatat(
+       struct vfs_handle_struct *handle,
+       const struct files_struct *dirfsp,
+       const struct smb_filename *smb_fname,
+       SMB_STRUCT_STAT *sbuf,
+       int flags)
+{
+       int result;
+
+       result = SMB_VFS_NEXT_FSTATAT(handle, dirfsp, smb_fname, sbuf, flags);
+
+       do_log(SMB_VFS_OP_FSTATAT,
+              (result >= 0),
+              handle,
+              "%s/%s",
+              fsp_str_do_log(dirfsp),
+              smb_fname_str_do_log(handle->conn, smb_fname));
+
+       return result;
+}
 static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
                       files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
 {
@@ -1732,19 +1802,19 @@ static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
        return result;
 }
 
-static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle,
-                                      struct files_struct *fsp,
-                                      uint32_t share_access,
-                                      uint32_t access_mask)
+static int smb_full_audit_filesystem_sharemode(struct vfs_handle_struct *handle,
+                                              struct files_struct *fsp,
+                                              uint32_t share_access,
+                                              uint32_t access_mask)
 {
        int result;
 
-       result = SMB_VFS_NEXT_KERNEL_FLOCK(handle,
-                                          fsp,
-                                          share_access,
-                                          access_mask);
+       result = SMB_VFS_NEXT_FILESYSTEM_SHAREMODE(handle,
+                                                  fsp,
+                                                  share_access,
+                                                  access_mask);
 
-       do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s",
+       do_log(SMB_VFS_OP_FILESYSTEM_SHAREMODE, (result >= 0), handle, "%s",
               fsp_str_do_log(fsp));
 
        return result;
@@ -1953,19 +2023,19 @@ static struct smb_filename *smb_full_audit_realpath(vfs_handle_struct *handle,
        return result_fname;
 }
 
-static int smb_full_audit_chflags(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
+static int smb_full_audit_fchflags(vfs_handle_struct *handle,
+                       struct files_struct *fsp,
                        unsigned int flags)
 {
        int result;
 
-       result = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
+       result = SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
 
-       do_log(SMB_VFS_OP_CHFLAGS,
+       do_log(SMB_VFS_OP_FCHFLAGS,
               (result != 0),
               handle,
               "%s",
-              smb_fname_str_do_log(handle->conn, smb_fname));
+              smb_fname_str_do_log(handle->conn, fsp->fsp_name));
 
        return result;
 }
@@ -2022,30 +2092,37 @@ static NTSTATUS smb_full_audit_fstreaminfo(vfs_handle_struct *handle,
         return result;
 }
 
-static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
-                                           const struct smb_filename *path,
-                                           const char *name,
-                                           TALLOC_CTX *mem_ctx,
-                                           char **found_name)
+static NTSTATUS smb_full_audit_get_real_filename_at(
+       struct vfs_handle_struct *handle,
+       struct files_struct *dirfsp,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
-       int result;
+       NTSTATUS result;
 
-       result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
-                                               found_name);
+       result = SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
+               handle, dirfsp, name, mem_ctx, found_name);
 
-       do_log(SMB_VFS_OP_GET_REAL_FILENAME, (result == 0), handle,
+       do_log(SMB_VFS_OP_GET_REAL_FILENAME_AT,
+              NT_STATUS_IS_OK(result),
+              handle,
               "%s/%s->%s",
-              path->base_name, name, (result == 0) ? *found_name : "");
+              fsp_str_dbg(dirfsp),
+              name,
+              NT_STATUS_IS_OK(result) ? *found_name : "");
 
        return result;
 }
 
-static const char *smb_full_audit_connectpath(vfs_handle_struct *handle,
-                                       const struct smb_filename *smb_fname)
+static const char *smb_full_audit_connectpath(
+       vfs_handle_struct *handle,
+       const struct files_struct *dirfsp,
+       const struct smb_filename *smb_fname)
 {
        const char *result;
 
-       result = SMB_VFS_NEXT_CONNECTPATH(handle, smb_fname);
+       result = SMB_VFS_NEXT_CONNECTPATH(handle, dirfsp, smb_fname);
 
        do_log(SMB_VFS_OP_CONNECTPATH,
               result != NULL,
@@ -2199,12 +2276,14 @@ static NTSTATUS smb_full_audit_offload_read_recv(
        struct tevent_req *req,
        struct vfs_handle_struct *handle,
        TALLOC_CTX *mem_ctx,
+       uint32_t *flags,
+       uint64_t *xferlen,
        DATA_BLOB *_token_blob)
 {
        NTSTATUS status;
 
        status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(req, handle, mem_ctx,
-                                               _token_blob);
+                                               flags, xferlen, _token_blob);
 
        do_log(SMB_VFS_OP_OFFLOAD_READ_RECV, NT_STATUS_IS_OK(status), handle, "");
 
@@ -2585,24 +2664,6 @@ static int smb_full_audit_sys_acl_delete_def_fd(vfs_handle_struct *handle,
        return result;
 }
 
-static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
-                             const struct smb_filename *smb_fname,
-                             const char *name, void *value, size_t size)
-{
-       ssize_t result;
-
-       result = SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
-
-       do_log(SMB_VFS_OP_GETXATTR,
-              (result >= 0),
-              handle,
-              "%s|%s",
-              smb_fname_str_do_log(handle->conn, smb_fname),
-              name);
-
-       return result;
-}
-
 struct smb_full_audit_getxattrat_state {
        struct vfs_aio_state aio_state;
        vfs_handle_struct *handle;
@@ -2910,6 +2971,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .stat_fn = smb_full_audit_stat,
        .fstat_fn = smb_full_audit_fstat,
        .lstat_fn = smb_full_audit_lstat,
+       .fstatat_fn = smb_full_audit_fstatat,
        .get_alloc_size_fn = smb_full_audit_get_alloc_size,
        .unlinkat_fn = smb_full_audit_unlinkat,
        .fchmod_fn = smb_full_audit_fchmod,
@@ -2921,7 +2983,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .ftruncate_fn = smb_full_audit_ftruncate,
        .fallocate_fn = smb_full_audit_fallocate,
        .lock_fn = smb_full_audit_lock,
-       .kernel_flock_fn = smb_full_audit_kernel_flock,
+       .filesystem_sharemode_fn = smb_full_audit_filesystem_sharemode,
        .fcntl_fn = smb_full_audit_fcntl,
        .linux_setlease_fn = smb_full_audit_linux_setlease,
        .getlock_fn = smb_full_audit_getlock,
@@ -2930,7 +2992,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .linkat_fn = smb_full_audit_linkat,
        .mknodat_fn = smb_full_audit_mknodat,
        .realpath_fn = smb_full_audit_realpath,
-       .chflags_fn = smb_full_audit_chflags,
+       .fchflags_fn = smb_full_audit_fchflags,
        .file_id_create_fn = smb_full_audit_file_id_create,
        .fs_file_id_fn = smb_full_audit_fs_file_id,
        .offload_read_send_fn = smb_full_audit_offload_read_send,
@@ -2943,7 +3005,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .snap_create_fn = smb_full_audit_snap_create,
        .snap_delete_fn = smb_full_audit_snap_delete,
        .fstreaminfo_fn = smb_full_audit_fstreaminfo,
-       .get_real_filename_fn = smb_full_audit_get_real_filename,
+       .get_real_filename_at_fn = smb_full_audit_get_real_filename_at,
        .connectpath_fn = smb_full_audit_connectpath,
        .brl_lock_windows_fn = smb_full_audit_brl_lock_windows,
        .brl_unlock_windows_fn = smb_full_audit_brl_unlock_windows,
@@ -2962,7 +3024,6 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .sys_acl_blob_get_fd_fn = smb_full_audit_sys_acl_blob_get_fd,
        .sys_acl_set_fd_fn = smb_full_audit_sys_acl_set_fd,
        .sys_acl_delete_def_fd_fn = smb_full_audit_sys_acl_delete_def_fd,
-       .getxattr_fn = smb_full_audit_getxattr,
        .getxattrat_send_fn = smb_full_audit_getxattrat_send,
        .getxattrat_recv_fn = smb_full_audit_getxattrat_recv,
        .fgetxattr_fn = smb_full_audit_fgetxattr,