s3-includes: only include system/filesys.h when needed.
[vlendec/samba-autobuild/.git] / source3 / modules / vfs_acl_common.c
index 58da9047692434d237383cb0e8568a4e98373466..0e513ee682c8f81a36b6b24cd04079d3c89c3056 100644 (file)
@@ -19,6 +19,8 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "system/filesys.h"
+#include "../libcli/security/security.h"
 #include "../librpc/gen_ndr/ndr_security.h"
 
 static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
@@ -85,7 +87,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
                        ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        switch (xacl.version) {
@@ -152,7 +154,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
                        ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
+               return ndr_map_error2ntstatus(ndr_err);
        }
 
        return NT_STATUS_OK;
@@ -256,6 +258,10 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
        uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
        struct security_descriptor *psd = NULL;
        struct security_descriptor *pdesc_next = NULL;
+       bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn),
+                                               ACL_MODULE_NAME,
+                                               "ignore system acls",
+                                               false);
 
        if (fsp && name == NULL) {
                name = fsp->fsp_name->base_name;
@@ -319,6 +325,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
                        goto out;
        }
 
+       if (ignore_file_system_acl) {
+               goto out;
+       }
 
        status = hash_sd_sha256(pdesc_next, hash_tmp);
        if (!NT_STATUS_IS_OK(status)) {
@@ -355,28 +364,45 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
                 * inheritable ACE entries we have to fake them.
                 */
                if (fsp) {
-                       is_directory = fsp->is_directory;
+                       status = vfs_stat_fsp(fsp);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
                        psbuf = &fsp->fsp_name->st;
                } else {
-                       if (vfs_stat_smb_fname(handle->conn,
+                       int ret = vfs_stat_smb_fname(handle->conn,
                                                name,
-                                               &sbuf) == 0) {
-                               is_directory = S_ISDIR(sbuf.st_ex_mode);
+                                               &sbuf);
+                       if (ret == -1) {
+                               return map_nt_error_from_unix(errno);
                        }
                }
-               if (is_directory &&
+               is_directory = S_ISDIR(sbuf.st_ex_mode);
+
+               if (ignore_file_system_acl) {
+                       TALLOC_FREE(pdesc_next);
+                       status = make_default_filesystem_acl(talloc_tos(),
+                                               name,
+                                               psbuf,
+                                               &psd);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
+               } else {
+                       if (is_directory &&
                                !sd_has_inheritable_components(psd,
                                                        true)) {
-                       add_directory_inheritable_components(handle,
+                               add_directory_inheritable_components(handle,
                                                        name,
                                                        psbuf,
                                                        psd);
+                       }
+                       /* The underlying POSIX module always sets
+                          the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
+                          can't be inherited in this way under POSIX.
+                          Remove it for Windows-style ACLs. */
+                       psd->type &= ~SEC_DESC_DACL_PROTECTED;
                }
-               /* The underlying POSIX module always sets
-                  the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
-                  can't be inherited in this way under POSIX.
-                  Remove it for Windows-style ACLs. */
-               psd->type &= ~SEC_DESC_DACL_PROTECTED;
        }
 
        if (!(security_info & SECINFO_OWNER)) {
@@ -394,6 +420,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
 
        TALLOC_FREE(blob.data);
        *ppdesc = psd;
+
+       if (DEBUGLEVEL >= 10) {
+               DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n",
+                       name ));
+               NDR_PRINT_DEBUG(security_descriptor, psd);
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -430,8 +463,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
                        &psd,
                        &size,
                        parent_desc,
-                       &handle->conn->server_info->ptok->sids[PRIMARY_USER_SID_INDEX],
-                       &handle->conn->server_info->ptok->sids[PRIMARY_GROUP_SID_INDEX],
+                       &handle->conn->session_info->security_token->sids[PRIMARY_USER_SID_INDEX],
+                       &handle->conn->session_info->security_token->sids[PRIMARY_GROUP_SID_INDEX],
                        is_directory);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -694,6 +727,10 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
                return status;
        }
 
+       psd->revision = orig_psd->revision;
+       /* All our SD's are self relative. */
+       psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE;
+
        if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) {
                psd->owner_sid = orig_psd->owner_sid;
        }
@@ -702,9 +739,11 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
        }
        if (security_info_sent & SECINFO_DACL) {
                psd->dacl = orig_psd->dacl;
+               psd->type |= SEC_DESC_DACL_PRESENT;
        }
        if (security_info_sent & SECINFO_SACL) {
                psd->sacl = orig_psd->sacl;
+               psd->type |= SEC_DESC_SACL_PRESENT;
        }
 
        status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
@@ -894,6 +933,10 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
                                        result,
                                        &info);
 
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
        if (info != FILE_WAS_CREATED) {
                /* File/directory was opened, not created. */
                goto out;
@@ -901,7 +944,7 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
 
        fsp = *result;
 
-       if (!NT_STATUS_IS_OK(status) || fsp == NULL) {
+       if (fsp == NULL) {
                /* Only handle success. */
                goto out;
        }