Complete fix for bug #8811 - sd_has_inheritable_components segfaults on an SD that...
authorJeremy Allison <jra@samba.org>
Fri, 30 Mar 2012 18:58:31 +0000 (11:58 -0700)
committerKarolin Seeger <kseeger@samba.org>
Wed, 13 Jun 2012 17:59:11 +0000 (19:59 +0200)
source3/lib/secdesc.c
source3/modules/vfs_acl_common.c
source3/smbd/file_access.c

index 001eccb5763b5a95b95c0726d7ae38ca80bbfe86..007e097ec31dd6fe357e40be6f682f06d2a43f94 100644 (file)
@@ -534,6 +534,10 @@ bool sd_has_inheritable_components(const struct security_descriptor *parent_ctr,
        unsigned int i;
        const struct security_acl *the_acl = parent_ctr->dacl;
 
+       if (the_acl == NULL) {
+               return false;
+       }
+
        for (i = 0; i < the_acl->num_aces; i++) {
                const struct security_ace *ace = &the_acl->aces[i];
 
index 56da3aff5677c6fa232830e31146256379e8d253..a5370110986a171b8f452aaeca2712158b0e2542 100644 (file)
@@ -166,7 +166,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
  CREATOR_OWNER/CREATOR_GROUP/WORLD.
 *******************************************************************/
 
-static void add_directory_inheritable_components(vfs_handle_struct *handle,
+static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle,
                                 const char *name,
                                SMB_STRUCT_STAT *psbuf,
                                struct security_descriptor *psd)
@@ -184,7 +184,7 @@ static void add_directory_inheritable_components(vfs_handle_struct *handle,
                                                num_aces + 3);
 
        if (new_ace_list == NULL) {
-               return;
+               return NT_STATUS_NO_MEMORY;
        }
 
        /* Fake a quick smb_filename. */
@@ -236,8 +236,19 @@ static void add_directory_inheritable_components(vfs_handle_struct *handle,
                        SEC_ACE_FLAG_CONTAINER_INHERIT|
                                SEC_ACE_FLAG_OBJECT_INHERIT|
                                SEC_ACE_FLAG_INHERIT_ONLY);
-       psd->dacl->aces = new_ace_list;
-       psd->dacl->num_aces += 3;
+       if (psd->dacl) {
+               psd->dacl->aces = new_ace_list;
+               psd->dacl->num_aces += 3;
+       } else {
+               psd->dacl = make_sec_acl(talloc_tos(),
+                               NT4_ACL_REVISION,
+                               3,
+                               new_ace_list);
+               if (psd->dacl == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -393,10 +404,14 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
                        if (is_directory &&
                                !sd_has_inheritable_components(psd,
                                                        true)) {
-                               add_directory_inheritable_components(handle,
+                               status = add_directory_inheritable_components(
+                                                       handle,
                                                        name,
                                                        psbuf,
                                                        psd);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return status;
+                               }
                        }
                        /* The underlying POSIX module always sets
                           the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
index 9f95d68cf379c874278e9d514c1a30ec306008dc..bd65a709827e6ce01c3053ce8de9daccff3ba5b2 100644 (file)
@@ -261,7 +261,10 @@ bool directory_has_default_acl(connection_struct *conn, const char *fname)
        NTSTATUS status = SMB_VFS_GET_NT_ACL(conn, fname,
                                SECINFO_DACL, &secdesc);
 
-       if (!NT_STATUS_IS_OK(status) || secdesc == NULL) {
+       if (!NT_STATUS_IS_OK(status) ||
+                       secdesc == NULL ||
+                       secdesc->dacl == NULL) {
+               TALLOC_FREE(secdesc);
                return false;
        }