smbd: Add extra VFS hooks to get the posix ACL as a blob
authorAndrew Bartlett <abartlet@samba.org>
Mon, 10 Sep 2012 02:44:01 +0000 (12:44 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 12 Sep 2012 05:06:01 +0000 (07:06 +0200)
This will allow us to hash this, rather than the NT ACL it maps to.
This will in turn allow us to know if the NT ACL is valid even if we
have to change the mapping code.

Andrew Bartlett

Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Wed Sep 12 07:06:01 CEST 2012 on sn-devel-104

examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_fake_acls.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index edfb7726981405db93e07ad64a004d04ec0ddfe2..a786a234d40a144d9e98980aa5bf01ba71175feb 100644 (file)
@@ -586,6 +586,18 @@ static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fs
        return (SMB_ACL_T)NULL;
 }
 
+static int skel_sys_acl_blob_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
+static int skel_sys_acl_blob_get_fd(vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
 static int skel_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
 {
        errno = ENOSYS;
@@ -771,10 +783,13 @@ struct vfs_fn_pointers skel_opaque_fns = {
 
        .sys_acl_get_file_fn = skel_sys_acl_get_file,
        .sys_acl_get_fd_fn = skel_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = skel_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = skel_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = skel_sys_acl_set_file,
        .sys_acl_set_fd_fn = skel_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = skel_sys_acl_delete_def_file,
 
+
        /* EA operations. */
        .getxattr_fn = skel_getxattr,
        .fgetxattr_fn = skel_fgetxattr,
index 711b7fc13963029917430328b18c9e1c41dd418c..02a994c07f7923dcb733c616b67d0025a189c8f9 100644 (file)
@@ -699,6 +699,22 @@ static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fs
        return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
 }
 
+static int skel_sys_acl_blob_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **blob_description, 
+                                     DATA_BLOB *blob)
+{
+       return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, type, mem_ctx, blob_description, blob);
+}
+
+static int skel_sys_acl_blob_get_fd(vfs_handle_struct *handle, files_struct *fsp,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **blob_description, 
+                                     DATA_BLOB *blob)
+{
+       return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
+}
+
 static int skel_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
 {
        return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl);
@@ -869,6 +885,8 @@ struct vfs_fn_pointers skel_transparent_fns = {
 
        .sys_acl_get_file_fn = skel_sys_acl_get_file,
        .sys_acl_get_fd_fn = skel_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = skel_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = skel_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = skel_sys_acl_set_file,
        .sys_acl_set_fd_fn = skel_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = skel_sys_acl_delete_def_file,
index 17ec2625a2a6635845018078f0cd729783cd7217..8e48803fe7d3985eeebc675563d6881e53303473 100644 (file)
 /* Leave at 29 - not yet released. Remove sys_acl functions other than set and get - abartlet */
 /* Leave at 29 - not yet released. Added backup_intent bool to files_struct - JRA */
 /* Leave at 29 - not yet released. Add durable handle functions - metze/obnox */
+/* Leave at 29 - not yet released. Added sys_acl_blob_get_file and sys_acl_blob_get_fd */
 /* Bump to version 30 - Samba 4.0.0 will ship with interface version 30 */
 #define SMB_VFS_INTERFACE_VERSION 30
 
@@ -691,6 +692,12 @@ struct vfs_fn_pointers {
 
        SMB_ACL_T (*sys_acl_get_file_fn)(struct vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type);
        SMB_ACL_T (*sys_acl_get_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp);
+       int (*sys_acl_blob_get_file_fn)(struct vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type,      
+                                       TALLOC_CTX *mem_ctx, char **blob_description,
+                                       DATA_BLOB *blob);
+       int (*sys_acl_blob_get_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp,       
+                                     TALLOC_CTX *mem_ctx, char **blob_description,
+                                     DATA_BLOB *blob);
        int (*sys_acl_set_file_fn)(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
        int (*sys_acl_set_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_ACL_T theacl);
        int (*sys_acl_delete_def_file_fn)(struct vfs_handle_struct *handle, const char *path);
@@ -1088,6 +1095,17 @@ SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
                                        SMB_ACL_TYPE_T type);
 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
                                      struct files_struct *fsp);
+int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
+                                      const char *path_p,
+                                      SMB_ACL_TYPE_T type,     
+                                      TALLOC_CTX *mem_ctx,
+                                      char **blob_description,
+                                      DATA_BLOB *blob);
+int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
+                                    struct files_struct *fsp,  
+                                    TALLOC_CTX *mem_ctx,
+                                    char **blob_description,
+                                    DATA_BLOB *blob);
 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
                                  const char *name, SMB_ACL_TYPE_T acltype,
                                  SMB_ACL_T theacl);
index f077a6f1af29dc5cf2cc5ce257de9f2c7dcff737..4eca1b074841bf2bae2935e26d04bfc2a923ce18 100644 (file)
 #define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp) \
        smb_vfs_call_sys_acl_get_fd((handle)->next, (fsp))
 
+#define SMB_VFS_SYS_ACL_BLOB_GET_FILE(conn, path_p, type, mem_ctx, blob_description, blob)     \
+       smb_vfs_call_sys_acl_blob_get_file((conn)->vfs_handles, (path_p), (type), (mem_ctx), (blob_description), (blob))
+#define SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, type, mem_ctx, blob_description, blob) \
+       smb_vfs_call_sys_acl_blob_get_file((handle)->next, (path_p), (type), (mem_ctx), (blob_description), (blob))
+
+#define SMB_VFS_SYS_ACL_BLOB_GET_FD(fsp, mem_ctx, blob_description, blob)                      \
+       smb_vfs_call_sys_acl_blob_get_fd((fsp)->conn->vfs_handles, (fsp), (mem_ctx), (blob_description), (blob))
+#define SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob) \
+       smb_vfs_call_sys_acl_blob_get_fd((handle)->next, (fsp), mem_ctx, (blob_description), (blob))
+
 #define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) \
        smb_vfs_call_sys_acl_set_file((conn)->vfs_handles, (name), (acltype), (theacl))
 #define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl) \
index abe65700deb0bdf32c74d5622bb5c83351057cc4..258cb197c0b9dd766824029f4ad5ed5af8a55878 100644 (file)
@@ -294,6 +294,72 @@ static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle, file
        return acl;
 }
 
+
+static int fake_acls_sys_acl_blob_get_file(struct vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx, 
+                                          char **blob_description, DATA_BLOB *blob)
+{
+       ssize_t length;
+       const char *name = NULL;
+       switch (type) {
+       case SMB_ACL_TYPE_ACCESS:
+               name = FAKE_ACL_ACCESS_XATTR;
+               break;
+       case SMB_ACL_TYPE_DEFAULT:
+               name = FAKE_ACL_DEFAULT_XATTR;
+               break;
+       }
+
+       *blob_description = talloc_strdup(mem_ctx, "fake_acls");
+       if (!*blob_description) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       *blob = data_blob_null;
+       do {
+               blob->length += 1000;
+               blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, blob->length);
+               if (!blob->data) {
+                       errno = ENOMEM;
+                       return -1;
+               }
+               length = SMB_VFS_NEXT_GETXATTR(handle, path, name, blob->data, blob->length);
+               blob->length = length;
+       } while (length == -1 && errno == ERANGE);
+       if (length == -1) {
+               return -1;
+       }
+       return 0;
+}
+
+static int fake_acls_sys_acl_blob_get_fd(struct vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx, 
+                                        char **blob_description, DATA_BLOB *blob)
+{
+       ssize_t length;
+       const char *name = FAKE_ACL_ACCESS_XATTR;
+               
+       *blob_description = talloc_strdup(mem_ctx, "fake_acls");
+       if (!*blob_description) {
+               errno = ENOMEM;
+               return -1;
+       }
+       *blob = data_blob_null;
+       do {
+               blob->length += 1000;
+               blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, blob->length);
+               if (!blob->data) {
+                       errno = ENOMEM;
+                       return -1;
+               }
+               length = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, blob->data, blob->length);
+               blob->length = length;
+       } while (length == -1 && errno == ERANGE);
+       if (length == -1) {
+               return -1;
+       }
+       return 0;
+}
+
 static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
 {
        int ret;
@@ -450,6 +516,8 @@ static struct vfs_fn_pointers vfs_fake_acls_fns = {
        .fstat_fn = fake_acls_fstat,
        .sys_acl_get_file_fn = fake_acls_sys_acl_get_file,
        .sys_acl_get_fd_fn = fake_acls_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = fake_acls_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = fake_acls_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = fake_acls_sys_acl_set_file,
        .sys_acl_set_fd_fn = fake_acls_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = fake_acls_sys_acl_delete_def_file,
index 48198e7fa5b3627af3316123d6cf1c125b596723..392baeadd0a299cf238c0c7b9585f1ba5bc63d8c 100644 (file)
@@ -175,6 +175,8 @@ typedef enum _vfs_op_type {
 
        SMB_VFS_OP_SYS_ACL_GET_FILE,
        SMB_VFS_OP_SYS_ACL_GET_FD,
+       SMB_VFS_OP_SYS_ACL_BLOB_GET_FILE,
+       SMB_VFS_OP_SYS_ACL_BLOB_GET_FD,
        SMB_VFS_OP_SYS_ACL_SET_FILE,
        SMB_VFS_OP_SYS_ACL_SET_FD,
        SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
@@ -284,6 +286,8 @@ static struct {
        { SMB_VFS_OP_FCHMOD_ACL,        "fchmod_acl" },
        { SMB_VFS_OP_SYS_ACL_GET_FILE,  "sys_acl_get_file" },
        { SMB_VFS_OP_SYS_ACL_GET_FD,    "sys_acl_get_fd" },
+       { SMB_VFS_OP_SYS_ACL_BLOB_GET_FILE,     "sys_acl_blob_get_file" },
+       { SMB_VFS_OP_SYS_ACL_BLOB_GET_FD,       "sys_acl_blob_get_fd" },
        { SMB_VFS_OP_SYS_ACL_SET_FILE,  "sys_acl_set_file" },
        { SMB_VFS_OP_SYS_ACL_SET_FD,    "sys_acl_set_fd" },
        { SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,   "sys_acl_delete_def_file" },
@@ -1821,6 +1825,39 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
        return result;
 }
 
+static int smb_full_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
+                                               const char *path_p,
+                                               SMB_ACL_TYPE_T type, 
+                                               TALLOC_CTX *mem_ctx, 
+                                               char **blob_description,
+                                               DATA_BLOB *blob)
+{
+       SMB_ACL_T result;
+
+       result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, type, mem_ctx, blob_description, blob);
+
+       do_log(SMB_VFS_OP_SYS_ACL_BLOB_GET_FILE,  (result >= 0), handle,
+              "%s", path_p);
+
+       return result;
+}
+
+static int smb_full_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
+                                             files_struct *fsp, 
+                                             TALLOC_CTX *mem_ctx, 
+                                             char **blob_description,
+                                             DATA_BLOB *blob)
+{
+       SMB_ACL_T result;
+
+       result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description,blob);
+
+       do_log(SMB_VFS_OP_SYS_ACL_BLOB_GET_FD,  (result >= 0), handle,
+              "%s", fsp_str_do_log(fsp));
+
+       return result;
+}
+
 static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle,
 
                                  const char *name, SMB_ACL_TYPE_T acltype,
index c80fc8a0c30988df4a85e8b43d56a58af5342155..7571b2f3403f6ae4cc1dd9b1d76e7d0f5158f67c 100644 (file)
@@ -1809,6 +1809,52 @@ static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
        return result;
 }
 
+
+static int smb_time_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
+                                               const char *path_p,
+                                               SMB_ACL_TYPE_T type,    
+                                               TALLOC_CTX *mem_ctx, 
+                                               char **blob_description,
+                                               DATA_BLOB *blob)
+{
+       int result;
+       struct timespec ts1,ts2;
+       double timediff;
+
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, type, mem_ctx, blob_description, blob);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("sys_acl_blob_get_file", timediff);
+       }
+
+       return result;
+}
+
+static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
+                                             files_struct *fsp,
+                                             TALLOC_CTX *mem_ctx, 
+                                             char **blob_description,
+                                             DATA_BLOB *blob)
+{
+       int result;
+       struct timespec ts1,ts2;
+       double timediff;
+
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("sys_acl_blob_get_fd", timediff);
+       }
+
+       return result;
+}
+
 static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
                                           const char *name,
                                           SMB_ACL_TYPE_T acltype,
@@ -2135,6 +2181,8 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .fchmod_acl_fn = smb_time_audit_fchmod_acl,
        .sys_acl_get_file_fn = smb_time_audit_sys_acl_get_file,
        .sys_acl_get_fd_fn = smb_time_audit_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = smb_time_audit_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = smb_time_audit_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = smb_time_audit_sys_acl_set_file,
        .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = smb_time_audit_sys_acl_delete_def_file,
index bb9549c887015e917efaae63b4a378cbcb9ce852..763ef37f899984732339669965f2457c074a739c 100644 (file)
@@ -2226,6 +2226,27 @@ SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
        return handle->fns->sys_acl_get_fd_fn(handle, fsp);
 }
 
+int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
+                                      const char *path_p,
+                                      SMB_ACL_TYPE_T type,
+                                      TALLOC_CTX *mem_ctx, 
+                                      char **blob_description,
+                                      DATA_BLOB *blob)
+{
+       VFS_FIND(sys_acl_blob_get_file);
+       return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, type, mem_ctx, blob_description, blob);
+}
+
+int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
+                                    struct files_struct *fsp,
+                                    TALLOC_CTX *mem_ctx, 
+                                    char **blob_description,
+                                    DATA_BLOB *blob)
+{
+       VFS_FIND(sys_acl_blob_get_fd);
+       return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
+}
+
 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
                                  const char *name, SMB_ACL_TYPE_T acltype,
                                  SMB_ACL_T theacl)