summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/posix_acls.c67
1 files changed, 46 insertions, 21 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index c3c9d2e60c..d422746a3c 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3814,6 +3814,26 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode)
}
/****************************************************************************
+ Check for an existing default POSIX ACL on a directory.
+****************************************************************************/
+
+static bool directory_has_default_posix_acl(connection_struct *conn, const char *fname)
+{
+ SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ bool has_acl = False;
+ SMB_ACL_ENTRY_T entry;
+
+ if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
+ has_acl = True;
+ }
+
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return has_acl;
+}
+
+/****************************************************************************
If the parent directory has no default ACL but it does have an Access ACL,
inherit this Access ACL to file name.
****************************************************************************/
@@ -3821,7 +3841,7 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode)
int inherit_access_acl(connection_struct *conn, const char *inherit_from_dir,
const char *name, mode_t mode)
{
- if (directory_has_default_acl(conn, inherit_from_dir))
+ if (directory_has_default_posix_acl(conn, inherit_from_dir))
return 0;
return copy_access_acl(conn, inherit_from_dir, name, mode);
@@ -3853,26 +3873,6 @@ int fchmod_acl(files_struct *fsp, mode_t mode)
}
/****************************************************************************
- Check for an existing default POSIX ACL on a directory.
-****************************************************************************/
-
-bool directory_has_default_acl(connection_struct *conn, const char *fname)
-{
- SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
- bool has_acl = False;
- SMB_ACL_ENTRY_T entry;
-
- if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
- has_acl = True;
- }
-
- if (def_acl) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
- }
- return has_acl;
-}
-
-/****************************************************************************
Map from wire type to permset.
****************************************************************************/
@@ -4310,3 +4310,28 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
return ret_sd;
}
+
+/****************************************************************************
+ Check for an existing default Windows ACL on a directory.
+****************************************************************************/
+
+bool directory_has_default_acl(connection_struct *conn, const char *fname)
+{
+ SEC_DESC *psd = NULL; /* returns talloced off tos. */
+ unsigned int i;
+ NTSTATUS status = SMB_VFS_GET_NT_ACL(conn, fname,
+ DACL_SECURITY_INFORMATION, &psd);
+
+ if (!NT_STATUS_IS_OK(status) || psd == NULL) {
+ return false;
+ }
+
+ for (i = 0; i < psd->dacl->num_aces; i++) {
+ SEC_ACE *psa = &psd->dacl->aces[i];
+ if (psa->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_CONTAINER_INHERIT)) {
+ return true;
+ }
+ }
+ return false;
+}